diff options
-rw-r--r-- | src/cli.rs | 18 | ||||
-rw-r--r-- | src/commands/mod.rs | 3 | ||||
-rw-r--r-- | src/commands/tree_of.rs | 44 | ||||
-rw-r--r-- | src/main.rs | 5 |
4 files changed, 70 insertions, 0 deletions
@@ -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::<Result<()>>() +} + + 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")), } |