##// END OF EJS Templates
rust: Fold find_root and check_requirements into Repo::find...
Simon Sapin -
r47175:1dcd9c99 default
parent child Browse files
Show More
@@ -11,7 +11,7 b' use super::layer;'
11 use crate::config::layer::{ConfigError, ConfigLayer, ConfigValue};
11 use crate::config::layer::{ConfigError, ConfigLayer, ConfigValue};
12 use std::path::PathBuf;
12 use std::path::PathBuf;
13
13
14 use crate::operations::find_root;
14 use crate::repo::Repo;
15 use crate::utils::files::read_whole_file;
15 use crate::utils::files::read_whole_file;
16
16
17 /// Holds the config values for the current repository
17 /// Holds the config values for the current repository
@@ -76,10 +76,9 b' impl Config {'
76
76
77 /// Loads the local config. In a future version, this will also load the
77 /// Loads the local config. In a future version, this will also load the
78 /// `$HOME/.hgrc` and more to mirror the Python implementation.
78 /// `$HOME/.hgrc` and more to mirror the Python implementation.
79 pub fn load() -> Result<Self, ConfigError> {
79 pub fn load_for_repo(repo: &Repo) -> Result<Self, ConfigError> {
80 let root = find_root().unwrap();
81 Ok(Self::load_from_explicit_sources(vec![
80 Ok(Self::load_from_explicit_sources(vec![
82 ConfigSource::AbsPath(root.join(".hg/hgrc")),
81 ConfigSource::AbsPath(repo.hg_vfs().join("hgrc")),
83 ])?)
82 ])?)
84 }
83 }
85
84
@@ -5,10 +5,8 b''
5 mod cat;
5 mod cat;
6 mod debugdata;
6 mod debugdata;
7 mod dirstate_status;
7 mod dirstate_status;
8 mod find_root;
9 mod list_tracked_files;
8 mod list_tracked_files;
10 pub use cat::cat;
9 pub use cat::cat;
11 pub use debugdata::{debug_data, DebugDataKind};
10 pub use debugdata::{debug_data, DebugDataKind};
12 pub use find_root::{find_root, find_root_from_path, FindRootError};
13 pub use list_tracked_files::Dirstate;
11 pub use list_tracked_files::Dirstate;
14 pub use list_tracked_files::{list_rev_tracked_files, FilesForRev};
12 pub use list_tracked_files::{list_rev_tracked_files, FilesForRev};
@@ -1,5 +1,4 b''
1 use crate::errors::{HgError, IoResultExt};
1 use crate::errors::{HgError, IoResultExt};
2 use crate::operations::{find_root, FindRootError};
3 use crate::requirements;
2 use crate::requirements;
4 use memmap::{Mmap, MmapOptions};
3 use memmap::{Mmap, MmapOptions};
5 use std::path::{Path, PathBuf};
4 use std::path::{Path, PathBuf};
@@ -11,6 +10,15 b' pub struct Repo {'
11 store: PathBuf,
10 store: PathBuf,
12 }
11 }
13
12
13 #[derive(Debug, derive_more::From)]
14 pub enum RepoFindError {
15 NotFoundInCurrentDirectoryOrAncestors {
16 current_directory: PathBuf,
17 },
18 #[from]
19 Other(HgError),
20 }
21
14 /// Filesystem access abstraction for the contents of a given "base" diretory
22 /// Filesystem access abstraction for the contents of a given "base" diretory
15 #[derive(Clone, Copy)]
23 #[derive(Clone, Copy)]
16 pub(crate) struct Vfs<'a> {
24 pub(crate) struct Vfs<'a> {
@@ -18,24 +26,26 b" pub(crate) struct Vfs<'a> {"
18 }
26 }
19
27
20 impl Repo {
28 impl Repo {
21 /// Returns `None` if the given path doesn’t look like a repository
29 /// Search the current directory and its ancestores for a repository:
22 /// (doesn’t contain a `.hg` sub-directory).
30 /// a working directory that contains a `.hg` sub-directory.
23 pub fn for_path(root: impl Into<PathBuf>) -> Self {
31 pub fn find() -> Result<Self, RepoFindError> {
24 let working_directory = root.into();
32 let current_directory = crate::utils::current_dir()?;
25 let dot_hg = working_directory.join(".hg");
33 // ancestors() is inclusive: it first yields `current_directory` as-is.
26 Self {
34 for ancestor in current_directory.ancestors() {
27 store: dot_hg.join("store"),
35 let dot_hg = ancestor.join(".hg");
28 dot_hg,
36 if dot_hg.is_dir() {
29 working_directory,
37 let repo = Self {
38 store: dot_hg.join("store"),
39 dot_hg,
40 working_directory: ancestor.to_owned(),
41 };
42 requirements::check(&repo)?;
43 return Ok(repo);
44 }
30 }
45 }
31 }
46 Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors {
32
47 current_directory,
33 pub fn find() -> Result<Self, FindRootError> {
48 })
34 find_root().map(Self::for_path)
35 }
36
37 pub fn check_requirements(&self) -> Result<(), HgError> {
38 requirements::check(self)
39 }
49 }
40
50
41 pub fn working_directory_path(&self) -> &Path {
51 pub fn working_directory_path(&self) -> &Path {
@@ -65,11 +75,15 b' impl Repo {'
65 }
75 }
66
76
67 impl Vfs<'_> {
77 impl Vfs<'_> {
78 pub(crate) fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
79 self.base.join(relative_path)
80 }
81
68 pub(crate) fn read(
82 pub(crate) fn read(
69 &self,
83 &self,
70 relative_path: impl AsRef<Path>,
84 relative_path: impl AsRef<Path>,
71 ) -> Result<Vec<u8>, HgError> {
85 ) -> Result<Vec<u8>, HgError> {
72 let path = self.base.join(relative_path);
86 let path = self.join(relative_path);
73 std::fs::read(&path).for_file(&path)
87 std::fs::read(&path).for_file(&path)
74 }
88 }
75
89
@@ -31,7 +31,6 b" impl<'a> Command for CatCommand<'a> {"
31 #[timed]
31 #[timed]
32 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
32 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
33 let repo = Repo::find()?;
33 let repo = Repo::find()?;
34 repo.check_requirements()?;
35 let cwd = hg::utils::current_dir()?;
34 let cwd = hg::utils::current_dir()?;
36
35
37 let mut files = vec![];
36 let mut files = vec![];
@@ -48,7 +48,6 b" impl<'a> FilesCommand<'a> {"
48 impl<'a> Command for FilesCommand<'a> {
48 impl<'a> Command for FilesCommand<'a> {
49 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
49 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
50 let repo = Repo::find()?;
50 let repo = Repo::find()?;
51 repo.check_requirements()?;
52 if let Some(rev) = self.rev {
51 if let Some(rev) = self.rev {
53 let files =
52 let files =
54 list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?;
53 list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?;
@@ -1,8 +1,10 b''
1 use crate::ui::utf8_to_local;
1 use crate::ui::utf8_to_local;
2 use crate::ui::UiError;
2 use crate::ui::UiError;
3 use hg::errors::{HgError, IoErrorContext};
3 use format_bytes::format_bytes;
4 use hg::operations::FindRootError;
4 use hg::errors::HgError;
5 use hg::repo::RepoFindError;
5 use hg::revlog::revlog::RevlogError;
6 use hg::revlog::revlog::RevlogError;
7 use hg::utils::files::get_bytes_from_path;
6 use std::convert::From;
8 use std::convert::From;
7
9
8 /// The kind of command error
10 /// The kind of command error
@@ -48,18 +50,18 b' impl From<UiError> for CommandError {'
48 }
50 }
49 }
51 }
50
52
51 impl From<FindRootError> for CommandError {
53 impl From<RepoFindError> for CommandError {
52 fn from(err: FindRootError) -> Self {
54 fn from(error: RepoFindError) -> Self {
53 match err {
55 match error {
54 FindRootError::RootNotFound(path) => CommandError::abort(format!(
56 RepoFindError::NotFoundInCurrentDirectoryOrAncestors {
55 "no repository found in '{}' (.hg not found)!",
57 current_directory,
56 path.display()
58 } => CommandError::Abort {
57 )),
59 message: format_bytes!(
58 FindRootError::GetCurrentDirError(error) => HgError::IoError {
60 b"no repository found in '{}' (.hg not found)!",
59 error,
61 get_bytes_from_path(current_directory)
60 context: IoErrorContext::CurrentDir,
62 ),
61 }
63 },
62 .into(),
64 RepoFindError::Other(error) => error.into(),
63 }
65 }
64 }
66 }
65 }
67 }
@@ -153,13 +153,7 b' Requirements'
153 [252]
153 [252]
154
154
155 $ rhg debugrequirements
155 $ rhg debugrequirements
156 dotencode
156 [252]
157 fncache
158 generaldelta
159 revlogv1
160 sparserevlog
161 store
162 indoor-pool
163
157
164 $ echo -e '\xFF' >> .hg/requires
158 $ echo -e '\xFF' >> .hg/requires
165 $ rhg debugrequirements
159 $ rhg debugrequirements
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now