Skip to content

feat(tree): show artifact dependency details#17075

Open
npmccallum wants to merge 2 commits into
rust-lang:masterfrom
npmccallum:issue-14804-bindeps-tree
Open

feat(tree): show artifact dependency details#17075
npmccallum wants to merge 2 commits into
rust-lang:masterfrom
npmccallum:issue-14804-bindeps-tree

Conversation

@npmccallum

@npmccallum npmccallum commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

What does this PR try to resolve?

cargo tree -Z bindeps currently shows artifact dependencies as ordinary dependency edges, without showing which artifact was requested. This makes several artifact-dependency shapes indistinguishable in tree output, including selected binaries, multiple artifact kinds, explicit artifact targets, and dependencies that are both normal Rust dependencies and artifact dependencies.

This PR carries artifact dependency metadata on cargo tree edges and annotates artifact edges with a compact suffix:

bar v0.5.0 (bin)
bar v0.5.0 (bin:bar-cli)
bar v0.5.0 (bin, wasm32-unknown-unknown)
bar v0.5.0 (bin:baz-suffix, staticlib, cdylib)

For lib = true, the tree renders the two relationships separately: a normal dependency edge plus an artifact dependency edge. This matches the manifest semantics and avoids a separate lib=true suffix.

Refs #14804.

Design notes

The annotation is edge-local, not package-global. The same package can be reached through a normal dependency edge, an artifact dependency edge, or multiple artifact aliases with different requested artifacts or targets. Keeping metadata on the edge lets those cases render differently without changing dependency resolution or package node identity.

Artifact dependencies stay in their existing normal/build/dev dependency sections. This follows the prior discussion that artifact dependencies are still dependency edges of those kinds; the suffix only describes the artifact request on that edge.

This PR does not implement a dashed or otherwise distinct line style for artifact edges. A line style could still be added later, but it would not replace the textual suffix because the suffix carries artifact kind, selected binary, and target details.

Commit structure

The first commit adds tests that pass with the existing output, recording the current unannotated behavior. The second commit updates the expected output while adding the edge metadata and rendering changes.

How should we test and review this PR?

Review the test output changes in the second commit; they are intended to show the display contract directly.

Local verification:

cargo fmt
git diff --check
cargo check -q
cargo test --test testsuite artifact_dep::
cargo test --test testsuite cargo_tree::

@rustbot rustbot added A-documenting-cargo-itself Area: Cargo's documentation Command-tree S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 4, 2026
@rustbot

rustbot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

r? @ehuss

rustbot has assigned @ehuss.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ehuss, @epage, @weihanglo
  • @ehuss, @epage, @weihanglo expanded to ehuss, epage, weihanglo
  • Random selection from ehuss, epage, weihanglo

}
}

#[derive(Debug, Copy, Hash, Eq, Clone, PartialEq)]

@epage epage Jun 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tip: splitting changes like this into their own commit make it easier / faster for maintainers to review, see https://epage.github.io/dev/pr-style/#c-atomic

View changes since the review

.with_status(0)
.run();

p.cargo("tree -Z bindeps -e features")

@epage epage Jun 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ask for new test cases to be added in their own commit first, with tests passing in that commit, see https://epage.github.io/dev/pr-style/#c-test

View changes since the review

Comment thread src/cargo/ops/tree/mod.rs
ws: &Workspace<'_>,
graph: &'a Graph<'_>,
node_index: NodeId,
incoming_edge: Option<&Edge>,

@epage epage Jun 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are relying on the incoming edge. Are there times where we have different edges but the same node? For example, what happens if a package has a regular dep and an artifact dep on a package?

#16192 also deals with edges and may have other relevant concerns.

View changes since the review

Comment thread tests/testsuite/artifact_dep.rs Outdated
r#"...
foo v0.1.0 ([ROOT]/foo)
└── bar v0.1.0 ([ROOT]/foo/bar)
└── bar v0.1.0 ([ROOT]/foo/bar) (artifact: bin, target=[ALT_TARGET])

