mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
manifest: rename FsNode to FsNodeMetadata
Summary: Consistency in naming. The general idea is to have Metadata types that don't contain paths. Then we will have File, Directory and eventually FsNode that will contain paths. Reviewed By: quark-zju Differential Revision: D18870141 fbshipit-source-id: a1f09add7f1c3dd4fa0348693cd3ce2fd5767fa7
This commit is contained in:
parent
05aa630a18
commit
67b0e3a600
@ -16,7 +16,7 @@ use cpython::*;
|
||||
use cpython_ext::{pyset_add, pyset_new};
|
||||
use cpython_failure::ResultPyErrExt;
|
||||
use encoding::{local_bytes_to_repo_path, repo_path_to_local_bytes};
|
||||
use manifest::{DiffType, File, FileMetadata, FileType, FsNode, Manifest};
|
||||
use manifest::{DiffType, File, FileMetadata, FileType, FsNodeMetadata, Manifest};
|
||||
use manifest_tree::TreeManifest;
|
||||
use pathmatcher::{AlwaysMatcher, Matcher, TreeMatcher};
|
||||
use pypathmatcher::PythonMatcher;
|
||||
@ -162,7 +162,7 @@ py_class!(class treemanifest |py| {
|
||||
let repo_path = pybytes_to_path(py, path);
|
||||
let tree = self.underlying(py).borrow();
|
||||
let result = match tree.get(&repo_path).map_pyerr::<exc::RuntimeError>(py)? {
|
||||
Some(FsNode::Directory(_)) => true,
|
||||
Some(FsNodeMetadata::Directory(_)) => true,
|
||||
_ => false
|
||||
};
|
||||
Ok(result)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
use crate::raw::CBytes;
|
||||
use anyhow::{format_err, Result};
|
||||
use manifest::{FileType, FsNode};
|
||||
use manifest::{FileType, FsNodeMetadata};
|
||||
use manifest_tree::List;
|
||||
use std::convert::TryFrom;
|
||||
use types::PathComponentBuf;
|
||||
@ -45,10 +45,12 @@ pub struct TreeEntry {
|
||||
}
|
||||
|
||||
impl TreeEntry {
|
||||
fn try_from_path_node(path: PathComponentBuf, node: FsNode) -> Result<Self> {
|
||||
fn try_from_path_node(path: PathComponentBuf, node: FsNodeMetadata) -> Result<Self> {
|
||||
let (ttype, hash) = match node {
|
||||
FsNode::Directory(Some(hgid)) => (TreeEntryType::Tree, hgid.as_ref().to_vec()),
|
||||
FsNode::File(metadata) => (metadata.file_type.into(), metadata.hgid.as_ref().to_vec()),
|
||||
FsNodeMetadata::Directory(Some(hgid)) => (TreeEntryType::Tree, hgid.as_ref().to_vec()),
|
||||
FsNodeMetadata::File(metadata) => {
|
||||
(metadata.file_type.into(), metadata.hgid.as_ref().to_vec())
|
||||
}
|
||||
_ => return Err(format_err!("received an ephemeral directory")),
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,7 @@ use std::collections::{btree_map, VecDeque};
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
|
||||
use manifest::FsNode;
|
||||
use manifest::FsNodeMetadata;
|
||||
use pathmatcher::Matcher;
|
||||
use types::{Key, PathComponentBuf, RepoPath, RepoPathBuf};
|
||||
|
||||
@ -52,13 +52,15 @@ impl<'a> BfsIter<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Iterator for BfsIter<'a> {
|
||||
type Item = Result<(RepoPathBuf, FsNode)>;
|
||||
type Item = Result<(RepoPathBuf, FsNodeMetadata)>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (path, children, hgid) = match self.queue.pop_front() {
|
||||
None => return None,
|
||||
Some((path, link)) => match link {
|
||||
Link::Leaf(file_metadata) => return Some(Ok((path, FsNode::File(*file_metadata)))),
|
||||
Link::Leaf(file_metadata) => {
|
||||
return Some(Ok((path, FsNodeMetadata::File(*file_metadata))))
|
||||
}
|
||||
Link::Ephemeral(children) => (path, children, None),
|
||||
Link::Durable(entry) => loop {
|
||||
match entry.get_links() {
|
||||
@ -81,7 +83,7 @@ impl<'a> Iterator for BfsIter<'a> {
|
||||
self.queue.push_back((child_path, &link));
|
||||
}
|
||||
}
|
||||
Some(Ok((path, FsNode::Directory(hgid))))
|
||||
Some(Ok((path, FsNodeMetadata::Directory(hgid))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ use crypto::{digest::Digest, sha1::Sha1};
|
||||
use once_cell::sync::OnceCell;
|
||||
use thiserror::Error;
|
||||
|
||||
use manifest::{DiffEntry, Directory, File, FileMetadata, FsNode, Manifest};
|
||||
use manifest::{DiffEntry, Directory, File, FileMetadata, FsNodeMetadata, Manifest};
|
||||
use pathmatcher::Matcher;
|
||||
use types::{HgId, Key, PathComponent, PathComponentBuf, RepoPath, RepoPathBuf};
|
||||
|
||||
@ -94,7 +94,7 @@ impl TreeManifest {
|
||||
}
|
||||
|
||||
impl Manifest for TreeManifest {
|
||||
fn get(&self, path: &RepoPath) -> Result<Option<FsNode>> {
|
||||
fn get(&self, path: &RepoPath) -> Result<Option<FsNodeMetadata>> {
|
||||
let result = self.get_link(path)?.map(|link| link.to_fs_node());
|
||||
Ok(result)
|
||||
}
|
||||
@ -264,7 +264,7 @@ impl Manifest for TreeManifest {
|
||||
matcher: &'a M,
|
||||
) -> Box<dyn Iterator<Item = Result<File>> + 'a> {
|
||||
let files = BfsIter::new(&self, matcher).filter_map(|result| match result {
|
||||
Ok((path, FsNode::File(metadata))) => Some(Ok(File::new(path, metadata))),
|
||||
Ok((path, FsNodeMetadata::File(metadata))) => Some(Ok(File::new(path, metadata))),
|
||||
Ok(_) => None,
|
||||
Err(e) => Some(Err(e)),
|
||||
});
|
||||
@ -281,7 +281,9 @@ impl Manifest for TreeManifest {
|
||||
matcher: &'a M,
|
||||
) -> Box<dyn Iterator<Item = Result<Directory>> + 'a> {
|
||||
let dirs = BfsIter::new(&self, matcher).filter_map(|result| match result {
|
||||
Ok((path, FsNode::Directory(metadata))) => Some(Ok(Directory::new(path, metadata))),
|
||||
Ok((path, FsNodeMetadata::Directory(metadata))) => {
|
||||
Some(Ok(Directory::new(path, metadata)))
|
||||
}
|
||||
Ok(_) => None,
|
||||
Err(e) => Some(Err(e)),
|
||||
});
|
||||
@ -539,7 +541,7 @@ impl TreeManifest {
|
||||
pub enum List {
|
||||
NotFound,
|
||||
File,
|
||||
Directory(Vec<(PathComponentBuf, FsNode)>),
|
||||
Directory(Vec<(PathComponentBuf, FsNodeMetadata)>),
|
||||
}
|
||||
|
||||
/// The purpose of this function is to provide compatible behavior with the C++ implementation
|
||||
@ -823,11 +825,11 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
tree.get(repo_path("foo/bar")).unwrap(),
|
||||
Some(FsNode::Directory(None))
|
||||
Some(FsNodeMetadata::Directory(None))
|
||||
);
|
||||
assert_eq!(
|
||||
tree.get(repo_path("foo")).unwrap(),
|
||||
Some(FsNode::Directory(None))
|
||||
Some(FsNodeMetadata::Directory(None))
|
||||
);
|
||||
}
|
||||
|
||||
@ -865,7 +867,7 @@ mod tests {
|
||||
assert_eq!(tree.get(repo_path("a1/b1/c1")).unwrap(), None);
|
||||
assert_eq!(
|
||||
tree.get(repo_path("a1/b2")).unwrap(),
|
||||
Some(FsNode::File(make_meta("20")))
|
||||
Some(FsNodeMetadata::File(make_meta("20")))
|
||||
);
|
||||
assert_eq!(
|
||||
tree.remove(repo_path("a1/b2")).unwrap(),
|
||||
@ -875,7 +877,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
tree.get(repo_path("a2/b2/c2")).unwrap(),
|
||||
Some(FsNode::File(make_meta("30")))
|
||||
Some(FsNodeMetadata::File(make_meta("30")))
|
||||
);
|
||||
assert_eq!(
|
||||
tree.remove(repo_path("a2/b2/c2")).unwrap(),
|
||||
@ -885,7 +887,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
tree.get(RepoPath::empty()).unwrap(),
|
||||
Some(FsNode::Directory(None))
|
||||
Some(FsNodeMetadata::Directory(None))
|
||||
);
|
||||
}
|
||||
|
||||
@ -913,7 +915,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
tree.get(RepoPath::empty()).unwrap(),
|
||||
Some(FsNode::Directory(Some(tree_hgid)))
|
||||
Some(FsNodeMetadata::Directory(Some(tree_hgid)))
|
||||
);
|
||||
assert_eq!(tree.remove(repo_path("a1")).unwrap(), None);
|
||||
assert_eq!(
|
||||
@ -923,7 +925,7 @@ mod tests {
|
||||
assert_eq!(tree.get(repo_path("a1/b1")).unwrap(), None);
|
||||
assert_eq!(
|
||||
tree.get(repo_path("a1/b2")).unwrap(),
|
||||
Some(FsNode::File(make_meta("12")))
|
||||
Some(FsNodeMetadata::File(make_meta("12")))
|
||||
);
|
||||
assert_eq!(
|
||||
tree.remove(repo_path("a1/b2")).unwrap(),
|
||||
@ -935,13 +937,13 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
tree.get(repo_path("a2")).unwrap(),
|
||||
Some(FsNode::File(make_meta("20")))
|
||||
Some(FsNodeMetadata::File(make_meta("20")))
|
||||
);
|
||||
assert_eq!(tree.remove(repo_path("a2")).unwrap(), Some(make_meta("20")));
|
||||
assert_eq!(tree.get(repo_path("a2")).unwrap(), None);
|
||||
assert_eq!(
|
||||
tree.get(RepoPath::empty()).unwrap(),
|
||||
Some(FsNode::Directory(None))
|
||||
Some(FsNodeMetadata::Directory(None))
|
||||
);
|
||||
}
|
||||
|
||||
@ -1450,7 +1452,10 @@ mod tests {
|
||||
assert_eq!(tree.list(repo_path("a1/b1/c1")).unwrap(), List::File);
|
||||
assert_eq!(
|
||||
tree.list(repo_path("a1/b1")).unwrap(),
|
||||
List::Directory(vec![(path_component_buf("c1"), FsNode::File(c1_meta))]),
|
||||
List::Directory(vec![(
|
||||
path_component_buf("c1"),
|
||||
FsNodeMetadata::File(c1_meta)
|
||||
)]),
|
||||
);
|
||||
assert_eq!(
|
||||
tree.list(repo_path("a1")).unwrap(),
|
||||
@ -1459,19 +1464,22 @@ mod tests {
|
||||
path_component_buf("b1"),
|
||||
tree.get(repo_path("a1/b1")).unwrap().unwrap()
|
||||
),
|
||||
(path_component_buf("b2"), FsNode::File(b2_meta)),
|
||||
(path_component_buf("b2"), FsNodeMetadata::File(b2_meta)),
|
||||
]),
|
||||
);
|
||||
assert_eq!(tree.list(repo_path("a2/b3/c2")).unwrap(), List::File);
|
||||
assert_eq!(
|
||||
tree.list(repo_path("a2/b3")).unwrap(),
|
||||
List::Directory(vec![(path_component_buf("c2"), FsNode::File(c2_meta))]),
|
||||
List::Directory(vec![(
|
||||
path_component_buf("c2"),
|
||||
FsNodeMetadata::File(c2_meta)
|
||||
)]),
|
||||
);
|
||||
assert_eq!(
|
||||
tree.list(repo_path("a2")).unwrap(),
|
||||
List::Directory(vec![
|
||||
(path_component_buf("b3"), FsNode::Directory(None)),
|
||||
(path_component_buf("b4"), FsNode::File(b4_meta)),
|
||||
(path_component_buf("b3"), FsNodeMetadata::Directory(None)),
|
||||
(path_component_buf("b4"), FsNodeMetadata::File(b4_meta)),
|
||||
]),
|
||||
);
|
||||
assert_eq!(
|
||||
@ -1481,7 +1489,7 @@ mod tests {
|
||||
path_component_buf("a1"),
|
||||
tree.get(repo_path("a1")).unwrap().unwrap()
|
||||
),
|
||||
(path_component_buf("a2"), FsNode::Directory(None)),
|
||||
(path_component_buf("a2"), FsNodeMetadata::Directory(None)),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use std::{cmp::Ordering, collections::BTreeMap, sync::Arc};
|
||||
use anyhow::{bail, format_err, Context, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use manifest::{File, FileMetadata, FsNode};
|
||||
use manifest::{File, FileMetadata, FsNodeMetadata};
|
||||
use pathmatcher::{DirectoryMatch, Matcher};
|
||||
use types::{HgId, Key, PathComponentBuf, RepoPath, RepoPathBuf};
|
||||
|
||||
@ -77,11 +77,11 @@ impl Link {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_fs_node(&self) -> FsNode {
|
||||
pub fn to_fs_node(&self) -> FsNodeMetadata {
|
||||
match self {
|
||||
&Link::Leaf(metadata) => FsNode::File(metadata),
|
||||
Link::Ephemeral(_) => FsNode::Directory(None),
|
||||
Link::Durable(durable) => FsNode::Directory(Some(durable.hgid)),
|
||||
&Link::Leaf(metadata) => FsNodeMetadata::File(metadata),
|
||||
Link::Ephemeral(_) => FsNodeMetadata::Directory(None),
|
||||
Link::Durable(durable) => FsNodeMetadata::Directory(Some(durable.hgid)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,11 @@ use types::{HgId, RepoPath, RepoPathBuf};
|
||||
/// determined previously to be directories will result in Errors.
|
||||
pub trait Manifest {
|
||||
/// Inspects the manifest for the given path.
|
||||
/// If the path is pointing to an file then Some(FsNode::File) is returned with then
|
||||
/// If the path is pointing to an file then Some(FsNodeMetadata::File) is returned with then
|
||||
/// file_metadata associated with the file. If the path is poitning to a directory then
|
||||
/// Some(FsNode::Directory) is returned. If the path is not found then None is returned.
|
||||
fn get(&self, path: &RepoPath) -> Result<Option<FsNode>>;
|
||||
/// Some(FsNodeMetadata::Directory) is returned. If the path is not found then None is
|
||||
/// returned.
|
||||
fn get(&self, path: &RepoPath) -> Result<Option<FsNodeMetadata>>;
|
||||
|
||||
/// Associates a file path with specific file metadata.
|
||||
/// A call with a file path that already exists results in an override or the old metadata.
|
||||
@ -50,8 +51,8 @@ pub trait Manifest {
|
||||
/// Paths that were not set will return None.
|
||||
fn get_file(&self, file_path: &RepoPath) -> Result<Option<FileMetadata>> {
|
||||
let result = self.get(file_path)?.and_then(|fs_hgid| match fs_hgid {
|
||||
FsNode::File(file_metadata) => Some(file_metadata),
|
||||
FsNode::Directory(_) => None,
|
||||
FsNodeMetadata::File(file_metadata) => Some(file_metadata),
|
||||
FsNodeMetadata::Directory(_) => None,
|
||||
});
|
||||
Ok(result)
|
||||
}
|
||||
@ -80,17 +81,34 @@ pub trait Manifest {
|
||||
) -> Box<dyn Iterator<Item = Result<DiffEntry>> + 'a>;
|
||||
}
|
||||
|
||||
/// FsNode short for file system node.
|
||||
/// FsNodeMetadata short for file system node.
|
||||
/// The manifest tracks a list of files. However file systems are hierarchical structures
|
||||
/// composed of directories and files at the end. For different operations it is useful to have
|
||||
/// a representation for file or directory. A good example is listing a directory. This structure
|
||||
/// helps us represent that notion.
|
||||
#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||
pub enum FsNode {
|
||||
pub enum FsNodeMetadata {
|
||||
Directory(Option<HgId>),
|
||||
File(FileMetadata),
|
||||
}
|
||||
|
||||
/// A directory entry in a manifest.
|
||||
///
|
||||
/// Consists of the full path to the directory. Directories may or may not be assigned
|
||||
/// identifiers. When an identifier is available it is also returned.
|
||||
// TODO: Move hgid to a new DirectoryMetadata struct.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct Directory {
|
||||
pub path: RepoPathBuf,
|
||||
pub hgid: Option<HgId>,
|
||||
}
|
||||
|
||||
impl Directory {
|
||||
pub fn new(path: RepoPathBuf, hgid: Option<HgId>) -> Self {
|
||||
Self { path, hgid }
|
||||
}
|
||||
}
|
||||
|
||||
/// A file entry in a manifest.
|
||||
///
|
||||
/// Consists of the full path to the file along with the associated file metadata.
|
||||
@ -106,22 +124,6 @@ impl File {
|
||||
}
|
||||
}
|
||||
|
||||
/// A directory entry in a manifest.
|
||||
///
|
||||
/// Consists of the full path to the directory. Directories may or may not be assigned
|
||||
/// identifiers. When an identifier is available it is also returned.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct Directory {
|
||||
pub path: RepoPathBuf,
|
||||
pub hgid: Option<HgId>,
|
||||
}
|
||||
|
||||
impl Directory {
|
||||
pub fn new(path: RepoPathBuf, hgid: Option<HgId>) -> Self {
|
||||
Self { path, hgid }
|
||||
}
|
||||
}
|
||||
|
||||
/// The contents of the Manifest for a file.
|
||||
/// * hgid: used to determine the revision of the file in the repository.
|
||||
/// * file_type: determines the type of the file.
|
||||
|
Loading…
Reference in New Issue
Block a user