fn process_path()

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
}