use super::core::WorkspaceGraph;
use crate::error::RailResult;
use std::collections::HashSet;
use std::path::Path;
#[derive(Debug, Clone)]
pub struct AffectedSet {
pub direct: HashSet<String>,
pub dependents: HashSet<String>,
pub test_targets: HashSet<String>,
}
#[derive(Debug, Clone)]
pub struct AffectedAnalysis {
pub changed_files: Vec<String>,
pub impact: AffectedSet,
}
pub fn analyze(graph: &WorkspaceGraph, changed_files: &[impl AsRef<Path>]) -> RailResult<AffectedAnalysis> {
if changed_files.is_empty() {
return Ok(AffectedAnalysis {
changed_files: vec![],
impact: AffectedSet {
direct: HashSet::new(),
dependents: HashSet::new(),
test_targets: HashSet::new(),
},
});
}
let direct_crates = graph.files_to_crates(changed_files);
if direct_crates.is_empty() {
return Ok(AffectedAnalysis {
changed_files: changed_files.iter().map(|p| p.as_ref().display().to_string()).collect(),
impact: AffectedSet {
direct: HashSet::new(),
dependents: HashSet::new(),
test_targets: HashSet::new(),
},
});
}
let all_dependents = graph.transitive_dependents_of_set(&direct_crates)?;
let mut test_targets = direct_crates.clone();
test_targets.extend(all_dependents.clone());
Ok(AffectedAnalysis {
changed_files: changed_files.iter().map(|p| p.as_ref().display().to_string()).collect(),
impact: AffectedSet {
direct: direct_crates,
dependents: all_dependents,
test_targets,
},
})
}