rust/hg-core/src/repo.rs
changeset 46446 1dcd9c9975ed
parent 46443 43d63979a75e
child 46462 d03b0601e0eb
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,