cargo/tests/testsuite/tree.rs

2202 lines
46 KiB
Rust
Raw Normal View History

2020-03-19 17:51:25 +00:00
//! Tests for the `cargo tree` command.
use super::features2::switch_to_resolver_2;
use cargo_test_support::cross_compile::{self, alternate};
2020-03-19 17:51:25 +00:00
use cargo_test_support::registry::{Dependency, Package};
use cargo_test_support::{basic_manifest, git, project, rustc_host, Project};
fn make_simple_proj() -> Project {
Package::new("c", "1.0.0").publish();
Package::new("b", "1.0.0").dep("c", "1.0").publish();
Package::new("a", "1.0.0").dep("b", "1.0").publish();
Package::new("bdep", "1.0.0").dep("b", "1.0").publish();
Package::new("devdep", "1.0.0").dep("b", "1.0.0").publish();
project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
a = "1.0"
c = "1.0"
[build-dependencies]
bdep = "1.0"
[dev-dependencies]
devdep = "1.0"
"#,
)
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build()
}
#[cargo_test]
fn simple() {
// A simple test with a few different dependencies.
let p = make_simple_proj();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
a v1.0.0
b v1.0.0
c v1.0.0
c v1.0.0
2020-03-19 17:51:25 +00:00
[build-dependencies]
bdep v1.0.0
b v1.0.0 (*)
[dev-dependencies]
devdep v1.0.0
b v1.0.0 (*)
",
)
.run();
p.cargo("tree -p bdep")
.with_stdout(
"\
bdep v1.0.0
b v1.0.0
c v1.0.0
",
)
.run();
}
#[cargo_test]
fn virtual_workspace() {
// Multiple packages in a virtual workspace.
Package::new("somedep", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["a", "baz", "c"]
2020-03-19 17:51:25 +00:00
"#,
)
.file("a/Cargo.toml", &basic_manifest("a", "1.0.0"))
.file("a/src/lib.rs", "")
.file(
"baz/Cargo.toml",
2020-03-19 17:51:25 +00:00
r#"
[package]
name = "baz"
2020-03-19 17:51:25 +00:00
version = "0.1.0"
[dependencies]
c = { path = "../c" }
somedep = "1.0"
"#,
)
.file("baz/src/lib.rs", "")
2020-03-19 17:51:25 +00:00
.file("c/Cargo.toml", &basic_manifest("c", "1.0.0"))
.file("c/src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
a v1.0.0 ([..]/foo/a)
baz v0.1.0 ([..]/foo/baz)
2020-03-19 17:51:25 +00:00
c v1.0.0 ([..]/foo/c)
somedep v1.0.0
c v1.0.0 ([..]/foo/c)
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -p a").with_stdout("a v1.0.0 [..]").run();
p.cargo("tree")
.cwd("baz")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
baz v0.1.0 ([..]/foo/baz)
c v1.0.0 ([..]/foo/c)
somedep v1.0.0
",
)
.run();
// exclude baz
p.cargo("tree --workspace --exclude baz")
.with_stdout(
"\
a v1.0.0 ([..]/foo/a)
c v1.0.0 ([..]/foo/c)
",
)
.run();
// exclude glob '*z'
p.cargo("tree --workspace --exclude '*z'")
.with_stdout(
"\
a v1.0.0 ([..]/foo/a)
c v1.0.0 ([..]/foo/c)
",
)
.run();
// include glob '*z'
p.cargo("tree -p '*z'")
.with_stdout(
"\
baz v0.1.0 ([..]/foo/baz)
2020-03-19 17:51:25 +00:00
c v1.0.0 ([..]/foo/c)
somedep v1.0.0
",
)
.run();
}
#[cargo_test]
fn dedupe_edges() {
// Works around https://github.com/rust-lang/cargo/issues/7985
Package::new("bitflags", "1.0.0").publish();
Package::new("manyfeat", "1.0.0")
.feature("f1", &[])
.feature("f2", &[])
.feature("f3", &[])
.dep("bitflags", "1.0")
.publish();
Package::new("a", "1.0.0")
.feature_dep("manyfeat", "1.0", &["f1"])
.publish();
Package::new("b", "1.0.0")
.feature_dep("manyfeat", "1.0", &["f2"])
.publish();
Package::new("c", "1.0.0")
.feature_dep("manyfeat", "1.0", &["f3"])
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
a = "1.0"
b = "1.0"
c = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
a v1.0.0
manyfeat v1.0.0
bitflags v1.0.0
b v1.0.0
manyfeat v1.0.0 (*)
c v1.0.0
manyfeat v1.0.0 (*)
",
)
.run();
}
#[cargo_test]
fn renamed_deps() {
// Handles renamed dependencies.
Package::new("one", "1.0.0").publish();
Package::new("two", "1.0.0").publish();
Package::new("bar", "1.0.0").dep("one", "1.0").publish();
Package::new("bar", "2.0.0").dep("two", "1.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[dependencies]
bar1 = {version = "1.0", package="bar"}
bar2 = {version = "2.0", package="bar"}
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v1.0.0 ([..]/foo)
bar v1.0.0
one v1.0.0
bar v2.0.0
two v1.0.0
",
)
.run();
}
#[cargo_test]
fn source_kinds() {
// Handles git and path sources.
Package::new("regdep", "1.0.0").publish();
let git_project = git::new("gitdep", |p| {
p.file("Cargo.toml", &basic_manifest("gitdep", "1.0.0"))
.file("src/lib.rs", "")
});
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
[dependencies]
regdep = "1.0"
pathdep = {{ path = "pathdep" }}
gitdep = {{ git = "{}" }}
"#,
2020-03-19 17:51:25 +00:00
git_project.url()
),
)
.file("src/lib.rs", "")
.file("pathdep/Cargo.toml", &basic_manifest("pathdep", "1.0.0"))
.file("pathdep/src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
gitdep v1.0.0 (file://[..]/gitdep#[..])
pathdep v1.0.0 ([..]/foo/pathdep)
regdep v1.0.0
",
)
.run();
}
#[cargo_test]
fn features() {
// Exercises a variety of feature behaviors.
Package::new("optdep_default", "1.0.0").publish();
Package::new("optdep", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "a"
version = "0.1.0"
[dependencies]
optdep_default = { version = "1.0", optional = true }
optdep = { version = "1.0", optional = true }
[features]
default = ["optdep_default"]
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
a v0.1.0 ([..]/foo)
optdep_default v1.0.0
",
)
.run();
p.cargo("tree --no-default-features")
.with_stdout(
"\
a v0.1.0 ([..]/foo)
",
)
.run();
p.cargo("tree --all-features")
.with_stdout(
"\
a v0.1.0 ([..]/foo)
optdep v1.0.0
optdep_default v1.0.0
",
)
.run();
p.cargo("tree --features optdep")
.with_stdout(
"\
a v0.1.0 ([..]/foo)
optdep v1.0.0
optdep_default v1.0.0
",
)
.run();
}
#[cargo_test]
fn filters_target() {
// --target flag
if cross_compile::disabled() {
return;
}
2020-03-19 17:51:25 +00:00
Package::new("targetdep", "1.0.0").publish();
Package::new("hostdep", "1.0.0").publish();
Package::new("devdep", "1.0.0").publish();
Package::new("build_target_dep", "1.0.0").publish();
Package::new("build_host_dep", "1.0.0")
.target_dep("targetdep", "1.0", alternate())
.target_dep("hostdep", "1.0", rustc_host())
2020-03-19 17:51:25 +00:00
.publish();
Package::new("pm_target", "1.0.0")
.proc_macro(true)
.publish();
Package::new("pm_host", "1.0.0").proc_macro(true).publish();
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
2020-03-19 17:51:25 +00:00
2020-09-27 00:59:58 +00:00
[target.'{alt}'.dependencies]
targetdep = "1.0"
pm_target = "1.0"
2020-03-19 17:51:25 +00:00
2020-09-27 00:59:58 +00:00
[target.'{host}'.dependencies]
hostdep = "1.0"
pm_host = "1.0"
2020-03-19 17:51:25 +00:00
2020-09-27 00:59:58 +00:00
[target.'{alt}'.dev-dependencies]
devdep = "1.0"
2020-03-19 17:51:25 +00:00
2020-09-27 00:59:58 +00:00
[target.'{alt}'.build-dependencies]
build_target_dep = "1.0"
2020-03-19 17:51:25 +00:00
2020-09-27 00:59:58 +00:00
[target.'{host}'.build-dependencies]
build_host_dep = "1.0"
"#,
2020-03-19 17:51:25 +00:00
alt = alternate(),
host = rustc_host()
),
)
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
hostdep v1.0.0
2020-10-10 08:38:52 +00:00
pm_host v1.0.0 (proc-macro)
2020-03-19 17:51:25 +00:00
[build-dependencies]
build_host_dep v1.0.0
hostdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree --target")
.arg(alternate())
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
2020-10-10 08:38:52 +00:00
pm_target v1.0.0 (proc-macro)
2020-03-19 17:51:25 +00:00
targetdep v1.0.0
[build-dependencies]
build_host_dep v1.0.0
hostdep v1.0.0
[dev-dependencies]
devdep v1.0.0
",
)
.run();
p.cargo("tree --target")
.arg(rustc_host())
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
hostdep v1.0.0
2020-10-10 08:38:52 +00:00
pm_host v1.0.0 (proc-macro)
2020-03-19 17:51:25 +00:00
[build-dependencies]
build_host_dep v1.0.0
hostdep v1.0.0
",
)
.run();
p.cargo("tree --target=all")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
hostdep v1.0.0
2020-10-10 08:38:52 +00:00
pm_host v1.0.0 (proc-macro)
pm_target v1.0.0 (proc-macro)
2020-03-19 17:51:25 +00:00
targetdep v1.0.0
[build-dependencies]
build_host_dep v1.0.0
hostdep v1.0.0
targetdep v1.0.0
2020-03-19 17:51:25 +00:00
build_target_dep v1.0.0
[dev-dependencies]
devdep v1.0.0
",
)
.run();
// no-proc-macro
p.cargo("tree --target=all -e no-proc-macro")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
hostdep v1.0.0
targetdep v1.0.0
[build-dependencies]
build_host_dep v1.0.0
hostdep v1.0.0
targetdep v1.0.0
build_target_dep v1.0.0
[dev-dependencies]
devdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn no_selected_target_dependency() {
// --target flag
if cross_compile::disabled() {
return;
}
Package::new("targetdep", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.1.0"
[target.'{alt}'.dependencies]
targetdep = "1.0"
"#,
alt = alternate(),
),
)
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
",
)
.run();
p.cargo("tree -i targetdep")
.with_stderr(
"\
[WARNING] nothing to print.
To find dependencies that require specific target platforms, \
try to use option `--target all` first, and then narrow your search scope accordingly.
",
)
.run();
p.cargo("tree -i targetdep --target all")
.with_stdout(
"\
targetdep v1.0.0
foo v0.1.0 ([..]/foo)
",
)
.run();
}
2020-03-19 17:51:25 +00:00
#[cargo_test]
fn dep_kinds() {
Package::new("inner-devdep", "1.0.0").publish();
Package::new("inner-builddep", "1.0.0").publish();
Package::new("inner-normal", "1.0.0").publish();
Package::new("inner-pm", "1.0.0").proc_macro(true).publish();
Package::new("inner-buildpm", "1.0.0")
.proc_macro(true)
.publish();
Package::new("normaldep", "1.0.0")
.dep("inner-normal", "1.0")
.dev_dep("inner-devdep", "1.0")
.build_dep("inner-builddep", "1.0")
.publish();
Package::new("devdep", "1.0.0")
.dep("inner-normal", "1.0")
.dep("inner-pm", "1.0")
.dev_dep("inner-devdep", "1.0")
.build_dep("inner-builddep", "1.0")
.build_dep("inner-buildpm", "1.0")
.publish();
Package::new("builddep", "1.0.0")
.dep("inner-normal", "1.0")
.dev_dep("inner-devdep", "1.0")
.build_dep("inner-builddep", "1.0")
.publish();
2020-03-19 17:51:25 +00:00
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
normaldep = "1.0"
2020-03-19 17:51:25 +00:00
[dev-dependencies]
devdep = "1.0"
[build-dependencies]
builddep = "1.0"
2020-03-19 17:51:25 +00:00
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
normaldep v1.0.0
inner-normal v1.0.0
[build-dependencies]
inner-builddep v1.0.0
[build-dependencies]
builddep v1.0.0
inner-normal v1.0.0
[build-dependencies]
inner-builddep v1.0.0
2020-03-19 17:51:25 +00:00
[dev-dependencies]
devdep v1.0.0
inner-normal v1.0.0
inner-pm v1.0.0 (proc-macro)
[build-dependencies]
inner-builddep v1.0.0
inner-buildpm v1.0.0 (proc-macro)
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -e no-dev")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
normaldep v1.0.0
inner-normal v1.0.0
[build-dependencies]
inner-builddep v1.0.0
[build-dependencies]
builddep v1.0.0
inner-normal v1.0.0
[build-dependencies]
inner-builddep v1.0.0
",
)
.run();
p.cargo("tree -e normal")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
normaldep v1.0.0
inner-normal v1.0.0
",
)
.run();
p.cargo("tree -e dev,build")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
[build-dependencies]
builddep v1.0.0
[build-dependencies]
inner-builddep v1.0.0
[dev-dependencies]
devdep v1.0.0
[build-dependencies]
inner-builddep v1.0.0
inner-buildpm v1.0.0 (proc-macro)
",
)
.run();
p.cargo("tree -e dev,build,no-proc-macro")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
[build-dependencies]
builddep v1.0.0
[build-dependencies]
inner-builddep v1.0.0
[dev-dependencies]
devdep v1.0.0
[build-dependencies]
inner-builddep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn cyclic_dev_dep() {
// Cyclical dev-dependency and inverse flag.
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dev-dependencies]
dev-dep = { path = "dev-dep" }
"#,
)
.file("src/lib.rs", "")
.file(
"dev-dep/Cargo.toml",
r#"
[package]
name = "dev-dep"
version = "0.1.0"
[dependencies]
foo = { path=".." }
"#,
)
.file("dev-dep/src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
[dev-dependencies]
dev-dep v0.1.0 ([..]/foo/dev-dep)
foo v0.1.0 ([..]/foo) (*)
",
)
.run();
p.cargo("tree --invert foo")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
dev-dep v0.1.0 ([..]/foo/dev-dep)
[dev-dependencies]
foo v0.1.0 ([..]/foo) (*)
",
)
.run();
}
#[cargo_test]
fn invert() {
Package::new("b1", "1.0.0").dep("c", "1.0").publish();
Package::new("b2", "1.0.0").dep("d", "1.0").publish();
Package::new("c", "1.0.0").publish();
Package::new("d", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
b1 = "1.0"
b2 = "1.0"
c = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
b1 v1.0.0
c v1.0.0
b2 v1.0.0
d v1.0.0
c v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree --invert c")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
c v1.0.0
b1 v1.0.0
foo v0.1.0 ([..]/foo)
foo v0.1.0 ([..]/foo)
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn invert_with_build_dep() {
// -i for a common dependency between normal and build deps.
2020-03-19 17:51:25 +00:00
Package::new("common", "1.0.0").publish();
Package::new("bdep", "1.0.0").dep("common", "1.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
common = "1.0"
[build-dependencies]
bdep = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
common v1.0.0
[build-dependencies]
bdep v1.0.0
common v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -i common")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
common v1.0.0
bdep v1.0.0
[build-dependencies]
foo v0.1.0 ([..]/foo)
foo v0.1.0 ([..]/foo)
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn no_indent() {
let p = make_simple_proj();
p.cargo("tree --prefix=none")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
a v1.0.0
b v1.0.0
c v1.0.0
c v1.0.0
2020-03-19 17:51:25 +00:00
bdep v1.0.0
b v1.0.0 (*)
devdep v1.0.0
b v1.0.0 (*)
",
)
.run();
}
#[cargo_test]
fn prefix_depth() {
let p = make_simple_proj();
p.cargo("tree --prefix=depth")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
0foo v0.1.0 ([..]/foo)
1a v1.0.0
2b v1.0.0
3c v1.0.0
1c v1.0.0
2020-03-19 17:51:25 +00:00
1bdep v1.0.0
2b v1.0.0 (*)
1devdep v1.0.0
2b v1.0.0 (*)
",
)
.run();
}
#[cargo_test]
fn no_dedupe() {
let p = make_simple_proj();
p.cargo("tree --no-dedupe")
.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
c v1.0.0
[dev-dependencies]
devdep v1.0.0
b v1.0.0
c v1.0.0
",
)
.run();
}
#[cargo_test]
fn no_dedupe_cycle() {
// --no-dedupe with a dependency cycle
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dev-dependencies]
bar = {path = "bar"}
"#,
)
.file("src/lib.rs", "")
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "0.1.0"
[dependencies]
foo = {path=".."}
"#,
)
.file("bar/src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
[dev-dependencies]
bar v0.1.0 ([..]/foo/bar)
foo v0.1.0 ([..]/foo) (*)
",
)
.run();
p.cargo("tree --no-dedupe")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
[dev-dependencies]
bar v0.1.0 ([..]/foo/bar)
foo v0.1.0 ([..]/foo) (*)
",
)
.run();
}
#[cargo_test]
fn duplicates() {
Package::new("dog", "1.0.0").publish();
Package::new("dog", "2.0.0").publish();
Package::new("cat", "1.0.0").publish();
Package::new("cat", "2.0.0").publish();
Package::new("dep", "1.0.0")
.dep("dog", "1.0")
.dep("cat", "1.0")
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["a", "b"]
"#,
)
.file(
"a/Cargo.toml",
r#"
[package]
name = "a"
version = "0.1.0"
[dependencies]
dog1 = { version = "1.0", package = "dog" }
dog2 = { version = "2.0", package = "dog" }
"#,
)
.file("a/src/lib.rs", "")
.file(
"b/Cargo.toml",
r#"
[package]
name = "b"
version = "0.1.0"
[dependencies]
dep = "1.0"
cat = "2.0"
"#,
)
.file("b/src/lib.rs", "")
.build();
p.cargo("tree -p a")
.with_stdout(
"\
a v0.1.0 ([..]/foo/a)
dog v1.0.0
dog v2.0.0
",
)
.run();
p.cargo("tree -p b")
.with_stdout(
"\
b v0.1.0 ([..]/foo/b)
cat v2.0.0
dep v1.0.0
cat v1.0.0
dog v1.0.0
",
)
.run();
p.cargo("tree -p a -d")
.with_stdout(
"\
dog v1.0.0
a v0.1.0 ([..]/foo/a)
dog v2.0.0
a v0.1.0 ([..]/foo/a)
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -p b -d")
.with_stdout(
"\
cat v1.0.0
dep v1.0.0
b v0.1.0 ([..]/foo/b)
cat v2.0.0
b v0.1.0 ([..]/foo/b)
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn duplicates_with_target() {
// --target flag
if cross_compile::disabled() {
return;
}
Package::new("a", "1.0.0").publish();
Package::new("dog", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
a = "1.0"
dog = "1.0"
[build-dependencies]
a = "1.0"
dog = "1.0"
"#,
)
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build();
p.cargo("tree -d").with_stdout("").run();
p.cargo("tree -d --target")
.arg(alternate())
.with_stdout("")
.run();
p.cargo("tree -d --target")
.arg(rustc_host())
.with_stdout("")
.run();
p.cargo("tree -d --target=all").with_stdout("").run();
}
#[cargo_test]
fn duplicates_with_proc_macro() {
Package::new("dupe-dep", "1.0.0").publish();
Package::new("dupe-dep", "2.0.0").publish();
Package::new("proc", "1.0.0")
.proc_macro(true)
.dep("dupe-dep", "1.0")
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
proc = "1.0"
dupe-dep = "2.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
dupe-dep v2.0.0
proc v1.0.0 (proc-macro)
dupe-dep v1.0.0
",
)
.run();
p.cargo("tree --duplicates")
.with_stdout(
"\
dupe-dep v1.0.0
proc v1.0.0 (proc-macro)
foo v0.1.0 ([..]/foo)
dupe-dep v2.0.0
foo v0.1.0 ([..]/foo)
",
)
.run();
p.cargo("tree --duplicates --edges no-proc-macro")
.with_stdout("")
.run();
}
2020-03-19 17:51:25 +00:00
#[cargo_test]
fn charset() {
let p = make_simple_proj();
p.cargo("tree --charset ascii")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
|-- a v1.0.0
| `-- b v1.0.0
| `-- c v1.0.0
`-- c v1.0.0
2020-03-19 17:51:25 +00:00
[build-dependencies]
`-- bdep v1.0.0
`-- b v1.0.0 (*)
[dev-dependencies]
`-- devdep v1.0.0
`-- b v1.0.0 (*)
",
)
.run();
}
#[cargo_test]
fn format() {
Package::new("dep", "1.0.0").publish();
Package::new("other-dep", "1.0.0").publish();
2021-07-08 22:59:07 +00:00
Package::new("dep_that_is_awesome", "1.0.0")
.file(
"Cargo.toml",
r#"
[package]
name = "dep_that_is_awesome"
version = "1.0.0"
[lib]
name = "awesome_dep"
"#,
)
.file("src/lib.rs", "pub struct Straw;")
.publish();
2020-03-19 17:51:25 +00:00
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
license = "MIT"
repository = "https://github.com/rust-lang/cargo"
[dependencies]
dep = {version="1.0", optional=true}
other-dep = {version="1.0", optional=true}
2021-07-08 22:59:07 +00:00
dep_that_is_awesome = {version="1.0", optional=true}
2020-03-19 17:51:25 +00:00
2020-03-19 17:51:25 +00:00
[features]
default = ["foo"]
foo = ["bar"]
bar = []
"#,
)
.file("src/main.rs", "")
2020-03-19 17:51:25 +00:00
.build();
p.cargo("tree --format <<<{p}>>>")
2021-07-08 22:59:07 +00:00
.with_stdout("<<<foo v0.1.0 ([..]/foo)>>>")
2020-03-19 17:51:25 +00:00
.run();
p.cargo("tree --format {}")
.with_stderr(
"\
[ERROR] tree format `{}` not valid
Caused by:
unsupported pattern ``
",
)
.with_status(101)
.run();
2020-04-02 18:31:39 +00:00
p.cargo("tree --format {p}-{{hello}}")
2021-07-08 22:59:07 +00:00
.with_stdout("foo v0.1.0 ([..]/foo)-{hello}")
2020-04-02 18:31:39 +00:00
.run();
2020-03-19 17:51:25 +00:00
p.cargo("tree --format")
.arg("{p} {l} {r}")
2021-07-08 22:59:07 +00:00
.with_stdout("foo v0.1.0 ([..]/foo) MIT https://github.com/rust-lang/cargo")
2020-03-19 17:51:25 +00:00
.run();
p.cargo("tree --format")
.arg("{p} {f}")
2021-07-08 22:59:07 +00:00
.with_stdout("foo v0.1.0 ([..]/foo) bar,default,foo")
2020-03-19 17:51:25 +00:00
.run();
p.cargo("tree --all-features --format")
.arg("{p} [{f}]")
.with_stdout(
"\
foo v0.1.0 ([..]/foo) [bar,default,dep,dep_that_is_awesome,foo,other-dep]
dep v1.0.0 []
dep_that_is_awesome v1.0.0 []
other-dep v1.0.0 []
2020-03-19 17:51:25 +00:00
",
)
.run();
2021-07-08 22:59:07 +00:00
p.cargo("tree")
.arg("--features=other-dep,dep_that_is_awesome")
2021-07-08 22:59:07 +00:00
.arg("--format={lib}")
.with_stdout(
"
awesome_dep
other_dep
2021-07-08 22:59:07 +00:00
",
)
.run();
2020-03-19 17:51:25 +00:00
}
#[cargo_test]
fn dev_dep_feature() {
// New feature resolver with optional dep
2020-03-19 17:51:25 +00:00
Package::new("optdep", "1.0.0").publish();
Package::new("bar", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dev-dependencies]
bar = { version = "1.0", features = ["optdep"] }
[dependencies]
bar = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
// Old behavior.
2020-03-19 17:51:25 +00:00
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
bar v1.0.0
optdep v1.0.0
[dev-dependencies]
bar v1.0.0 (*)
",
)
.run();
p.cargo("tree -e normal")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
bar v1.0.0
optdep v1.0.0
",
)
.run();
// New behavior.
switch_to_resolver_2(&p);
p.cargo("tree")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
bar v1.0.0
optdep v1.0.0
[dev-dependencies]
bar v1.0.0 (*)
",
)
.run();
p.cargo("tree -e normal")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
bar v1.0.0
",
)
.run();
}
#[cargo_test]
fn host_dep_feature() {
// New feature resolver with optional build dep
2020-03-19 17:51:25 +00:00
Package::new("optdep", "1.0.0").publish();
Package::new("bar", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[build-dependencies]
bar = { version = "1.0", features = ["optdep"] }
[dependencies]
bar = "1.0"
"#,
)
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build();
// Old behavior
2020-03-19 17:51:25 +00:00
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
bar v1.0.0
optdep v1.0.0
[build-dependencies]
bar v1.0.0 (*)
",
)
.run();
// -p
p.cargo("tree -p bar")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
bar v1.0.0
optdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
// invert
p.cargo("tree -i optdep")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
optdep v1.0.0
bar v1.0.0
foo v0.1.0 ([..]/foo)
[build-dependencies]
foo v0.1.0 ([..]/foo)
2020-03-19 17:51:25 +00:00
",
)
.run();
// New behavior.
switch_to_resolver_2(&p);
p.cargo("tree")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
bar v1.0.0
[build-dependencies]
bar v1.0.0
optdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -p bar")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
bar v1.0.0
bar v1.0.0
optdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -i optdep")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
optdep v1.0.0
bar v1.0.0
[build-dependencies]
foo v0.1.0 ([..]/foo)
",
)
.run();
// Check that -d handles duplicates with features.
p.cargo("tree -d")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
bar v1.0.0
foo v0.1.0 ([..]/foo)
bar v1.0.0
[build-dependencies]
foo v0.1.0 ([..]/foo)
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn proc_macro_features() {
// New feature resolver with a proc-macro
2020-03-19 17:51:25 +00:00
Package::new("optdep", "1.0.0").publish();
Package::new("somedep", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
.publish();
Package::new("pm", "1.0.0")
.proc_macro(true)
.feature_dep("somedep", "1.0", &["optdep"])
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
pm = "1.0"
somedep = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
// Old behavior
2020-03-19 17:51:25 +00:00
p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
2020-10-10 08:38:52 +00:00
pm v1.0.0 (proc-macro)
2020-03-19 17:51:25 +00:00
somedep v1.0.0
optdep v1.0.0
somedep v1.0.0 (*)
",
)
.run();
// Old behavior + no-proc-macro
p.cargo("tree -e no-proc-macro")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
somedep v1.0.0
optdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
// -p
p.cargo("tree -p somedep")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
somedep v1.0.0
optdep v1.0.0
",
)
.run();
// -p -e no-proc-macro
p.cargo("tree -p somedep -e no-proc-macro")
.with_stdout(
"\
somedep v1.0.0
optdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
// invert
p.cargo("tree -i somedep")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
somedep v1.0.0
foo v0.1.0 ([..]/foo)
pm v1.0.0 (proc-macro)
foo v0.1.0 ([..]/foo)
",
)
.run();
// invert + no-proc-macro
p.cargo("tree -i somedep -e no-proc-macro")
.with_stdout(
"\
somedep v1.0.0
foo v0.1.0 ([..]/foo)
2020-03-19 17:51:25 +00:00
",
)
.run();
// New behavior.
switch_to_resolver_2(&p);
// Note the missing (*)
p.cargo("tree")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
pm v1.0.0 (proc-macro)
somedep v1.0.0
optdep v1.0.0
somedep v1.0.0
",
)
.run();
p.cargo("tree -e no-proc-macro")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
somedep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -p somedep")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
somedep v1.0.0
somedep v1.0.0
optdep v1.0.0
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -i somedep")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
somedep v1.0.0
foo v0.1.0 ([..]/foo)
somedep v1.0.0
2020-10-10 08:38:52 +00:00
pm v1.0.0 (proc-macro)
foo v0.1.0 ([..]/foo)
",
)
.run();
p.cargo("tree -i somedep -e no-proc-macro")
.with_stdout(
"\
somedep v1.0.0
foo v0.1.0 ([..]/foo)
2020-03-19 17:51:25 +00:00
",
)
.run();
}
#[cargo_test]
fn itarget_opt_dep() {
// New feature resolver with optional target dep
2020-03-19 17:51:25 +00:00
Package::new("optdep", "1.0.0").publish();
Package::new("common", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[dependencies]
common = "1.0"
[target.'cfg(whatever)'.dependencies]
common = { version = "1.0", features = ["optdep"] }
"#,
)
.file("src/lib.rs", "")
.build();
// Old behavior
2020-03-19 17:51:25 +00:00
p.cargo("tree")
.with_stdout(
"\
foo v1.0.0 ([..]/foo)
common v1.0.0
optdep v1.0.0
",
)
.run();
// New behavior.
switch_to_resolver_2(&p);
p.cargo("tree")
2020-03-19 17:51:25 +00:00
.with_stdout(
"\
foo v1.0.0 ([..]/foo)
common v1.0.0
",
)
.run();
}
#[cargo_test]
fn ambiguous_name() {
// -p that is ambiguous.
Package::new("dep", "1.0.0").publish();
Package::new("dep", "2.0.0").publish();
Package::new("bar", "1.0.0").dep("dep", "2.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
dep = "1.0"
bar = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree -p dep")
.with_stderr_contains(
"\
error: There are multiple `dep` packages in your project, and the specification `dep` is ambiguous.
Please re-run this command with one of the following specifications:
dep@1.0.0
dep@2.0.0
2020-03-19 17:51:25 +00:00
",
)
.with_status(101)
.run();
}
#[cargo_test]
fn workspace_features_are_local() {
// The features for workspace packages should be the same as `cargo build`
// (i.e., the features selected depend on the "current" package).
Package::new("optdep", "1.0.0").publish();
Package::new("somedep", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["a", "b"]
"#,
)
.file(
"a/Cargo.toml",
r#"
[package]
name = "a"
version = "0.1.0"
[dependencies]
somedep = {version="1.0", features=["optdep"]}
"#,
)
.file("a/src/lib.rs", "")
.file(
"b/Cargo.toml",
r#"
[package]
name = "b"
version = "0.1.0"
[dependencies]
somedep = "1.0"
"#,
)
.file("b/src/lib.rs", "")
.build();
p.cargo("tree")
.with_stdout(
"\
a v0.1.0 ([..]/foo/a)
somedep v1.0.0
optdep v1.0.0
b v0.1.0 ([..]/foo/b)
2020-04-02 18:09:06 +00:00
somedep v1.0.0 (*)
2020-03-19 17:51:25 +00:00
",
)
.run();
p.cargo("tree -p a")
.with_stdout(
"\
a v0.1.0 ([..]/foo/a)
somedep v1.0.0
optdep v1.0.0
",
)
.run();
p.cargo("tree -p b")
.with_stdout(
"\
b v0.1.0 ([..]/foo/b)
somedep v1.0.0
",
)
.run();
}
2021-05-19 00:52:45 +00:00
#[cargo_test]
fn unknown_edge_kind() {
let p = project()
.file("Cargo.toml", "")
.file("src/lib.rs", "")
.build();
p.cargo("tree -e unknown")
.with_stderr(
"\
[ERROR] unknown edge kind `unknown`, valid values are \
\"normal\", \"build\", \"dev\", \
\"no-normal\", \"no-build\", \"no-dev\", \"no-proc-macro\", \
\"features\", or \"all\"
",
)
.with_status(101)
.run();
}
#[cargo_test]
fn mixed_no_edge_kinds() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree -e no-build,normal")
.with_stderr(
"\
[ERROR] `normal` dependency kind cannot be mixed with \
\"no-normal\", \"no-build\", or \"no-dev\" dependency kinds
",
)
.with_status(101)
.run();
// `no-proc-macro` can be mixed with others
p.cargo("tree -e no-proc-macro,normal")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
",
)
.run();
}
2021-05-28 15:27:42 +00:00
2021-05-19 00:52:45 +00:00
#[cargo_test]
fn depth_limit() {
let p = make_simple_proj();
p.cargo("tree --depth 0")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
[build-dependencies]
[dev-dependencies]
",
)
.run();
p.cargo("tree --depth 1")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
a v1.0.0
c v1.0.0
[build-dependencies]
bdep v1.0.0
[dev-dependencies]
devdep v1.0.0
",
)
.run();
p.cargo("tree --depth 2")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
a v1.0.0
b 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();
// specify a package
p.cargo("tree -p bdep --depth 1")
.with_stdout(
"\
bdep v1.0.0
b v1.0.0
",
)
.run();
// different prefix
p.cargo("tree --depth 1 --prefix depth")
.with_stdout(
"\
0foo v0.1.0 ([..]/foo)
1a v1.0.0
1c v1.0.0
1bdep v1.0.0
1devdep v1.0.0
",
)
.run();
// with edge-kinds
p.cargo("tree --depth 1 -e no-dev")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
a v1.0.0
c v1.0.0
[build-dependencies]
bdep v1.0.0
",
)
.run();
// invert
p.cargo("tree --depth 1 --invert c")
.with_stdout(
"\
c v1.0.0
b v1.0.0
foo v0.1.0 ([..]/foo)
",
)
.run();
}
2021-05-29 03:22:53 +00:00
#[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();
}
#[cargo_test]
fn cyclic_features() {
// Check for stack overflow with cyclic features (oops!).
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[features]
a = ["b"]
b = ["a"]
default = ["a"]
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("tree -e features")
.with_stdout("foo v1.0.0 ([ROOT]/foo)")
.run();
p.cargo("tree -e features -i foo")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
foo feature \"a\"
foo feature \"b\"
foo feature \"a\" (*)
foo feature \"default\" (command-line)
foo feature \"b\" (*)
foo feature \"default\" (command-line)
",
)
.run();
}
#[cargo_test]
fn dev_dep_cycle_with_feature() {
// Cycle with features and a dev-dependency.
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[dev-dependencies]
bar = { path = "bar" }
[features]
a = ["bar/feat1"]
"#,
)
.file("src/lib.rs", "")
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "1.0.0"
[dependencies]
foo = { path = ".." }
[features]
feat1 = ["foo/a"]
"#,
)
.file("bar/src/lib.rs", "")
.build();
p.cargo("tree -e features --features a")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
[dev-dependencies]
bar feature \"default\"
bar v1.0.0 ([ROOT]/foo/bar)
foo feature \"default\" (command-line)
foo v1.0.0 ([ROOT]/foo) (*)
",
)
.run();
p.cargo("tree -e features --features a -i foo")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
foo feature \"a\" (command-line)
bar feature \"feat1\"
foo feature \"a\" (command-line) (*)
foo feature \"default\" (command-line)
bar v1.0.0 ([ROOT]/foo/bar)
bar feature \"default\"
[dev-dependencies]
foo v1.0.0 ([ROOT]/foo) (*)
bar feature \"feat1\" (*)
",
)
.run();
}
#[cargo_test]
fn dev_dep_cycle_with_feature_nested() {
// Checks for an issue where a cyclic dev dependency tries to activate a
// feature on its parent that tries to activate the feature back on the
// dev-dependency.
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[dev-dependencies]
bar = { path = "bar" }
[features]
a = ["bar/feat1"]
b = ["a"]
"#,
)
.file("src/lib.rs", "")
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "1.0.0"
[dependencies]
foo = { path = ".." }
[features]
feat1 = ["foo/b"]
"#,
)
.file("bar/src/lib.rs", "")
.build();
p.cargo("tree -e features")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
[dev-dependencies]
bar feature \"default\"
bar v1.0.0 ([ROOT]/foo/bar)
foo feature \"default\" (command-line)
foo v1.0.0 ([ROOT]/foo) (*)
",
)
.run();
p.cargo("tree -e features --features a -i foo")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
foo feature \"a\" (command-line)
foo feature \"b\"
bar feature \"feat1\"
foo feature \"a\" (command-line) (*)
foo feature \"b\" (*)
foo feature \"default\" (command-line)
bar v1.0.0 ([ROOT]/foo/bar)
bar feature \"default\"
[dev-dependencies]
foo v1.0.0 ([ROOT]/foo) (*)
bar feature \"feat1\" (*)
",
)
.run();
p.cargo("tree -e features --features b -i foo")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
foo feature \"a\"
foo feature \"b\" (command-line)
bar feature \"feat1\"
foo feature \"a\" (*)
foo feature \"b\" (command-line) (*)
foo feature \"default\" (command-line)
bar v1.0.0 ([ROOT]/foo/bar)
bar feature \"default\"
[dev-dependencies]
foo v1.0.0 ([ROOT]/foo) (*)
bar feature \"feat1\" (*)
",
)
.run();
p.cargo("tree -e features --features bar/feat1 -i foo")
.with_stdout(
"\
foo v1.0.0 ([ROOT]/foo)
foo feature \"a\"
foo feature \"b\"
bar feature \"feat1\" (command-line)
foo feature \"a\" (*)
foo feature \"b\" (*)
foo feature \"default\" (command-line)
bar v1.0.0 ([ROOT]/foo/bar)
bar feature \"default\"
[dev-dependencies]
foo v1.0.0 ([ROOT]/foo) (*)
bar feature \"feat1\" (command-line) (*)
",
)
.run();
}