Mercurial > public > mercurial-scm > hg
diff 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 |
line wrap: on
line diff
--- a/rust/hg-core/src/repo.rs Thu Jan 28 19:13:55 2021 +0100 +++ b/rust/hg-core/src/repo.rs Thu Jan 28 20:31:42 2021 +0100 @@ -1,5 +1,4 @@ use crate::errors::{HgError, IoResultExt}; -use crate::operations::{find_root, FindRootError}; use crate::requirements; use memmap::{Mmap, MmapOptions}; use std::path::{Path, PathBuf}; @@ -11,6 +10,15 @@ store: PathBuf, } +#[derive(Debug, derive_more::From)] +pub enum RepoFindError { + NotFoundInCurrentDirectoryOrAncestors { + current_directory: PathBuf, + }, + #[from] + Other(HgError), +} + /// Filesystem access abstraction for the contents of a given "base" diretory #[derive(Clone, Copy)] pub(crate) struct Vfs<'a> { @@ -18,24 +26,26 @@ } impl Repo { - /// Returns `None` if the given path doesn’t look like a repository - /// (doesn’t contain a `.hg` sub-directory). - pub fn for_path(root: impl Into<PathBuf>) -> Self { - let working_directory = root.into(); - let dot_hg = working_directory.join(".hg"); - Self { - store: dot_hg.join("store"), - dot_hg, - working_directory, + /// Search the current directory and its ancestores for a repository: + /// a working directory that contains a `.hg` sub-directory. + pub fn find() -> Result<Self, RepoFindError> { + let current_directory = crate::utils::current_dir()?; + // ancestors() is inclusive: it first yields `current_directory` as-is. + for ancestor in current_directory.ancestors() { + let dot_hg = ancestor.join(".hg"); + if dot_hg.is_dir() { + let repo = Self { + store: dot_hg.join("store"), + dot_hg, + working_directory: ancestor.to_owned(), + }; + requirements::check(&repo)?; + return Ok(repo); + } } - } - - pub fn find() -> Result<Self, FindRootError> { - find_root().map(Self::for_path) - } - - pub fn check_requirements(&self) -> Result<(), HgError> { - requirements::check(self) + Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors { + current_directory, + }) } pub fn working_directory_path(&self) -> &Path { @@ -65,11 +75,15 @@ } impl Vfs<'_> { + pub(crate) fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf { + self.base.join(relative_path) + } + pub(crate) fn read( &self, relative_path: impl AsRef<Path>, ) -> Result<Vec<u8>, HgError> { - let path = self.base.join(relative_path); + let path = self.join(relative_path); std::fs::read(&path).for_file(&path) }