use crate::dependent_version_content::{ContentUnavailable, TrackedPath, WorkspaceContent};
use crate::dependent_version_graph::{WorkspaceNode, transitive_dependent_names};
use crate::dependent_version_imports::imports_package;
use crate::dependent_version_paths::is_non_test_source_path;
use crate::dependent_version_states::ManifestState;
use std::collections::HashSet;
fn candidate_edges(state: &ManifestState, relevant: &HashSet<String>) -> Vec<String> {
let mut edges: Vec<String> = Vec::new();
for name in &state.facts.dev_dependency_names {
if relevant.contains(name) && *name != state.facts.name {
edges.push(name.clone());
}
}
return edges;
}
fn source_texts(
content: &mut dyn WorkspaceContent,
tracked: &[TrackedPath],
directory: &[u8],
) -> Result<Vec<String>, ContentUnavailable> {
let mut texts: Vec<String> = Vec::new();
for entry in tracked {
if is_non_test_source_path(directory, &entry.path) {
let bytes: Vec<u8> = content.candidate_bytes(&entry.path)?;
texts.push(String::from_utf8_lossy(&bytes).into_owned());
}
}
return Ok(texts);
}
pub fn bundled_development_edges(
content: &mut dyn WorkspaceContent,
tracked: &[TrackedPath],
states: &[ManifestState],
bumped_names: &[String],
) -> Result<Vec<Vec<String>>, ContentUnavailable> {
let mut every_edge: Vec<WorkspaceNode> = Vec::new();
for state in states {
every_edge.push(WorkspaceNode {
name: state.facts.name.clone(),
directory: state.directory.clone(),
version: None,
edge_names: [
state.facts.runtime_dependency_names.as_slice(),
state.facts.dev_dependency_names.as_slice(),
]
.concat(),
});
}
let mut relevant: HashSet<String> = transitive_dependent_names(&every_edge, bumped_names);
relevant.extend(bumped_names.iter().cloned());
let mut bundled: Vec<Vec<String>> = Vec::new();
for state in states {
let candidates: Vec<String> = candidate_edges(state, &relevant);
if candidates.is_empty() {
bundled.push(Vec::new());
continue;
}
let texts: Vec<String> = source_texts(content, tracked, &state.directory)?;
let mut imported: Vec<String> = Vec::new();
for name in candidates {
let mut found: bool = false;
for text in &texts {
if imports_package(text, &name) {
found = true;
break;
}
}
if found {
imported.push(name);
}
}
bundled.push(imported);
}
return Ok(bundled);
}
#[cfg(test)]
#[path = "dependent_version_bundled_tests.rs"]
mod tests;