Skip to main content

relay_knowledge/code/source/layout/
impact_partition.rs

1use std::path::PathBuf;
2
3use crate::{
4    code::{
5        CodeIndexError,
6        source::repository::{source_commit_is_filesystem, source_snapshot},
7    },
8    domain::{CodeImpactPathGroups, CodeRepositoryRegistration, CodeRepositorySelector},
9};
10
11use super::{
12    discovery::discover_source_layout,
13    scoped_snapshot::{filesystem_policy_for_selector, scoped_source_snapshot},
14    selection::selection_exclusion_reason_for_source,
15};
16
17/// Splits diff paths by the same selector rules used by indexing and impact.
18pub fn partition_changed_paths_for_selector(
19    registration: &CodeRepositoryRegistration,
20    selector: &CodeRepositorySelector,
21    paths: Vec<String>,
22) -> Result<CodeImpactPathGroups, CodeIndexError> {
23    if paths.is_empty() {
24        return Ok(CodeImpactPathGroups {
25            in_scope_changed_paths: Vec::new(),
26            out_of_scope_changed_paths: Vec::new(),
27        });
28    }
29    let root = PathBuf::from(&registration.root_path);
30    let filesystem_policy = filesystem_policy_for_selector(registration, selector);
31    let (source_layout, source_kind) = if source_commit_is_filesystem(&selector.ref_selector) {
32        let snapshot =
33            scoped_source_snapshot(registration, selector, &root, &selector.ref_selector)?;
34        (discover_source_layout(&snapshot.entries), snapshot.kind)
35    } else {
36        let snapshot = source_snapshot(&root, &selector.ref_selector, filesystem_policy)?;
37        (discover_source_layout(&snapshot.entries), snapshot.kind)
38    };
39    let mut in_scope_changed_paths = Vec::new();
40    let mut out_of_scope_changed_paths = Vec::new();
41    for path in paths {
42        if selection_exclusion_reason_for_source(
43            &path,
44            registration,
45            selector,
46            &source_layout,
47            source_kind,
48        )
49        .is_none()
50        {
51            in_scope_changed_paths.push(path);
52        } else {
53            out_of_scope_changed_paths.push(path);
54        }
55    }
56    in_scope_changed_paths.sort();
57    in_scope_changed_paths.dedup();
58    out_of_scope_changed_paths.sort();
59    out_of_scope_changed_paths.dedup();
60
61    Ok(CodeImpactPathGroups {
62        in_scope_changed_paths,
63        out_of_scope_changed_paths,
64    })
65}
66
67#[cfg(test)]
68#[path = "impact_partition_tests.rs"]
69mod tests;