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_package_ids = graph.files_to_package_ids(changed_files);
if direct_package_ids.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 direct_crates: HashSet<String> = direct_package_ids
.iter()
.filter_map(|package_id| graph.package(package_id).map(|package| package.name.clone()))
.collect();
let all_dependents = graph.transitive_dependents_of_ids(&direct_package_ids)?;
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,
},
})
}