in tools/determinator/src/determinator.rs [371:424]
fn process_path<'g>(
path: &Utf8Path,
workspace: &Workspace<'g>,
path_rules: &[PathRuleImpl<'g>],
mut match_cb: impl FnMut(&'g PackageId),
) -> PathMatch {
let candidate = Candidate::new(path);
// 1. Apply any rules that match the path.
for rule in path_rules {
if rule.glob_set.is_match_candidate(&candidate) {
// This glob matches this rule, so execute it.
match &rule.mark_changed {
MarkChangedImpl::Packages(packages) => {
for package in packages {
match_cb(package.id());
}
}
MarkChangedImpl::All => {
// Mark all packages changed.
return PathMatch::RuleMatchedAll;
}
}
match &rule.post_rule {
DeterminatorPostRule::Skip => {
// Skip all further processing for this path but continue reading other
// paths.
return PathMatch::RuleMatched(rule.rule_index);
}
DeterminatorPostRule::SkipRules => {
// Skip further rule processing but continue to step 2 to match to the
// nearest package.
break;
}
DeterminatorPostRule::Fallthrough => {
// Continue applying rules.
continue;
}
}
}
}
// 2. Map the path to its nearest ancestor package.
for ancestor in path.ancestors() {
if let Ok(package) = workspace.member_by_path(ancestor) {
match_cb(package.id());
return PathMatch::AncestorMatched;
}
}
// 3. If a file didn't match anything so far, rebuild everything.
PathMatch::NoMatches
}