Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/operations/find_root.rs @ 44980:5965efb609b6
hg-core: add FindRoot operation to find repository root path
Differential Revision: https://phab.mercurial-scm.org/D8609
author | Antoine Cezar <antoine.cezar@octobus.net> |
---|---|
date | Fri, 05 Jun 2020 08:48:09 +0200 |
parents | |
children | 452ece5654c5 |
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 super::Operation; |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
2 use std::fmt; |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
3 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
|
4 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
5 /// 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
|
6 #[derive(Debug)] |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
7 pub enum FindRootErrorKind { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
8 /// 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
|
9 /// 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
|
10 RootNotFound(PathBuf), |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
11 /// 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
|
12 /// 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
|
13 GetCurrentDirError(std::io::Error), |
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 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
16 /// A FindRoot error |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
17 #[derive(Debug)] |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
18 pub struct FindRootError { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
19 /// 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
|
20 pub kind: FindRootErrorKind, |
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 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
23 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
|
24 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
25 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
|
26 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
|
27 unimplemented!() |
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 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
31 /// 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
|
32 /// 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
|
33 /// ancestors |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
34 pub struct FindRoot<'a> { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
35 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
|
36 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
37 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
38 impl<'a> FindRoot<'a> { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
39 pub fn new() -> Self { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
40 Self { current_dir: None } |
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 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
43 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
|
44 Self { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
45 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
|
46 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
47 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
48 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
49 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
50 impl<'a> Operation<PathBuf> for FindRoot<'a> { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
51 type Error = FindRootError; |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
52 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
53 fn run(&self) -> Result<PathBuf, Self::Error> { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
54 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
|
55 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
|
56 Err(FindRootError { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
57 kind: FindRootErrorKind::GetCurrentDirError(e), |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
58 }) |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
59 })?, |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
60 Some(path) => path.into(), |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
61 }; |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
62 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
63 if current_dir.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(current_dir.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 let mut ancestors = current_dir.ancestors(); |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
67 while let Some(parent) = ancestors.next() { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
68 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
|
69 return Ok(parent.into()); |
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 Err(FindRootError { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
73 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
|
74 }) |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
75 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
76 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
77 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
78 #[cfg(test)] |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
79 mod tests { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
80 use super::*; |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
81 use std::fs; |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
82 use tempfile; |
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 #[test] |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
85 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
|
86 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
|
87 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
|
88 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
89 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
|
90 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
91 // TODO do something better |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
92 assert!(match err { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
93 FindRootError { kind } => match kind { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
94 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
|
95 _ => false, |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
96 }, |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
97 }) |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
98 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
99 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
100 #[test] |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 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
|
105 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
106 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
|
107 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
108 assert_eq!(result, root) |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
109 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
110 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
111 #[test] |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
112 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
|
113 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
|
114 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
|
115 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
|
116 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
117 let result = |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
118 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
|
119 .run() |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
120 .unwrap(); |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
121 |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
122 assert_eq!(result, root) |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
123 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
124 } /* tests */ |