From 19337f3581dc3430615d6d019b8dc7aeb7c2d1b2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 11 Dec 2020 13:12:58 +0100 Subject: Add "tree-of" subcommand to print dependency tree of a package Signed-off-by: Matthias Beyer --- src/cli.rs | 18 ++++++++++++++++++ src/commands/mod.rs | 3 +++ src/commands/tree_of.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 5 +++++ 4 files changed, 70 insertions(+) create mode 100644 src/commands/tree_of.rs diff --git a/src/cli.rs b/src/cli.rs index d1d8b92..6e5db05 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -621,6 +621,24 @@ pub fn cli<'a>() -> App<'a> { ) ) + .subcommand(App::new("tree-of") + .about("Print the dependency tree of one or multiple packages") + .arg(Arg::new("package_name") + .required(true) + .multiple(false) + .index(1) + .value_name("NAME") + .about("Package name to lint (if not present, every package will be linted") + ) + .arg(Arg::new("package_version") + .required(false) + .multiple(false) + .index(2) + .value_name("VERSION_CONSTRAINT") + .about("A version constraint to search for (optional), E.G. '=1.0.0'") + ) + ) + } fn script_arg_line_numbers<'a>() -> clap::Arg<'a> { diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 2fb124e..f18b9d0 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -28,4 +28,7 @@ pub use source::source; mod versions_of; pub use versions_of::versions_of; +mod tree_of; +pub use tree_of::tree_of; + mod util; diff --git a/src/commands/tree_of.rs b/src/commands/tree_of.rs new file mode 100644 index 0000000..7281349 --- /dev/null +++ b/src/commands/tree_of.rs @@ -0,0 +1,44 @@ +use std::io::Write; + +use anyhow::Result; +use clap::ArgMatches; +use resiter::AndThen; + +use crate::package::PackageName; +use crate::package::PackageVersionConstraint; +use crate::repository::Repository; +use crate::package::Tree; +use crate::util::progress::ProgressBars; + +pub async fn tree_of(matches: &ArgMatches, repo: Repository, progressbars: ProgressBars) -> Result<()> { + let pname = matches.value_of("package_name").map(String::from).map(PackageName::from); + let pvers = matches.value_of("package_version").map(String::from).map(PackageVersionConstraint::new).transpose()?; + + fn print_package_tree(out: &mut dyn Write, indent: usize, tree: Tree) -> Result<()> { + for (pkg, tree) in tree.into_iter() { + writeln!(out, "{:indent$}{name} {version}", "", indent = indent, name = pkg.name(), version = pkg.version())?; + print_package_tree(out, indent + 2, tree)?; + } + Ok(()) + } + + repo.packages() + .filter(|p| pname.as_ref().map(|n| p.name() == n).unwrap_or(true)) + .filter(|p| pvers.as_ref().map(|v| v.matches(p.version())).unwrap_or(true)) + .map(|package| { + let bar_tree_building = progressbars.bar(); + let mut tree = Tree::new(); + let _ = tree.add_package(package.clone(), &repo, bar_tree_building.clone())?; + bar_tree_building.finish_with_message("Finished loading Tree"); + Ok(tree) + }) + .and_then_ok(|tree| { + let stdout = std::io::stdout(); + let mut outlock = stdout.lock(); + + print_package_tree(&mut outlock, 0, tree) + }) + .collect::>() +} + + diff --git a/src/main.rs b/src/main.rs index ca642b8..a896313 100644 --- a/src/main.rs +++ b/src/main.rs @@ -147,6 +147,11 @@ async fn main() -> Result<()> { crate::commands::lint(&repo_path, matches, progressbars, &config, repo).await? } + Some(("tree-of", matches)) => { + let repo = load_repo()?; + crate::commands::tree_of(matches, repo, progressbars).await? + } + Some((other, _)) => return Err(anyhow!("Unknown subcommand: {}", other)), None => return Err(anyhow!("No subcommand")), } -- cgit v1.2.3