Skip to content

Commit

Permalink
[bndbuild] Add a graphiviz export
Browse files Browse the repository at this point in the history
  • Loading branch information
Krusty/Benediction committed Jul 9, 2024
1 parent 29b2aef commit baf3984
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 22 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cpclib-bndbuild/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ exclude = ["examples", "tests/dummy"]
shlex = "1.3.0"
topologic = "1.1.0"
lazy-regex = "3.1.0"
dot-writer = "0.1.3"

cpclib-common = {workspace=true, features=["cmdline"]}
cpclib-basm = { workspace=true, default-features=false, features=["xferlib"] }
Expand Down
11 changes: 10 additions & 1 deletion cpclib-bndbuild/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashSet;
use std::io::{BufReader, Read};
use std::ops::Deref;
use std::path::Path;

use cpclib_common::itertools::Itertools;
Expand All @@ -21,6 +22,14 @@ pub struct BndBuilder {
inner: BndBuilderInner
}

impl Deref for BndBuilder {
type Target = rules::Rules;

fn deref(&self) -> &Self::Target {
&self.inner.borrow_owner()
}
}

impl BndBuilder {
pub fn add_default_rule<S: AsRef<str>>(
self,
Expand Down Expand Up @@ -63,7 +72,7 @@ impl BndBuilder {
) -> Result<Self, BndBuilderError> {
if let Some(working_directory) = working_directory {
let working_directory = working_directory.as_ref();
println!(
eprintln!(
"> Set working directory to: {}",
working_directory.display()
);
Expand Down
59 changes: 38 additions & 21 deletions cpclib-bndbuild/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ fn inner_main() -> Result<(), BndBuilderError> {
.help("Print version")
.action(ArgAction::SetTrue)
)
.arg(
Arg::new("dot")
.long("dot")
.alias("grapĥviz")
.help("Generate the .dot representation of the selected bndbuild.yml file")
.action(ArgAction::SetTrue)
)
.arg(
Arg::new("file")
.short('f')
Expand All @@ -66,25 +73,29 @@ fn inner_main() -> Result<(), BndBuilderError> {
.long("watch")
.action(ArgAction::SetTrue)
.help("Watch the targets and permanently rebuild them when needed.")
.conflicts_with("dot")
)
.arg(
Arg::new("list")
.short('l')
.long("list")
.action(ArgAction::SetTrue)
.help("List the available targets")
.conflicts_with("dot")
)
.arg(
Arg::new("init")
.long("init")
.action(ArgAction::SetTrue)
.help("Init a new project by creating it")
.conflicts_with("dot")
)
.arg(
Arg::new("add")
.long("add")
.short('a')
.help("Add a new basm target in an existing bndbuild.yml (or create it)")
.conflicts_with("dot")
.action(ArgAction::Set)
)
.arg(
Expand Down Expand Up @@ -282,31 +293,37 @@ fn inner_main() -> Result<(), BndBuilderError> {
.collect::<Vec<&std::path::Path>>()
};

// Execute the targets
let mut first_loop = true;
let watch_requested = matches.get_flag("watch");
loop {
for tgt in targets.iter() {
if first_loop || builder.outdated(tgt).unwrap_or(false) {
builder.execute(tgt).map_err(|e| {
if targets_provided {
e
}
else {
BndBuilderError::DefaultTargetError {
source: Box::new(e)
if matches.get_flag("dot") {
let dot = builder.to_dot();
println!("{dot}")

} else {
// Execute the targets
let mut first_loop = true;
let watch_requested = matches.get_flag("watch");
loop {
for tgt in targets.iter() {
if first_loop || builder.outdated(tgt).unwrap_or(false) {
builder.execute(tgt).map_err(|e| {
if targets_provided {
e
}
else {
BndBuilderError::DefaultTargetError {
source: Box::new(e)
}
}
}
})?;
})?;
}
}
}

if !watch_requested {
break;
}
if !watch_requested {
break;
}

std::thread::sleep(std::time::Duration::from_millis(1000)); // sleep 1s before trying to build
first_loop = false;
std::thread::sleep(std::time::Duration::from_millis(1000)); // sleep 1s before trying to build
first_loop = false;
}
}
}

Expand Down
37 changes: 37 additions & 0 deletions cpclib-bndbuild/src/rules/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::BTreeMap;
use std::fmt::Display;
use std::path::Path;

use dot_writer::{Attributes, DotWriter, Style};
use serde::{self, Deserialize};
use topologic::AcyclicDependencyGraph;

Expand Down Expand Up @@ -109,3 +110,39 @@ impl Rules {
})
}
}



impl Rules {
pub fn to_dot(&self) -> String {
let mut output_bytes = Vec::new();
{
let mut writer = DotWriter::from(&mut output_bytes);
writer.set_pretty_print(true);

let mut digraph = writer.digraph();
digraph
.set_rank_direction(dot_writer::RankDirection::BottomTop)
.node_attributes()
.set_style(Style::Filled)
.set_shape(dot_writer::Shape::Rectangle)
;

for rule in self.rules() {
let deps = rule.dependencies();
let tgts = rule.targets();

for dep in deps {
for tgt in tgts {
digraph.edge(
format!("\"{}\"", dep.display().to_string()),
format!("\"{}\"", tgt.display().to_string()));
}
}

}
}

String::from_utf8_lossy(&output_bytes).into_owned()
}
}

0 comments on commit baf3984

Please sign in to comment.