@epage epage Jun 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is marked as closing the issue but part of the issue is how to visually represent the graph.

View changes since the review

@npmccallum npmccallum force-pushed the issue-14804-bindeps-tree branch from 2eb63a0 to 83d0988 Compare June 4, 2026 17:23
@npmccallum

Copy link
Copy Markdown
Contributor Author

I traced the design history through #10593, #14804, #14658, RFC 3028,
and RFC 3176. I did not find an accepted RFC-level output format for
cargo tree.

The concrete proposal in #10593 / #14804 was to annotate artifact
dependencies with the artifact kind, for example (bin), (staticlib),
or (cdylib), optionally including the target in that annotation if we
choose to show it. The prior draft PR #14658 followed that textual suffix
direction.

This PR takes that minimal textual approach, but spells the annotation
out as (artifact: ..., target=...) so the meaning is self-describing.
It keeps artifact dependencies in their existing normal/build/dev
sections and attaches the annotation to the incoming edge, not globally
to the package node. That is why a normal edge and an artifact edge to
the same package render differently.

I did not implement dashed-line rendering in this PR. Line style could
communicate that an edge is a non-linking artifact edge, but it cannot
disambiguate multiple artifact requests to the same package, such as
different artifact kinds, binary selectors, or targets. The target case
is not hypothetical; #17067 allows separate artifact dependency aliases
for the same package with different requested targets. The textual
annotation carries that edge-local detail, and the graph representation
keeps the metadata on the edge so dashed-line rendering remains possible
as a future UI refinement.

If dashed-line rendering would be valuable, I am happy to implement that
as a follow-up once there is agreement on how it should interact with the
textual artifact details.

I also changed this from Closes #14804 to Refs #14804 because the
larger visual design remains open, especially whether cargo tree
should eventually use a distinct line style and how far we want to go
for lib = true rendering.

@npmccallum npmccallum force-pushed the issue-14804-bindeps-tree branch from 83d0988 to 78717bd Compare June 24, 2026 16:18
@rustbot

This comment has been minimized.

@npmccallum

Copy link
Copy Markdown
Contributor Author

Updated this PR around the design discussion and the PR-structure feedback.

Changes in this revision:

I left the review threads open for reviewer confirmation.

Verified locally:

cargo fmt
git diff --check
cargo check -q
cargo test --test testsuite artifact_dep::
cargo test --test testsuite cargo_tree::

Add cargo tree coverage for artifact dependency display before changing the visual output. The baseline records the current behavior: artifact dependencies are displayed in their dependency section without artifact-specific annotation.

The cases cover selected binaries, multiple artifact kinds, explicit artifact targets, feature-edge output, normal and artifact edges to the same package, build-dependency placement, and lib=true.
Carry artifact dependency metadata on cargo tree edges and annotate artifact edges with a compact suffix like (bin), (bin:name), or (bin, target).

The annotation is edge-local because the same package can be reached through both normal and artifact dependency edges, or through multiple artifact aliases with different requested artifacts or targets. Artifact dependencies remain in their normal/build/dev dependency sections.

Render lib=true as two relationships: a normal dependency edge plus an artifact dependency edge. This matches the manifest semantics without needing a separate lib=true suffix.

Refs rust-lang#14804.
@npmccallum npmccallum force-pushed the issue-14804-bindeps-tree branch from 78717bd to 4280c6a Compare July 3, 2026 14:20
@rustbot

rustbot commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@epage

epage commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

We have other attempts at annotating edges which gets weird in some cases. I wonder if we should instead treat these like features: an artifact is a node that depends on the package / lib.

@epage

epage commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Not dug into all the details of this implementation (particularly when there are bigger questions) but

  • consider how this interacts with --format
  • the more you split out refactors / logistical changes (like possibly removing Copy), it removes noise from the most relevant changes, making it easier to review, particularly with limited reviewer time

@rustbot

rustbot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (possibly #17169) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-documenting-cargo-itself Area: Cargo's documentation Command-tree S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants