Mercurial > public > mercurial-scm > hg
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 |
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 */ |