Skip to content

Commit

Permalink
Add serial-buildorder argument to the build-tree
Browse files Browse the repository at this point in the history
- Introduced a new command-line argument `--serial-buildorder` that
  outputs the tree-of package in a serial build order.
- The `--serial-buildorder` argument conflicts with the existing `--dot`
  argument for now. Showing the serial build order in the dot format
  would not bring any benefits.
- Ensured cyclic dependency detection and error handling during
  topological sorting.

Fixes science-computing#379

Signed-off-by: Nico Steinle <[email protected]>
  • Loading branch information
ammernico committed Sep 18, 2024
1 parent cc35c20 commit a66313a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,24 @@ pub fn cli() -> Command {
.required(false)
.long("dot")
.help("Output the dependency DAG in the Graphviz DOT format")
.conflicts_with("serial-buildorder")
)
.arg(Arg::new("serial-buildorder")
.action(ArgAction::SetTrue)
.required(false)
.long("serial-buildorder")
.help("Output the dependencies in a serial build order (flattened tree)")
.long_help(indoc::indoc!(r#"
A serial build order ensures that dependencies are built one at a time
in a specific sequence. This approach follows a reversed topological ordering,
where dependencies (or children) are listed and built first. Each dependency
must be fully built before the next one begins, ensuring all components are
available when needed.
Keep in mind that the actual build order remains parallel, this serialized
output is mainly useful for debugging purposes.
"#))
.conflicts_with("dot")
)
)

Expand Down
15 changes: 15 additions & 0 deletions src/commands/tree_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ pub async fn tree_of(matches: &ArgMatches, repo: Repository, config: &Configurat

let dot = matches.get_flag("dot");

let serial_buildorder = matches.get_flag("serial-buildorder");

repo.packages()
.filter(|p| pname.as_ref().map(|n| p.name() == n).unwrap_or(true))
.filter(|p| {
Expand Down Expand Up @@ -92,6 +94,19 @@ pub async fn tree_of(matches: &ArgMatches, repo: Repository, config: &Configurat
);

println!("{:?}", dot);
Ok(())
} else if serial_buildorder {
let petgraph: DiGraph<Package, DependencyType> = (*dag.dag()).clone().into();

let topo_sorted = petgraph::algo::toposort(&petgraph, None)
.map_err(|_| Error::msg("Cyclic dependency found!"))?;

for node in topo_sorted.iter().rev() {
let package = petgraph.node_weight(*node).unwrap();
println!("{}", package.clone().display_name_version());
}
println!();

Ok(())
} else {
let stdout = std::io::stdout();
Expand Down

0 comments on commit a66313a

Please sign in to comment.