[Request] [+++ ] D8609: hg-core: add FindRoot operation to find repository root path
acezar (Antoine Cezar)
phabricator at mercurial-scm.org
Fri Jun 5 14:32:31 UTC 2020
acezar created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D8609
AFFECTED FILES
rust/hg-core/src/operations/find_root.rs
rust/hg-core/src/operations/mod.rs
CHANGE DETAILS
diff --git a/rust/hg-core/src/operations/mod.rs b/rust/hg-core/src/operations/mod.rs
--- a/rust/hg-core/src/operations/mod.rs
+++ b/rust/hg-core/src/operations/mod.rs
@@ -1,3 +1,6 @@
+mod find_root;
+pub use find_root::{FindRoot, FindRootError, FindRootErrorKind};
+
/// An interface for high-level hg operations.
///
/// A distinction is made between operation and commands.
diff --git a/rust/hg-core/src/operations/find_root.rs b/rust/hg-core/src/operations/find_root.rs
new file mode 100644
--- /dev/null
+++ b/rust/hg-core/src/operations/find_root.rs
@@ -0,0 +1,128 @@
+use super::Operation;
+use std::fmt;
+use std::path::{Path, PathBuf};
+
+/// Kind of error encoutered by FindRoot
+#[derive(Debug, PartialEq)]
+pub enum FindRootErrorKind {
+ /// Root of the repository has not been found
+ RootNotFound,
+ /// The current directory does not exists or permissions are insufficient
+ /// to get access to it
+ GetCurrentDirError,
+}
+
+/// A FindRoot error
+#[derive(Debug, PartialEq)]
+pub struct FindRootError {
+ /// Kind of error encoutered by FindRoot
+ pub kind: FindRootErrorKind,
+
+ /// Curent directory used by FindRoot
+ ///
+ /// Can be none if std::env::current_dir returns std::io::Error
+ pub current_dir: Option<PathBuf>,
+}
+
+impl std::error::Error for FindRootError {}
+
+impl fmt::Display for FindRootError {
+ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ unimplemented!()
+ }
+}
+
+/// Find the root of the repository
+/// by searching for a .hg directory in the current directory and its
+/// ancestors
+pub struct FindRoot<'a> {
+ current_dir: Option<&'a Path>,
+}
+
+impl<'a> FindRoot<'a> {
+ pub fn new() -> Self {
+ Self { current_dir: None }
+ }
+
+ pub fn new_from_path(current_dir: &'a Path) -> Self {
+ Self {
+ current_dir: Some(current_dir),
+ }
+ }
+}
+
+impl<'a> Operation<PathBuf> for FindRoot<'a> {
+ type Error = FindRootError;
+
+ fn run(&self) -> Result<PathBuf, Self::Error> {
+ let current_dir = match self.current_dir {
+ None => std::env::current_dir().or(Err(FindRootError {
+ kind: FindRootErrorKind::GetCurrentDirError,
+ current_dir: None,
+ }))?,
+ Some(path) => path.into(),
+ };
+
+ if current_dir.join(".hg").exists() {
+ return Ok(current_dir.into());
+ }
+ let mut anscestors = current_dir.ancestors();
+ while let Some(parent) = anscestors.next() {
+ if parent.join(".hg").exists() {
+ return Ok(parent.into());
+ }
+ }
+ Err(FindRootError {
+ kind: FindRootErrorKind::RootNotFound,
+ current_dir: Some(current_dir.to_path_buf()),
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::fs;
+ use tempfile;
+
+ #[test]
+ fn dot_hg_not_found() {
+ let tmp_dir = tempfile::tempdir().unwrap();
+ let path = tmp_dir.path();
+
+ let err = FindRoot::new_from_path(&path).run().unwrap_err();
+
+ assert_eq!(
+ err,
+ FindRootError {
+ kind: FindRootErrorKind::RootNotFound,
+ current_dir: Some(path.to_path_buf()),
+ }
+ )
+ }
+
+ #[test]
+ fn dot_hg_in_current_path() {
+ let tmp_dir = tempfile::tempdir().unwrap();
+ let root = tmp_dir.path();
+ fs::create_dir_all(root.join(".hg")).unwrap();
+
+ let result = FindRoot::new_from_path(&root).run().unwrap();
+
+ assert_eq!(result, root)
+ }
+
+ #[test]
+ fn dot_hg_in_parent() {
+ let tmp_dir = tempfile::tempdir().unwrap();
+ let root = tmp_dir.path();
+ fs::create_dir_all(root.join(".hg")).unwrap();
+
+ let result =
+ FindRoot::new_from_path(&root.join("some/nested/directory"))
+ .run()
+ .unwrap();
+
+ assert_eq!(result, root)
+ }
+} /* tests */
To: acezar, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mercurial-scm.org/pipermail/mercurial-patches/attachments/20200605/19c77f9b/attachment-0001.html>
More information about the Mercurial-patches
mailing list