Skip to content

Commit 2182b47

Browse files
Feature --exclude-unpublished (#710)
This PR adds a new command line flag `--exclude-unpublished`. If the flag is set, the construction of the crate graph does not use explicitly unpublished crates as roots. Workspace members are considered explicitly unpublished if their manifest specifies `publish = false`. For motivation please see the [associated issue](#708). This PR depends on EmbarkStudios/krates#94 to fix the workspace filters mechanism of https://github.com/EmbarkStudios/krates. Documentation for the flag will follow as soon as I find the time. --------- Co-authored-by: Jake Shadle <[email protected]>
1 parent c54dc46 commit 2182b47

File tree

9 files changed

+170
-73
lines changed

9 files changed

+170
-73
lines changed

Cargo.lock

Lines changed: 107 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cargo-deny/check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ pub(crate) fn cmd(
161161
krate_ctx.all_features |= graph.all_features;
162162
krate_ctx.no_default_features |= graph.no_default_features;
163163
krate_ctx.exclude_dev |= graph.exclude_dev | args.exclude_dev;
164+
krate_ctx.exclude_unpublished |= graph.exclude_unpublished;
164165

165166
// If not specified on the cmd line, fallback to the feature related config options
166167
if krate_ctx.features.is_empty() {

src/cargo-deny/common.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub struct KrateContext {
2424
pub locked: bool,
2525
pub offline: bool,
2626
pub exclude_dev: bool,
27+
pub exclude_unpublished: bool,
2728
}
2829

2930
impl KrateContext {
@@ -169,7 +170,14 @@ impl KrateContext {
169170
}),
170171
);
171172
}
172-
173+
if self.exclude_unpublished {
174+
gb.include_workspace_crates(metadata.workspace_packages().iter().filter_map(
175+
|package| match package.publish {
176+
Some(ref registries) if registries.is_empty() => None,
177+
_ => Some(package.manifest_path.as_std_path()),
178+
},
179+
));
180+
}
173181
// Attempt to open the crates.io index so that the feature sets for every
174182
// crate in the graph are correct, however, don't consider it a hard failure
175183
// if we can't for some reason, as the graph will _probably_ still be accurate

src/cargo-deny/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ pub(crate) struct GraphContext {
9898
#[arg(long)]
9999
/// If set, excludes all dev-dependencies, not just ones for non-workspace crates
100100
pub(crate) exclude_dev: bool,
101+
#[arg(long)]
102+
/// If set, exclude unpublished workspace members from graph roots.
103+
/// Workspace members are considered unpublished if they they are explicitly marked with `publish = false` as such.
104+
/// Note that the excluded workspace members are still used for the initial dependency resolution by cargo,
105+
/// which might affect the exact version of used dependencies.
106+
pub(crate) exclude_unpublished: bool,
101107
}
102108

103109
/// Lints your project's crate graph
@@ -296,6 +302,7 @@ fn real_main() -> Result<(), Error> {
296302
locked: args.ctx.locked,
297303
offline: args.ctx.offline,
298304
exclude_dev: args.ctx.exclude_dev,
305+
exclude_unpublished: args.ctx.exclude_unpublished,
299306
};
300307

301308
let log_ctx = crate::common::LogContext {

src/root_cfg.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct GraphConfig {
4848
pub no_default_features: bool,
4949
/// By default, dev dependencies for workspace crates are not ignored
5050
pub exclude_dev: bool,
51+
pub exclude_unpublished: bool,
5152
}
5253

5354
impl<'de> Deserialize<'de> for GraphConfig {
@@ -59,6 +60,7 @@ impl<'de> Deserialize<'de> for GraphConfig {
5960
let all_features = th.optional("all-features").unwrap_or_default();
6061
let no_default_features = th.optional("no-default-features").unwrap_or_default();
6162
let exclude_dev = th.optional("exclude-dev").unwrap_or_default();
63+
let exclude_unpublished = th.optional("exclude-unpublished").unwrap_or_default();
6264
th.finalize(None)?;
6365

6466
Ok(Self {
@@ -68,6 +70,7 @@ impl<'de> Deserialize<'de> for GraphConfig {
6870
all_features,
6971
no_default_features,
7072
exclude_dev,
73+
exclude_unpublished,
7174
})
7275
}
7376
}

tests/bans.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ allow-wildcard-paths = true
118118
insta::assert_json_snapshot!(diags);
119119
}
120120

121+
/// Ensures that individual workspace crates can be ignored
122+
#[test]
123+
fn ignores_unpublished_crates() {
124+
let project_dir = camino::Utf8PathBuf::from("./tests/test_data/workspace");
125+
126+
let mut cmd = krates::Cmd::new();
127+
cmd.current_dir(project_dir.clone());
128+
129+
let mut kb = krates::Builder::new();
130+
kb.ignore_kind(krates::DepKind::Build, krates::Scope::All);
131+
kb.include_workspace_crates([project_dir.join("crates/member-two/Cargo.toml")]);
132+
let krates = kb
133+
.build(cmd, krates::NoneFilter)
134+
.expect("failed to build crate graph");
135+
136+
let diags = gather_diagnostics::<cargo_deny::bans::cfg::Config, _, _>(
137+
&krates,
138+
func_name!(),
139+
// If either the workspace `root` or `member-one` crates are pulled in,
140+
// they will emit diagnostics that won't be emitted by just including member-two
141+
r#"
142+
multiple-versions = 'allow'
143+
wildcards = 'deny'
144+
allow-wildcard-paths = true
145+
"#
146+
.into(),
147+
|ctx, tx| {
148+
cargo_deny::bans::check(ctx, None, tx);
149+
},
150+
);
151+
152+
insta::assert_json_snapshot!(diags);
153+
}
154+
121155
/// Ensures that dependencies with wildcard and git are allowed for private packages
122156
#[test]
123157
fn allow_git_wildcards_private_package() {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
source: tests/bans.rs
3+
expression: diags
4+
snapshot_kind: text
5+
---
6+
[]

tests/snapshots/cargo_deny__test__cargo_deny.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,11 @@ Options:
8989
--exclude-dev
9090
If set, excludes all dev-dependencies, not just ones for non-workspace crates
9191

92+
--exclude-unpublished
93+
If set, exclude unpublished workspace members from graph roots. Workspace members are considered unpublished if they they are explicitly marked with `publish = false` as such. Note that the excluded workspace members are still used for the initial dependency resolution by cargo, which might affect the exact version of used dependencies
94+
9295
-h, --help
9396
Print help (see a summary with '-h')
9497

9598
-V, --version
9699
Print version
97-

tests/test_data/wildcards/allow-paths-private/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@ license = "MIT"
77

88
publish = false
99

10-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11-
1210
[dependencies]
1311
wildcards-test-allow-paths-dependency = { path = "../allow-paths-dependency" }

0 commit comments

Comments
 (0)