From 233abbe4ff4073effc860efb6f8c0972f1ff5064 Mon Sep 17 00:00:00 2001 From: Sebastian Kuzminsky Date: Wed, 22 Jan 2025 14:37:18 -0600 Subject: [PATCH] start adding build_plan to track the build process for a job --- tools/src/bin/parser/main.rs | 3 ++- tools/src/build_plan.rs | 30 ++++++++++++++++++++++++++++++ tools/src/lib.rs | 3 +++ tools/src/repos.rs | 29 ++++++++++++++++++++++++++--- 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 tools/src/build_plan.rs diff --git a/tools/src/bin/parser/main.rs b/tools/src/bin/parser/main.rs index 552cbe2..96a4697 100644 --- a/tools/src/bin/parser/main.rs +++ b/tools/src/bin/parser/main.rs @@ -20,6 +20,7 @@ fn main() -> anyhow::Result<()> { for repo_path in &args.repo { repos.add_repo(repo_path)?; } - repos.compile(&args.target)?; + let build_plan = repos.compile(&args.target)?; + println!("{build_plan:#?}"); Ok(()) } diff --git a/tools/src/build_plan.rs b/tools/src/build_plan.rs new file mode 100644 index 0000000..be03c6e --- /dev/null +++ b/tools/src/build_plan.rs @@ -0,0 +1,30 @@ +// This is a representation of the recipes/steps that result in a +// desired Output. It's a path from starting points/vitamins to the +// desired Output. + +use crate::quantity::*; + +// FIXME: this isn't the correct abstraction for Item +#[derive(Debug)] +pub struct Item { + pub name: String, + pub quantity: Quantity, +} + +#[derive(Debug)] +pub struct BuildPlan<'a> { + // Keys are the names of Items. + // Values are Items, which are just the name and a Quantity. + pub bom: std::collections::HashMap, + + pub repos: &'a crate::repos::Repos, +} + +impl<'a> BuildPlan<'a> { + pub fn new(repos: &'a crate::repos::Repos) -> Self { + BuildPlan { + bom: std::collections::HashMap::::new(), + repos, + } + } +} diff --git a/tools/src/lib.rs b/tools/src/lib.rs index 1a93fbd..842ffec 100644 --- a/tools/src/lib.rs +++ b/tools/src/lib.rs @@ -14,3 +14,6 @@ pub use repos::Repos; pub mod recipe_id; pub use recipe_id::RecipeId; pub use recipe_id::RecipeIdParseError; + +pub mod build_plan; +pub use build_plan::BuildPlan; diff --git a/tools/src/repos.rs b/tools/src/repos.rs index 3b34fc9..bc441d9 100644 --- a/tools/src/repos.rs +++ b/tools/src/repos.rs @@ -11,6 +11,8 @@ use crate::recipe_id::RecipeIdParseError; use crate::repo::Repo; +use crate::build_plan::BuildPlan; + #[derive(Debug, Default)] pub struct Repos { repos: std::collections::HashMap, @@ -99,26 +101,28 @@ impl Repos { } } - pub fn compile(&self, target: &str) -> Result<(), RecipeCompileError> { + pub fn compile<'a>(&'a self, target: &'a str) -> Result, RecipeCompileError> { + let mut build_plan = BuildPlan::new(self); let recipe = self.get_recipe(target)?; let puml_filename = format!("{target}.puml"); let mut puml_file = std::fs::File::create(&puml_filename)?; writeln!(puml_file, "@startuml")?; writeln!(puml_file, "object {}", target)?; - self.compile_inner(&mut puml_file, 1, target, recipe, 4)?; + self.compile_inner(&mut build_plan, &mut puml_file, 1, target, recipe, 4)?; writeln!(puml_file, "@enduml")?; Command::new("plantuml") .arg("-v") .arg(&puml_filename) .output() .expect("failed to run `plantuml`"); - Ok(()) + Ok(build_plan) } } impl Repos { fn compile_inner( &self, + build_plan: &mut BuildPlan, puml_file: &mut std::fs::File, quantity: usize, // how many of this thing we're making recipe_name: &str, // the name of the thing we're making FIXME: aka the Item @@ -127,6 +131,24 @@ impl Repos { ) -> Result<(), RecipeCompileError> { for (input_name, input_info) in recipe.inputs.iter() { let input_recipe = self.get_recipe(input_name)?; + + if input_recipe.is_vitamin() { + match build_plan.bom.get_mut(input_name) { + Some(item) => { + item.quantity = item.quantity + &(input_info.quantity * quantity); + } + None => { + build_plan.bom.insert( + input_name.clone(), + crate::build_plan::Item { + name: input_name.clone(), + quantity: input_info.quantity * quantity, + }, + ); + } + } + } + // A Recipe whose only input is Capital is a Vitamin. let cost = match input_recipe.is_vitamin() { true => { @@ -202,6 +224,7 @@ impl Repos { if !input_recipe.is_vitamin() { self.compile_inner( + build_plan, puml_file, (input_info.quantity * quantity).amount as usize, // FIXME: pretty dodgy input_name,