Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/operations/find_root.rs @ 45358:452ece5654c5
hg-core: remove the `Operation` trait
There is no way to currently define a trait which can both return references
to `self` and to passed data, which is what we would need.
Generic Associated Types may fix this and allow us to have a unified interface.
See: rust #44265
Differential Revision: https://phab.mercurial-scm.org/D8862
author | Antoine Cezar <antoine.cezar@octobus.net> |
---|---|
date | Wed, 29 Jul 2020 10:08:09 +0200 |
parents | 5965efb609b6 |
children | 3d9f1dfc52c2 |
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() { |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
59 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
|
60 } |
5965efb609b6
hg-core: add FindRoot operation to find repository root path
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
61 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
|
62 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
|
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 */ |