start adding build_plan to track the build process for a job
This commit is contained in:
parent
e0e38503f0
commit
233abbe4ff
4 changed files with 61 additions and 4 deletions
|
|
@ -20,6 +20,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
for repo_path in &args.repo {
|
for repo_path in &args.repo {
|
||||||
repos.add_repo(repo_path)?;
|
repos.add_repo(repo_path)?;
|
||||||
}
|
}
|
||||||
repos.compile(&args.target)?;
|
let build_plan = repos.compile(&args.target)?;
|
||||||
|
println!("{build_plan:#?}");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
tools/src/build_plan.rs
Normal file
30
tools/src/build_plan.rs
Normal file
|
|
@ -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<String, Item>,
|
||||||
|
|
||||||
|
pub repos: &'a crate::repos::Repos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BuildPlan<'a> {
|
||||||
|
pub fn new(repos: &'a crate::repos::Repos) -> Self {
|
||||||
|
BuildPlan {
|
||||||
|
bom: std::collections::HashMap::<String, Item>::new(),
|
||||||
|
repos,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,3 +14,6 @@ pub use repos::Repos;
|
||||||
pub mod recipe_id;
|
pub mod recipe_id;
|
||||||
pub use recipe_id::RecipeId;
|
pub use recipe_id::RecipeId;
|
||||||
pub use recipe_id::RecipeIdParseError;
|
pub use recipe_id::RecipeIdParseError;
|
||||||
|
|
||||||
|
pub mod build_plan;
|
||||||
|
pub use build_plan::BuildPlan;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ use crate::recipe_id::RecipeIdParseError;
|
||||||
|
|
||||||
use crate::repo::Repo;
|
use crate::repo::Repo;
|
||||||
|
|
||||||
|
use crate::build_plan::BuildPlan;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Repos {
|
pub struct Repos {
|
||||||
repos: std::collections::HashMap<String, Repo>,
|
repos: std::collections::HashMap<String, Repo>,
|
||||||
|
|
@ -99,26 +101,28 @@ impl Repos {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(&self, target: &str) -> Result<(), RecipeCompileError> {
|
pub fn compile<'a>(&'a self, target: &'a str) -> Result<BuildPlan<'a>, RecipeCompileError> {
|
||||||
|
let mut build_plan = BuildPlan::new(self);
|
||||||
let recipe = self.get_recipe(target)?;
|
let recipe = self.get_recipe(target)?;
|
||||||
let puml_filename = format!("{target}.puml");
|
let puml_filename = format!("{target}.puml");
|
||||||
let mut puml_file = std::fs::File::create(&puml_filename)?;
|
let mut puml_file = std::fs::File::create(&puml_filename)?;
|
||||||
writeln!(puml_file, "@startuml")?;
|
writeln!(puml_file, "@startuml")?;
|
||||||
writeln!(puml_file, "object {}", target)?;
|
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")?;
|
writeln!(puml_file, "@enduml")?;
|
||||||
Command::new("plantuml")
|
Command::new("plantuml")
|
||||||
.arg("-v")
|
.arg("-v")
|
||||||
.arg(&puml_filename)
|
.arg(&puml_filename)
|
||||||
.output()
|
.output()
|
||||||
.expect("failed to run `plantuml`");
|
.expect("failed to run `plantuml`");
|
||||||
Ok(())
|
Ok(build_plan)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Repos {
|
impl Repos {
|
||||||
fn compile_inner(
|
fn compile_inner(
|
||||||
&self,
|
&self,
|
||||||
|
build_plan: &mut BuildPlan,
|
||||||
puml_file: &mut std::fs::File,
|
puml_file: &mut std::fs::File,
|
||||||
quantity: usize, // how many of this thing we're making
|
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
|
recipe_name: &str, // the name of the thing we're making FIXME: aka the Item
|
||||||
|
|
@ -127,6 +131,24 @@ impl Repos {
|
||||||
) -> Result<(), RecipeCompileError> {
|
) -> Result<(), RecipeCompileError> {
|
||||||
for (input_name, input_info) in recipe.inputs.iter() {
|
for (input_name, input_info) in recipe.inputs.iter() {
|
||||||
let input_recipe = self.get_recipe(input_name)?;
|
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.
|
// A Recipe whose only input is Capital is a Vitamin.
|
||||||
let cost = match input_recipe.is_vitamin() {
|
let cost = match input_recipe.is_vitamin() {
|
||||||
true => {
|
true => {
|
||||||
|
|
@ -202,6 +224,7 @@ impl Repos {
|
||||||
|
|
||||||
if !input_recipe.is_vitamin() {
|
if !input_recipe.is_vitamin() {
|
||||||
self.compile_inner(
|
self.compile_inner(
|
||||||
|
build_plan,
|
||||||
puml_file,
|
puml_file,
|
||||||
(input_info.quantity * quantity).amount as usize, // FIXME: pretty dodgy
|
(input_info.quantity * quantity).amount as usize, // FIXME: pretty dodgy
|
||||||
input_name,
|
input_name,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue