Skip to content

Add --no-dev flag to skip dev-dependencies#791

Open
dharimarzouq wants to merge 3 commits into
trailofbits:mainfrom
dharimarzouq:no-dev-flag
Open

Add --no-dev flag to skip dev-dependencies#791
dharimarzouq wants to merge 3 commits into
trailofbits:mainfrom
dharimarzouq:no-dev-flag

Conversation

@dharimarzouq

Copy link
Copy Markdown

adds a --no-dev flag, as discussed in #607, following cargo-supply-chain's naming. when set, dev-dependencies are skipped in outdated_deps.

while writing the test i found the false positive only manifests when the dev-deps crate is resolvable in the scanned projects tree (otherwise the existing find_packages let-else already skips it). the fixture therefore depends on rand 0.8 directly, mirroring the situation in the issue: xz2 is flagged via its rand ^0.8 dev-dependency without the flag, and not flagged with it.

snapshots were blessed on windows; happy to adjust if anything is platform-flavored.

@dharimarzouq dharimarzouq requested a review from smoelius as a code owner July 10, 2026 13:42
@CLAassistant

CLAassistant commented Jul 10, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@smoelius

Copy link
Copy Markdown
Collaborator

Those failures are not your code's fault. I will address them and then rebase your code shortly.

@smoelius smoelius force-pushed the no-dev-flag branch 2 times, most recently from c4563fb to 0117f7d Compare July 12, 2026 00:05

@smoelius smoelius left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please note that I rebased your branch.

This looks very good. Thanks very much for doing this.

Please ensure that all files end in a newline. For example, fixtures/dev-dependencies/src/lib.rs is currently an empty file. Please make it file consisting of a single newline.

while writing the test i found the false positive only manifests when the dev-deps crate is resolvable in the scanned projects tree (otherwise the existing find_packages let-else already skips it). the fixture therefore depends on rand 0.8 directly, mirroring the situation in the issue: xz2 is flagged via its rand ^0.8 dev-dependency without the flag, and not flagged with it.

I want to be sure I understand. For a problem to arise, the following must occur:

  • a dependency Y resolves normally (Y = rand in this case)
  • Y is used as a dev dependency by some other package X (X = xz2 in this case)
  • X's use of Y causes X to appear unmaintained

In other words, dependency Y must resolve normally. If it does not, it will not be found under X. Is that right?

Comment thread fixtures/dev-dependencies/Cargo.toml Outdated

[dependencies]
rand = "0.8"
xz2 = "0.1.7" No newline at end of file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
xz2 = "0.1.7"
xz2 = "0.1"

Nit. Generally, the project does not include patch versions in Cargo.toml files.

(Also, please add a newline here.)

@dharimarzouq

Copy link
Copy Markdown
Author

yes exactly. if Y doesnt resolve in the scanned tree, the let-else before the version check skips it (thats what the existing debug_assert is about), so X can never be flagged through Y. the fixture depends on rand directly for that reason only, it never uses it :) Nits amended also, thank you!

@smoelius

Copy link
Copy Markdown
Collaborator

yes exactly. if Y doesnt resolve in the scanned tree, the let-else before the version check skips it (thats what the existing debug_assert is about), so X can never be flagged through Y. the fixture depends on rand directly for that reason only, it never uses it :) Nits amended also, thank you!

That bothers me because it sounds like avoiding dev-dependencies is a half-implemented cargo-unmaintained feature.

Your example demonstrates this: if a package X has outdated dev-dependencies, whether X is flagged depends on what else is used in the environment in which X is used.

How would you feel about eliminating the flag and making the new behavior the default? (If you are willing, please keep both tests, but give them different names.)

Alternatively, we could merge your change as-is, and I could make the behavior the default afterward.

@dharimarzouq

Copy link
Copy Markdown
Author

happy to make it the default, agree the flag was papering over the inconsistency. ill remove --no-dev + make the skip unconditional + keep both tests renamed (regression-proofing the default from both sides).

one question: the new default will change some existing real-github snapshots too, eg hyperfine.json has bitvec flagged partly via its rand ^0.8 dev-dependency, which disappears... want me to re-bless those as part of this pr or leave them to you?

after taking a look, ill also tighten the debug_assert in the let-else to just dep.optional since dev-deps cant reach it anymore.

@smoelius

Copy link
Copy Markdown
Collaborator

happy to make it the default, agree the flag was papering over the inconsistency. ill remove --no-dev + make the skip unconditional + keep both tests renamed (regression-proofing the default from both sides).

🙏

one question: the new default will change some existing real-github snapshots too, eg hyperfine.json has bitvec flagged partly via its rand ^0.8 dev-dependency, which disappears... want me to re-bless those as part of this pr or leave them to you?

Sure. Thank you. If this becomes too much of a PITA, we can fallback to 9eee658 and I can make those changes spearately.

after taking a look, ill also tighten the debug_assert in the let-else to just dep.optional since dev-deps cant reach it anymore.

Is that debug_assert reachable with dep.optional? If so, then yes please, and can you tell me what triggers it?

@dharimarzouq

Copy link
Copy Markdown
Author

Is that debug_assert reachable with dep.optional?

yes it is

can you tell me what triggers it?

X declares an optional dep Y and nothing in the scanned tree activates the feature, so Y never resolves and find_packages misses it with dep.optional = true.

funny thing is i didnt plan for this, but xz2 0.1.7 declares futures and tokio-io as optional deps behind its tokio feature, and neither is in my fixtures lockfiles, so both testcases already exercise the assert on every run. cargo test builds in debug, so if the tightened assert was wrong the suite wouldve panicked by now

@smoelius

Copy link
Copy Markdown
Collaborator

If you rebase onto the current main, it should resolve that CI failure.

Closes trailofbits#607. The false positive only fires when the dev-dep crate is
resolvable in the scanned tree, so the test fixture depends on rand 0.8
directly to recreate it. xz2 is flagged without the flag, clean with it.
whether X got flagged via dev-deps depended on what else was in the
scanned tree, so its now unconditional. debug_assert in the let-else
tightened to dep.optional (exercised by both fixtures via xz2s
optional futures/tokio-io). re-blessed hyperfine and taplo snapshots,
removals only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants