annotate rust/hg-core/src/operations/find_root.rs @ 46127:c58c8f1d63b1

copies-rust: hide most of the comparison details inside a closure The function that compares values needs various supporting elements that are the same for each call. We are about to both make change to these element and change to call sites in our upcoming work. So abstracting most of the details will help to avoid conflict while these works happen in parallel. Differential Revision: https://phab.mercurial-scm.org/D9426
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sat, 21 Nov 2020 10:50:14 +0100
parents 3d9f1dfc52c2
children dca9cb99971c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
44980
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
1 use std::fmt;
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
2 use std::path::{Path, PathBuf};
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
3
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
4 /// Kind of error encoutered by FindRoot
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
5 #[derive(Debug)]
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
6 pub enum FindRootErrorKind {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
7 /// Root of the repository has not been found
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
8 /// Contains the current directory used by FindRoot
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
9 RootNotFound(PathBuf),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
10 /// The current directory does not exists or permissions are insufficient
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
11 /// to get access to it
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
12 GetCurrentDirError(std::io::Error),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
13 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
14
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
15 /// A FindRoot error
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
16 #[derive(Debug)]
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
17 pub struct FindRootError {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
18 /// Kind of error encoutered by FindRoot
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
19 pub kind: FindRootErrorKind,
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
20 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
21
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
22 impl std::error::Error for FindRootError {}
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
23
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
24 impl fmt::Display for FindRootError {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
25 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
26 unimplemented!()
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
27 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
28 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
29
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
30 /// Find the root of the repository
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
31 /// by searching for a .hg directory in the current directory and its
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
32 /// ancestors
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
33 pub struct FindRoot<'a> {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
34 current_dir: Option<&'a Path>,
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
35 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
36
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
37 impl<'a> FindRoot<'a> {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
38 pub fn new() -> Self {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
39 Self { current_dir: None }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
40 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
41
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
42 pub fn new_from_path(current_dir: &'a Path) -> Self {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
43 Self {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
44 current_dir: Some(current_dir),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
45 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
46 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
47
45358
452ece5654c5 hg-core: remove the `Operation` trait
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44980
diff changeset
48 pub fn run(&self) -> Result<PathBuf, FindRootError> {
44980
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
49 let current_dir = match self.current_dir {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
50 None => std::env::current_dir().or_else(|e| {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
51 Err(FindRootError {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
52 kind: FindRootErrorKind::GetCurrentDirError(e),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
53 })
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
54 })?,
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
55 Some(path) => path.into(),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
56 };
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
57
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
58 if current_dir.join(".hg").exists() {
45441
3d9f1dfc52c2 hg-core: fix some `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45358
diff changeset
59 return Ok(current_dir);
44980
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
60 }
45441
3d9f1dfc52c2 hg-core: fix some `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45358
diff changeset
61 let ancestors = current_dir.ancestors();
3d9f1dfc52c2 hg-core: fix some `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45358
diff changeset
62 for parent in ancestors {
44980
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
63 if parent.join(".hg").exists() {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
64 return Ok(parent.into());
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
65 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
66 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
67 Err(FindRootError {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
68 kind: FindRootErrorKind::RootNotFound(current_dir.to_path_buf()),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
69 })
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
70 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
71 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
72
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
73 #[cfg(test)]
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
74 mod tests {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
75 use super::*;
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
76 use std::fs;
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
77 use tempfile;
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
78
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
79 #[test]
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
80 fn dot_hg_not_found() {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
81 let tmp_dir = tempfile::tempdir().unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
82 let path = tmp_dir.path();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
83
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
84 let err = FindRoot::new_from_path(&path).run().unwrap_err();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
85
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
86 // TODO do something better
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
87 assert!(match err {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
88 FindRootError { kind } => match kind {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
89 FindRootErrorKind::RootNotFound(p) => p == path.to_path_buf(),
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
90 _ => false,
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
91 },
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
92 })
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
93 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
94
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
95 #[test]
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
96 fn dot_hg_in_current_path() {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
97 let tmp_dir = tempfile::tempdir().unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
98 let root = tmp_dir.path();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
99 fs::create_dir_all(root.join(".hg")).unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
100
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
101 let result = FindRoot::new_from_path(&root).run().unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
102
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
103 assert_eq!(result, root)
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
104 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
105
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
106 #[test]
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
107 fn dot_hg_in_parent() {
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
108 let tmp_dir = tempfile::tempdir().unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
109 let root = tmp_dir.path();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
110 fs::create_dir_all(root.join(".hg")).unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
111
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
112 let result =
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
113 FindRoot::new_from_path(&root.join("some/nested/directory"))
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
114 .run()
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
115 .unwrap();
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
116
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
117 assert_eq!(result, root)
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
118 }
5965efb609b6 hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
119 } /* tests */