comparison rust/hg-core/src/repo.rs @ 46446:1dcd9c9975ed

rust: Fold find_root and check_requirements into Repo::find Differential Revision: https://phab.mercurial-scm.org/D9906
author Simon Sapin <simon.sapin@octobus.net>
date Thu, 28 Jan 2021 20:31:42 +0100
parents 43d63979a75e
children d03b0601e0eb
comparison
equal deleted inserted replaced
46445:ca3f73cc3cf4 46446:1dcd9c9975ed
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};
6 5
7 /// A repository on disk 6 /// A repository on disk
9 working_directory: PathBuf, 8 working_directory: PathBuf,
10 dot_hg: PathBuf, 9 dot_hg: PathBuf,
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> {
17 base: &'a Path, 25 base: &'a Path,
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 {
42 &self.working_directory 52 &self.working_directory
43 } 53 }
63 } 73 }
64 } 74 }
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
76 pub(crate) fn mmap_open( 90 pub(crate) fn mmap_open(
77 &self, 91 &self,