mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00
feat(tree): Add --depth public
behind -Zunstable-options
(#15243)
### What does this PR try to resolve? I was investigating some issues around public dependency lints and wanted to see the structure of the public dependencies and had the idea to add this with us having added `--depth workspace`. See https://github.com/rust-lang/rust/issues/119428#issuecomment-2686384070 for some example output (comparing `cargo tree` with `cargo tree --depth public`) ### How should we test and review this PR? ### Additional information
This commit is contained in:
commit
73b3092fd5
@ -78,6 +78,7 @@ impl Node {
|
|||||||
pub struct Edge {
|
pub struct Edge {
|
||||||
kind: EdgeKind,
|
kind: EdgeKind,
|
||||||
node: NodeId,
|
node: NodeId,
|
||||||
|
public: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Edge {
|
impl Edge {
|
||||||
@ -88,6 +89,10 @@ impl Edge {
|
|||||||
pub fn node(&self) -> NodeId {
|
pub fn node(&self) -> NodeId {
|
||||||
self.node
|
self.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn public(&self) -> bool {
|
||||||
|
self.public
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The kind of edge, for separating dependencies into different sections.
|
/// The kind of edge, for separating dependencies into different sections.
|
||||||
@ -105,7 +110,7 @@ pub enum EdgeKind {
|
|||||||
///
|
///
|
||||||
/// The value is a `Vec` because each edge kind can have multiple outgoing
|
/// The value is a `Vec` because each edge kind can have multiple outgoing
|
||||||
/// edges. For example, package "foo" can have multiple normal dependencies.
|
/// edges. For example, package "foo" can have multiple normal dependencies.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
struct Edges(HashMap<EdgeKind, Vec<Edge>>);
|
struct Edges(HashMap<EdgeKind, Vec<Edge>>);
|
||||||
|
|
||||||
impl Edges {
|
impl Edges {
|
||||||
@ -135,6 +140,7 @@ impl Edges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A graph of dependencies.
|
/// A graph of dependencies.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Graph<'a> {
|
pub struct Graph<'a> {
|
||||||
nodes: Vec<Node>,
|
nodes: Vec<Node>,
|
||||||
/// The indexes of `edges` correspond to the `nodes`. That is, `edges[0]`
|
/// The indexes of `edges` correspond to the `nodes`. That is, `edges[0]`
|
||||||
@ -268,6 +274,7 @@ impl<'a> Graph<'a> {
|
|||||||
let new_edge = Edge {
|
let new_edge = Edge {
|
||||||
kind: edge.kind(),
|
kind: edge.kind(),
|
||||||
node: new_to_index,
|
node: new_to_index,
|
||||||
|
public: edge.public(),
|
||||||
};
|
};
|
||||||
new_graph.edges_mut(new_from).add_edge(new_edge);
|
new_graph.edges_mut(new_from).add_edge(new_edge);
|
||||||
}
|
}
|
||||||
@ -290,6 +297,7 @@ impl<'a> Graph<'a> {
|
|||||||
let new_edge = Edge {
|
let new_edge = Edge {
|
||||||
kind: edge.kind(),
|
kind: edge.kind(),
|
||||||
node: NodeId::new(from_idx, self.nodes[from_idx].name()),
|
node: NodeId::new(from_idx, self.nodes[from_idx].name()),
|
||||||
|
public: edge.public(),
|
||||||
};
|
};
|
||||||
new_edges[edge.node().index].add_edge(new_edge);
|
new_edges[edge.node().index].add_edge(new_edge);
|
||||||
}
|
}
|
||||||
@ -514,6 +522,7 @@ fn add_pkg(
|
|||||||
let new_edge = Edge {
|
let new_edge = Edge {
|
||||||
kind: EdgeKind::Dep(dep.kind()),
|
kind: EdgeKind::Dep(dep.kind()),
|
||||||
node: dep_index,
|
node: dep_index,
|
||||||
|
public: dep.is_public(),
|
||||||
};
|
};
|
||||||
if opts.graph_features {
|
if opts.graph_features {
|
||||||
// Add the dependency node with feature nodes in-between.
|
// Add the dependency node with feature nodes in-between.
|
||||||
@ -577,12 +586,14 @@ fn add_feature(
|
|||||||
let from_edge = Edge {
|
let from_edge = Edge {
|
||||||
kind: to.kind(),
|
kind: to.kind(),
|
||||||
node: node_index,
|
node: node_index,
|
||||||
|
public: to.public(),
|
||||||
};
|
};
|
||||||
graph.edges_mut(from).add_edge(from_edge);
|
graph.edges_mut(from).add_edge(from_edge);
|
||||||
}
|
}
|
||||||
let to_edge = Edge {
|
let to_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: to.node(),
|
node: to.node(),
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
graph.edges_mut(node_index).add_edge(to_edge);
|
graph.edges_mut(node_index).add_edge(to_edge);
|
||||||
(missing, node_index)
|
(missing, node_index)
|
||||||
@ -620,6 +631,7 @@ fn add_cli_features(
|
|||||||
let feature_edge = Edge {
|
let feature_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: package_index,
|
node: package_index,
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
let index = add_feature(graph, feature, None, feature_edge).1;
|
let index = add_feature(graph, feature, None, feature_edge).1;
|
||||||
graph.cli_features.insert(index);
|
graph.cli_features.insert(index);
|
||||||
@ -654,6 +666,7 @@ fn add_cli_features(
|
|||||||
let feature_edge = Edge {
|
let feature_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: package_index,
|
node: package_index,
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
let index = add_feature(graph, dep_name, None, feature_edge).1;
|
let index = add_feature(graph, dep_name, None, feature_edge).1;
|
||||||
graph.cli_features.insert(index);
|
graph.cli_features.insert(index);
|
||||||
@ -661,6 +674,7 @@ fn add_cli_features(
|
|||||||
let dep_edge = Edge {
|
let dep_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: dep_index,
|
node: dep_index,
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
let index = add_feature(graph, dep_feature, None, dep_edge).1;
|
let index = add_feature(graph, dep_feature, None, dep_edge).1;
|
||||||
graph.cli_features.insert(index);
|
graph.cli_features.insert(index);
|
||||||
@ -721,6 +735,7 @@ fn add_feature_rec(
|
|||||||
let feature_edge = Edge {
|
let feature_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: package_index,
|
node: package_index,
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
let (missing, feat_index) = add_feature(graph, *dep_name, Some(from), feature_edge);
|
let (missing, feat_index) = add_feature(graph, *dep_name, Some(from), feature_edge);
|
||||||
// Don't recursive if the edge already exists to deal with cycles.
|
// Don't recursive if the edge already exists to deal with cycles.
|
||||||
@ -771,12 +786,14 @@ fn add_feature_rec(
|
|||||||
let feature_edge = Edge {
|
let feature_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: package_index,
|
node: package_index,
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
add_feature(graph, *dep_name, Some(from), feature_edge);
|
add_feature(graph, *dep_name, Some(from), feature_edge);
|
||||||
}
|
}
|
||||||
let dep_edge = Edge {
|
let dep_edge = Edge {
|
||||||
kind: EdgeKind::Feature,
|
kind: EdgeKind::Feature,
|
||||||
node: dep_index,
|
node: dep_index,
|
||||||
|
public: true,
|
||||||
};
|
};
|
||||||
let (missing, feat_index) =
|
let (missing, feat_index) =
|
||||||
add_feature(graph, *dep_feature, Some(from), dep_edge);
|
add_feature(graph, *dep_feature, Some(from), dep_edge);
|
||||||
|
@ -91,6 +91,7 @@ impl FromStr for Prefix {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum DisplayDepth {
|
pub enum DisplayDepth {
|
||||||
MaxDisplayDepth(u32),
|
MaxDisplayDepth(u32),
|
||||||
|
Public,
|
||||||
Workspace,
|
Workspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +101,7 @@ impl FromStr for DisplayDepth {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s {
|
match s {
|
||||||
"workspace" => Ok(Self::Workspace),
|
"workspace" => Ok(Self::Workspace),
|
||||||
|
"public" => Ok(Self::Public),
|
||||||
s => s.parse().map(Self::MaxDisplayDepth).map_err(|_| {
|
s => s.parse().map(Self::MaxDisplayDepth).map_err(|_| {
|
||||||
clap::Error::raw(
|
clap::Error::raw(
|
||||||
clap::error::ErrorKind::ValueValidation,
|
clap::error::ErrorKind::ValueValidation,
|
||||||
@ -282,7 +284,7 @@ fn print(
|
|||||||
&mut visited_deps,
|
&mut visited_deps,
|
||||||
&mut levels_continue,
|
&mut levels_continue,
|
||||||
&mut print_stack,
|
&mut print_stack,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -302,7 +304,7 @@ fn print_node<'a>(
|
|||||||
visited_deps: &mut HashSet<NodeId>,
|
visited_deps: &mut HashSet<NodeId>,
|
||||||
levels_continue: &mut Vec<(anstyle::Style, bool)>,
|
levels_continue: &mut Vec<(anstyle::Style, bool)>,
|
||||||
print_stack: &mut Vec<NodeId>,
|
print_stack: &mut Vec<NodeId>,
|
||||||
) {
|
) -> CargoResult<()> {
|
||||||
let new = no_dedupe || visited_deps.insert(node_index);
|
let new = no_dedupe || visited_deps.insert(node_index);
|
||||||
|
|
||||||
match prefix {
|
match prefix {
|
||||||
@ -343,7 +345,7 @@ fn print_node<'a>(
|
|||||||
drop_println!(ws.gctx(), "{}{}", format.display(graph, node_index), star);
|
drop_println!(ws.gctx(), "{}{}", format.display(graph, node_index), star);
|
||||||
|
|
||||||
if !new || in_cycle {
|
if !new || in_cycle {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
print_stack.push(node_index);
|
print_stack.push(node_index);
|
||||||
|
|
||||||
@ -367,9 +369,11 @@ fn print_node<'a>(
|
|||||||
levels_continue,
|
levels_continue,
|
||||||
print_stack,
|
print_stack,
|
||||||
kind,
|
kind,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
print_stack.pop();
|
print_stack.pop();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints all the dependencies of a package for the given dependency kind.
|
/// Prints all the dependencies of a package for the given dependency kind.
|
||||||
@ -387,10 +391,10 @@ fn print_dependencies<'a>(
|
|||||||
levels_continue: &mut Vec<(anstyle::Style, bool)>,
|
levels_continue: &mut Vec<(anstyle::Style, bool)>,
|
||||||
print_stack: &mut Vec<NodeId>,
|
print_stack: &mut Vec<NodeId>,
|
||||||
kind: &EdgeKind,
|
kind: &EdgeKind,
|
||||||
) {
|
) -> CargoResult<()> {
|
||||||
let deps = graph.edges_of_kind(node_index, kind);
|
let deps = graph.edges_of_kind(node_index, kind);
|
||||||
if deps.is_empty() {
|
if deps.is_empty() {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = match kind {
|
let name = match kind {
|
||||||
@ -415,14 +419,20 @@ fn print_dependencies<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (max_display_depth, filter_non_workspace_member) = match display_depth {
|
let (max_display_depth, filter_non_workspace_member, filter_private) = match display_depth {
|
||||||
DisplayDepth::MaxDisplayDepth(max) => (max, false),
|
DisplayDepth::MaxDisplayDepth(max) => (max, false, false),
|
||||||
DisplayDepth::Workspace => (u32::MAX, true),
|
DisplayDepth::Workspace => (u32::MAX, true, false),
|
||||||
|
DisplayDepth::Public => {
|
||||||
|
if !ws.gctx().cli_unstable().unstable_options {
|
||||||
|
anyhow::bail!("`--depth public` requires `-Zunstable-options`")
|
||||||
|
}
|
||||||
|
(u32::MAX, false, true)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Current level exceeds maximum display depth. Skip.
|
// Current level exceeds maximum display depth. Skip.
|
||||||
if levels_continue.len() + 1 > max_display_depth as usize {
|
if levels_continue.len() + 1 > max_display_depth as usize {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut it = deps
|
let mut it = deps
|
||||||
@ -434,9 +444,17 @@ fn print_dependencies<'a>(
|
|||||||
if filter_non_workspace_member && !ws.is_member_id(*package_id) {
|
if filter_non_workspace_member && !ws.is_member_id(*package_id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if filter_private && !dep.public() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
!pkgs_to_prune.iter().any(|spec| spec.matches(*package_id))
|
!pkgs_to_prune.iter().any(|spec| spec.matches(*package_id))
|
||||||
}
|
}
|
||||||
_ => true,
|
Node::Feature { .. } => {
|
||||||
|
if filter_private && !dep.public() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.peekable();
|
.peekable();
|
||||||
@ -457,9 +475,11 @@ fn print_dependencies<'a>(
|
|||||||
visited_deps,
|
visited_deps,
|
||||||
levels_continue,
|
levels_continue,
|
||||||
print_stack,
|
print_stack,
|
||||||
);
|
)?;
|
||||||
levels_continue.pop();
|
levels_continue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edge_line_color(kind: EdgeKind) -> anstyle::Style {
|
fn edge_line_color(kind: EdgeKind) -> anstyle::Style {
|
||||||
|
@ -1901,6 +1901,138 @@ c v0.1.0 ([ROOT]/foo/c) (*)
|
|||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")]
|
||||||
|
fn depth_public() {
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[workspace]
|
||||||
|
members = ["diamond", "left-pub", "right-priv", "dep"]
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"diamond/Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["public-dependency"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "diamond"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
left-pub = { path = "../left-pub", public = true }
|
||||||
|
right-priv = { path = "../right-priv", public = true }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("diamond/src/lib.rs", "")
|
||||||
|
.file(
|
||||||
|
"left-pub/Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["public-dependency"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "left-pub"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dep = { path = "../dep", public = true }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("left-pub/src/lib.rs", "")
|
||||||
|
.file(
|
||||||
|
"right-priv/Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "right-priv"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dep = { path = "../dep" }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("right-priv/src/lib.rs", "")
|
||||||
|
.file(
|
||||||
|
"dep/Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "dep"
|
||||||
|
version = "0.1.0"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("dep/src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("tree --depth public")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_status(101)
|
||||||
|
.with_stderr_data(str![[r#"
|
||||||
|
[ERROR] `--depth public` requires `-Zunstable-options`
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree --depth public -p left-pub")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
left-pub v0.1.0 ([ROOT]/foo/left-pub)
|
||||||
|
└── dep v0.1.0 ([ROOT]/foo/dep)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree --depth public -p right-priv")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
right-priv v0.1.0 ([ROOT]/foo/right-priv)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree --depth public -p diamond")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
diamond v0.1.0 ([ROOT]/foo/diamond)
|
||||||
|
├── left-pub v0.1.0 ([ROOT]/foo/left-pub)
|
||||||
|
│ └── dep v0.1.0 ([ROOT]/foo/dep)
|
||||||
|
└── right-priv v0.1.0 ([ROOT]/foo/right-priv)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree --depth public")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
dep v0.1.0 ([ROOT]/foo/dep)
|
||||||
|
|
||||||
|
diamond v0.1.0 ([ROOT]/foo/diamond)
|
||||||
|
├── left-pub v0.1.0 ([ROOT]/foo/left-pub)
|
||||||
|
│ └── dep v0.1.0 ([ROOT]/foo/dep)
|
||||||
|
└── right-priv v0.1.0 ([ROOT]/foo/right-priv)
|
||||||
|
|
||||||
|
left-pub v0.1.0 ([ROOT]/foo/left-pub) (*)
|
||||||
|
|
||||||
|
right-priv v0.1.0 ([ROOT]/foo/right-priv) (*)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree --depth public --invert dep")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
dep v0.1.0 ([ROOT]/foo/dep)
|
||||||
|
└── left-pub v0.1.0 ([ROOT]/foo/left-pub)
|
||||||
|
└── diamond v0.1.0 ([ROOT]/foo/diamond)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn prune() {
|
fn prune() {
|
||||||
let p = make_simple_proj();
|
let p = make_simple_proj();
|
||||||
|
@ -350,3 +350,164 @@ foo v0.1.0 ([ROOT]/foo)
|
|||||||
"#]])
|
"#]])
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")]
|
||||||
|
fn depth_public_no_features() {
|
||||||
|
Package::new("pub-defaultdep", "1.0.0").publish();
|
||||||
|
Package::new("priv-defaultdep", "1.0.0").publish();
|
||||||
|
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["public-dependency"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pub-defaultdep = { version = "1.0.0", public = true }
|
||||||
|
priv-defaultdep = "1.0.0"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("tree -e features --depth public")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
foo v0.1.0 ([ROOT]/foo)
|
||||||
|
└── pub-defaultdep feature "default"
|
||||||
|
└── pub-defaultdep v1.0.0
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")]
|
||||||
|
fn depth_public_transitive_features() {
|
||||||
|
Package::new("pub-defaultdep", "1.0.0")
|
||||||
|
.feature("default", &["f1"])
|
||||||
|
.feature("f1", &["f2"])
|
||||||
|
.feature("f2", &["optdep"])
|
||||||
|
.add_dep(Dependency::new("optdep", "1.0").optional(true).public(true))
|
||||||
|
.publish();
|
||||||
|
Package::new("priv-defaultdep", "1.0.0")
|
||||||
|
.feature("default", &["f1"])
|
||||||
|
.feature("f1", &["f2"])
|
||||||
|
.feature("f2", &["optdep"])
|
||||||
|
.add_dep(Dependency::new("optdep", "1.0").optional(true))
|
||||||
|
.publish();
|
||||||
|
Package::new("optdep", "1.0.0")
|
||||||
|
.feature("default", &["f"])
|
||||||
|
.feature("f", &[])
|
||||||
|
.publish();
|
||||||
|
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["public-dependency"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pub-defaultdep = { version = "1.0.0", public = true }
|
||||||
|
priv-defaultdep = { version = "1.0.0", public = true }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("tree -e features --depth public")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
foo v0.1.0 ([ROOT]/foo)
|
||||||
|
├── priv-defaultdep feature "default"
|
||||||
|
│ ├── priv-defaultdep v1.0.0
|
||||||
|
│ └── priv-defaultdep feature "f1"
|
||||||
|
│ ├── priv-defaultdep v1.0.0 (*)
|
||||||
|
│ └── priv-defaultdep feature "f2"
|
||||||
|
│ ├── priv-defaultdep v1.0.0 (*)
|
||||||
|
│ └── priv-defaultdep feature "optdep"
|
||||||
|
│ └── priv-defaultdep v1.0.0 (*)
|
||||||
|
└── pub-defaultdep feature "default"
|
||||||
|
├── pub-defaultdep v1.0.0
|
||||||
|
│ └── optdep feature "default"
|
||||||
|
│ ├── optdep v1.0.0
|
||||||
|
│ └── optdep feature "f"
|
||||||
|
│ └── optdep v1.0.0
|
||||||
|
└── pub-defaultdep feature "f1"
|
||||||
|
├── pub-defaultdep v1.0.0 (*)
|
||||||
|
└── pub-defaultdep feature "f2"
|
||||||
|
├── pub-defaultdep v1.0.0 (*)
|
||||||
|
└── pub-defaultdep feature "optdep"
|
||||||
|
└── pub-defaultdep v1.0.0 (*)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")]
|
||||||
|
fn depth_public_cli() {
|
||||||
|
Package::new("priv", "1.0.0").feature("f", &[]).publish();
|
||||||
|
Package::new("pub", "1.0.0").feature("f", &[]).publish();
|
||||||
|
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["public-dependency"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
priv-indirect = ["priv"]
|
||||||
|
priv = ["dep:priv", "priv?/f"]
|
||||||
|
pub-indirect = ["pub"]
|
||||||
|
pub = ["dep:pub", "priv?/f"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
priv = { version = "1.0.0", optional = true }
|
||||||
|
pub = { version = "1.0.0", optional = true, public = true }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("tree -e features --depth public")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
foo v0.1.0 ([ROOT]/foo)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree -e features --depth public --features pub-indirect")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
foo v0.1.0 ([ROOT]/foo)
|
||||||
|
└── pub feature "default"
|
||||||
|
└── pub v1.0.0
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("tree -e features --depth public --features priv-indirect")
|
||||||
|
.arg("-Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["public-dependency", "depth-public"])
|
||||||
|
.with_stdout_data(str![[r#"
|
||||||
|
foo v0.1.0 ([ROOT]/foo)
|
||||||
|
|
||||||
|
"#]])
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user