use crate::git::co_change::CoChangeMatrix;
use crate::graph::builder::GraphBuilder;
use crate::graph::frozen::CodeGraph;
use crate::parsers::ParseResult;
use crate::values::store::ValueStore;
use anyhow::Result;
use std::path::{Path, PathBuf};
use std::sync::Arc;
pub struct GraphInput<'a> {
pub parse_results: &'a [(PathBuf, Arc<ParseResult>)],
pub repo_path: &'a Path,
}
pub struct GraphOutput {
pub mutable_graph: GraphBuilder,
pub value_store: Option<Arc<ValueStore>>,
}
pub struct FrozenGraphOutput {
pub graph: Arc<CodeGraph>,
pub value_store: Option<Arc<ValueStore>>,
pub edge_fingerprint: u64,
}
pub struct GraphPatchInput {
pub mutable_graph: GraphBuilder,
pub changed_files: Vec<PathBuf>,
pub removed_files: Vec<PathBuf>,
pub new_parse_results: Vec<(PathBuf, Arc<ParseResult>)>,
pub repo_path: PathBuf,
}
pub fn graph_stage(input: &GraphInput) -> Result<GraphOutput> {
let mut graph = GraphBuilder::new();
let multi = indicatif::MultiProgress::with_draw_target(
indicatif::ProgressDrawTarget::hidden(),
);
let bar_style = indicatif::ProgressStyle::default_bar();
let value_store = crate::cli::analyze::graph::build_graph(
&mut graph,
input.repo_path,
input.parse_results,
&multi,
&bar_style,
)?;
Ok(GraphOutput {
mutable_graph: graph,
value_store: Some(Arc::new(value_store)),
})
}
pub fn freeze_graph(
builder: GraphBuilder,
value_store: Option<Arc<ValueStore>>,
co_change: Option<&CoChangeMatrix>,
) -> FrozenGraphOutput {
let code_graph = if let Some(cc) = co_change {
builder.freeze_with_co_change(cc)
} else {
builder.freeze()
};
let edge_fingerprint = code_graph.edge_fingerprint();
FrozenGraphOutput {
graph: Arc::new(code_graph),
value_store,
edge_fingerprint,
}
}
pub fn graph_patch_stage(input: GraphPatchInput) -> Result<GraphOutput> {
let mut graph = input.mutable_graph;
let files_to_remove: Vec<PathBuf> = input
.changed_files
.iter()
.chain(input.removed_files.iter())
.filter_map(|p| {
p.strip_prefix(&input.repo_path)
.ok()
.map(|r| r.to_path_buf())
})
.collect();
graph.remove_file_entities(&files_to_remove);
if !input.new_parse_results.is_empty() {
let multi = indicatif::MultiProgress::with_draw_target(
indicatif::ProgressDrawTarget::hidden(),
);
let bar_style = indicatif::ProgressStyle::default_bar();
let value_store = crate::cli::analyze::graph::build_graph(
&mut graph,
&input.repo_path,
&input.new_parse_results,
&multi,
&bar_style,
)?;
Ok(GraphOutput {
mutable_graph: graph,
value_store: Some(Arc::new(value_store)),
})
} else {
Ok(GraphOutput {
mutable_graph: graph,
value_store: None,
})
}
}