use std::fs; use std::io; use std::path::PathBuf; use crate::pipeline::Stage; pub mod pipeline; const OUTPUT_GRAPH_DIR: &str = "graph"; pub type Result = io::Result; #[derive(Debug, Clone)] pub struct Config { pub output_dir: PathBuf, pub force: bool, pub target_stage: pipeline::Stage, } pub fn run(config: &Config) -> Result<()> { for stage in config.target_stage.with_prerequisites() { run_stage(config, stage)?; } Ok(()) } fn get_output_dir(config: &Config, stage: Stage) -> Result { let output_dir = config.output_dir.join(OUTPUT_GRAPH_DIR).join(stage.name()); if output_dir.exists() && !output_dir.is_dir() { return Err(io::Error::new( io::ErrorKind::NotADirectory, format!("output path is not a directory: {path}", path = output_dir.display()), )); } if output_dir.is_dir() && fs::read_dir(&output_dir)?.next().transpose()?.is_some() { if !config.force { return Err(io::Error::new( io::ErrorKind::AlreadyExists, format!( "output directory already exists and is not empty: {path}", path = output_dir.display() ), )); } fs::remove_dir_all(&output_dir)?; } fs::create_dir_all(&output_dir)?; Ok(output_dir) } fn run_stage(config: &Config, stage: Stage) -> Result<()> { let output_dir = get_output_dir(config, stage)?; pipeline::run_stage(stage, &output_dir) }