mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Auto merge of #9520 - weihanglo:tree-prune, r=ehuss
Add `--prune` option for cargo-tree Part of #8105 Prune the given package from the display of the dependency tree. Also providing a nice suggestion if the package is not within the resolved dependency graph.
This commit is contained in:
commit
aa8b09297b
@ -56,6 +56,11 @@ pub fn cli() -> App {
|
||||
)
|
||||
.short("i"),
|
||||
)
|
||||
.arg(multi_opt(
|
||||
"prune",
|
||||
"SPEC",
|
||||
"Prune the given package from the display of the dependency tree",
|
||||
))
|
||||
.arg(opt("depth", "Maximum display depth of the dependency tree").value_name("DEPTH"))
|
||||
// Deprecated, use --prefix=none instead.
|
||||
.arg(Arg::with_name("no-indent").long("no-indent").hidden(true))
|
||||
@ -152,6 +157,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||
let (edge_kinds, no_proc_macro) = parse_edge_kinds(config, args)?;
|
||||
let graph_features = edge_kinds.contains(&EdgeKind::Feature);
|
||||
|
||||
let pkgs_to_prune = args._values_of("prune");
|
||||
|
||||
let packages = args.packages_from_flags()?;
|
||||
let mut invert = args
|
||||
.values_of("invert")
|
||||
@ -197,6 +204,7 @@ subtree of the package given to -p.\n\
|
||||
target,
|
||||
edge_kinds,
|
||||
invert,
|
||||
pkgs_to_prune,
|
||||
prefix,
|
||||
no_dedupe,
|
||||
duplicates: args.is_present("duplicates"),
|
||||
|
@ -27,6 +27,8 @@ pub struct TreeOptions {
|
||||
/// The dependency kinds to display.
|
||||
pub edge_kinds: HashSet<EdgeKind>,
|
||||
pub invert: Vec<String>,
|
||||
/// The packages to prune from the display of the dependency tree.
|
||||
pub pkgs_to_prune: Vec<String>,
|
||||
/// The style of prefix for each line.
|
||||
pub prefix: Prefix,
|
||||
/// If `true`, duplicates will be repeated.
|
||||
@ -199,7 +201,19 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<()
|
||||
graph.invert();
|
||||
}
|
||||
|
||||
print(ws.config(), opts, root_indexes, &graph)?;
|
||||
// Packages to prune.
|
||||
let pkgs_to_prune = opts
|
||||
.pkgs_to_prune
|
||||
.iter()
|
||||
.map(|p| PackageIdSpec::parse(p))
|
||||
.map(|r| {
|
||||
// Provide a error message if pkgid is not within the resolved
|
||||
// dependencies graph.
|
||||
r.and_then(|spec| spec.query(ws_resolve.targeted_resolve.iter()).and(Ok(spec)))
|
||||
})
|
||||
.collect::<CargoResult<Vec<PackageIdSpec>>>()?;
|
||||
|
||||
print(ws.config(), opts, root_indexes, &pkgs_to_prune, &graph)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -208,6 +222,7 @@ fn print(
|
||||
config: &Config,
|
||||
opts: &TreeOptions,
|
||||
roots: Vec<usize>,
|
||||
pkgs_to_prune: &[PackageIdSpec],
|
||||
graph: &Graph<'_>,
|
||||
) -> CargoResult<()> {
|
||||
let format = Pattern::new(&opts.format)
|
||||
@ -240,6 +255,7 @@ fn print(
|
||||
root_index,
|
||||
&format,
|
||||
symbols,
|
||||
pkgs_to_prune,
|
||||
opts.prefix,
|
||||
opts.no_dedupe,
|
||||
opts.max_display_depth,
|
||||
@ -260,6 +276,7 @@ fn print_node<'a>(
|
||||
node_index: usize,
|
||||
format: &Pattern,
|
||||
symbols: &Symbols,
|
||||
pkgs_to_prune: &[PackageIdSpec],
|
||||
prefix: Prefix,
|
||||
no_dedupe: bool,
|
||||
max_display_depth: u32,
|
||||
@ -319,6 +336,7 @@ fn print_node<'a>(
|
||||
node_index,
|
||||
format,
|
||||
symbols,
|
||||
pkgs_to_prune,
|
||||
prefix,
|
||||
no_dedupe,
|
||||
max_display_depth,
|
||||
@ -339,6 +357,7 @@ fn print_dependencies<'a>(
|
||||
node_index: usize,
|
||||
format: &Pattern,
|
||||
symbols: &Symbols,
|
||||
pkgs_to_prune: &[PackageIdSpec],
|
||||
prefix: Prefix,
|
||||
no_dedupe: bool,
|
||||
max_display_depth: u32,
|
||||
@ -371,6 +390,11 @@ fn print_dependencies<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
// Current level exceeds maximum display depth. Skip.
|
||||
if levels_continue.len() + 1 > max_display_depth as usize {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut it = deps
|
||||
.iter()
|
||||
.filter(|dep| {
|
||||
@ -386,26 +410,34 @@ fn print_dependencies<'a>(
|
||||
true
|
||||
}
|
||||
})
|
||||
.filter(|dep| {
|
||||
// Filter out packages to prune.
|
||||
match graph.node(**dep) {
|
||||
Node::Package { package_id, .. } => {
|
||||
!pkgs_to_prune.iter().any(|spec| spec.matches(*package_id))
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
})
|
||||
.peekable();
|
||||
|
||||
while let Some(dependency) = it.next() {
|
||||
if levels_continue.len() + 1 <= max_display_depth as usize {
|
||||
levels_continue.push(it.peek().is_some());
|
||||
print_node(
|
||||
config,
|
||||
graph,
|
||||
*dependency,
|
||||
format,
|
||||
symbols,
|
||||
prefix,
|
||||
no_dedupe,
|
||||
max_display_depth,
|
||||
no_proc_macro,
|
||||
visited_deps,
|
||||
levels_continue,
|
||||
print_stack,
|
||||
);
|
||||
levels_continue.pop();
|
||||
}
|
||||
levels_continue.push(it.peek().is_some());
|
||||
print_node(
|
||||
config,
|
||||
graph,
|
||||
*dependency,
|
||||
format,
|
||||
symbols,
|
||||
pkgs_to_prune,
|
||||
prefix,
|
||||
no_dedupe,
|
||||
max_display_depth,
|
||||
no_proc_macro,
|
||||
visited_deps,
|
||||
levels_continue,
|
||||
print_stack,
|
||||
);
|
||||
levels_continue.pop();
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,10 @@ flag can be used to display the package's reverse dependencies only with the
|
||||
subtree of the package given to `-p`.
|
||||
{{/option}}
|
||||
|
||||
{{#option "`--prune` _spec_" }}
|
||||
Prune the given package from the display of the dependency tree.
|
||||
{{/option}}
|
||||
|
||||
{{#option "`--depth` _depth_" }}
|
||||
Maximum display depth of the dependency tree. A depth of 1 displays the direct
|
||||
dependencies, for example.
|
||||
|
@ -59,6 +59,9 @@ OPTIONS
|
||||
package's reverse dependencies only with the subtree of the package
|
||||
given to -p.
|
||||
|
||||
--prune spec
|
||||
Prune the given package from the display of the dependency tree.
|
||||
|
||||
--depth depth
|
||||
Maximum display depth of the dependency tree. A depth of 1 displays
|
||||
the direct dependencies, for example.
|
||||
|
@ -71,6 +71,10 @@ flag can be used to display the package's reverse dependencies only with the
|
||||
subtree of the package given to <code>-p</code>.</dd>
|
||||
|
||||
|
||||
<dt class="option-term" id="option-cargo-tree---prune"><a class="option-anchor" href="#option-cargo-tree---prune"></a><code>--prune</code> <em>spec</em></dt>
|
||||
<dd class="option-desc">Prune the given package from the display of the dependency tree.</dd>
|
||||
|
||||
|
||||
<dt class="option-term" id="option-cargo-tree---depth"><a class="option-anchor" href="#option-cargo-tree---depth"></a><code>--depth</code> <em>depth</em></dt>
|
||||
<dd class="option-desc">Maximum display depth of the dependency tree. A depth of 1 displays the direct
|
||||
dependencies, for example.</dd>
|
||||
|
@ -69,6 +69,11 @@ flag can be used to display the package's reverse dependencies only with the
|
||||
subtree of the package given to \fB\-p\fR\&.
|
||||
.RE
|
||||
.sp
|
||||
\fB\-\-prune\fR \fIspec\fR
|
||||
.RS 4
|
||||
Prune the given package from the display of the dependency tree.
|
||||
.RE
|
||||
.sp
|
||||
\fB\-\-depth\fR \fIdepth\fR
|
||||
.RS 4
|
||||
Maximum display depth of the dependency tree. A depth of 1 displays the direct
|
||||
|
@ -1720,3 +1720,81 @@ c v1.0.0
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn prune() {
|
||||
let p = make_simple_proj();
|
||||
|
||||
p.cargo("tree --prune c")
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.1.0 ([..]/foo)
|
||||
└── a v1.0.0
|
||||
└── b v1.0.0
|
||||
[build-dependencies]
|
||||
└── bdep v1.0.0
|
||||
└── b v1.0.0 (*)
|
||||
[dev-dependencies]
|
||||
└── devdep v1.0.0
|
||||
└── b v1.0.0 (*)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// multiple prune
|
||||
p.cargo("tree --prune c --prune bdep")
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.1.0 ([..]/foo)
|
||||
└── a v1.0.0
|
||||
└── b v1.0.0
|
||||
[build-dependencies]
|
||||
[dev-dependencies]
|
||||
└── devdep v1.0.0
|
||||
└── b v1.0.0 (*)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// with edge-kinds
|
||||
p.cargo("tree --prune c -e normal")
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.1.0 ([..]/foo)
|
||||
└── a v1.0.0
|
||||
└── b v1.0.0
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// pruning self does not works
|
||||
p.cargo("tree --prune foo")
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.1.0 ([..]/foo)
|
||||
├── a v1.0.0
|
||||
│ └── b v1.0.0
|
||||
│ └── c v1.0.0
|
||||
└── c v1.0.0
|
||||
[build-dependencies]
|
||||
└── bdep v1.0.0
|
||||
└── b v1.0.0 (*)
|
||||
[dev-dependencies]
|
||||
└── devdep v1.0.0
|
||||
└── b v1.0.0 (*)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// dep not exist
|
||||
p.cargo("tree --prune no-dep")
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] package ID specification `no-dep` did not match any packages
|
||||
|
||||
<tab>Did you mean `bdep`?
|
||||
",
|
||||
)
|
||||
.with_status(101)
|
||||
.run();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user