in src/rust/engine/fs/src/lib.rs [328:404]
fn parse_globs(
canonical_dir: Dir,
symbolic_path: PathBuf,
parts: &[Pattern],
) -> Result<Vec<PathGlob>, String> {
if parts.is_empty() {
Ok(vec![])
} else if *DOUBLE_STAR == parts[0].as_str() {
if parts.len() == 1 {
// Per https://git-scm.com/docs/gitignore:
// "A trailing '/**' matches everything inside. For example, 'abc/**' matches all files
// inside directory "abc", relative to the location of the .gitignore file, with infinite
// depth."
return Ok(vec![
PathGlob::dir_wildcard(
canonical_dir.clone(),
symbolic_path.clone(),
SINGLE_STAR_GLOB.clone(),
vec![DOUBLE_STAR_GLOB.clone()],
),
PathGlob::wildcard(canonical_dir, symbolic_path, SINGLE_STAR_GLOB.clone()),
]);
}
// There is a double-wildcard in a dirname of the path: double wildcards are recursive,
// so there are two remainder possibilities: one with the double wildcard included, and the
// other without.
let pathglob_with_doublestar = PathGlob::dir_wildcard(
canonical_dir.clone(),
symbolic_path.clone(),
SINGLE_STAR_GLOB.clone(),
parts[0..].to_vec(),
);
let pathglob_no_doublestar = if parts.len() == 2 {
PathGlob::wildcard(canonical_dir, symbolic_path, parts[1].clone())
} else {
PathGlob::dir_wildcard(
canonical_dir,
symbolic_path,
parts[1].clone(),
parts[2..].to_vec(),
)
};
Ok(vec![pathglob_with_doublestar, pathglob_no_doublestar])
} else if *PARENT_DIR == parts[0].as_str() {
// A request for the parent of `canonical_dir`: since we've already expanded the directory
// to make it canonical, we can safely drop it directly and recurse without this component.
// The resulting symbolic path will continue to contain a literal `..`.
let mut canonical_dir_parent = canonical_dir;
let mut symbolic_path_parent = symbolic_path;
if !canonical_dir_parent.0.pop() {
let mut symbolic_path = symbolic_path_parent;
symbolic_path.extend(parts.iter().map(Pattern::as_str));
return Err(format!(
"Globs may not traverse outside of the buildroot: {:?}",
symbolic_path,
));
}
symbolic_path_parent.push(Path::new(*PARENT_DIR));
PathGlob::parse_globs(canonical_dir_parent, symbolic_path_parent, &parts[1..])
} else if parts.len() == 1 {
// This is the path basename.
Ok(vec![PathGlob::wildcard(
canonical_dir,
symbolic_path,
parts[0].clone(),
)])
} else {
// This is a path dirname.
Ok(vec![PathGlob::dir_wildcard(
canonical_dir,
symbolic_path,
parts[0].clone(),
parts[1..].to_vec(),
)])
}
}