Skip to content

Commit

Permalink
feat: package doesnt exist in workspace is regarded as an error
Browse files Browse the repository at this point in the history
  • Loading branch information
linyihai committed Feb 6, 2025
1 parent 69a3e0a commit 23ab2af
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 84 deletions.
50 changes: 41 additions & 9 deletions src/cargo/ops/cargo_compile/packages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub enum Packages {
/// Opt in all packages.
///
/// As of the time of this writing, it only works on opting in all workspace members.
All,
/// Keeps the packages passed in to verify that they exist in the workspace.
All(Vec<String>),
/// Opt out of packages passed in.
///
/// As of the time of this writing, it only works on opting out workspace members.
Expand All @@ -36,19 +37,21 @@ impl Packages {
(false, 0, 0) => Packages::Default,
(false, 0, _) => Packages::Packages(package),
(false, _, _) => anyhow::bail!("--exclude can only be used together with --workspace"),
(true, 0, _) => Packages::All,
(true, 0, _) => Packages::All(package),
(true, _, _) => Packages::OptOut(exclude),
})
}

/// Converts selected packages to [`PackageIdSpec`]s.
pub fn to_package_id_specs(&self, ws: &Workspace<'_>) -> CargoResult<Vec<PackageIdSpec>> {
let specs = match self {
Packages::All => ws
.members()
.map(Package::package_id)
.map(|id| id.to_spec())
.collect(),
Packages::All(packages) => {
emit_packages_not_found_within_workspace(ws, packages)?;
ws.members()
.map(Package::package_id)
.map(|id| id.to_spec())
.collect()
}
Packages::OptOut(opt_out) => {
let (mut patterns, mut ids) = opt_patterns_and_ids(opt_out)?;
let specs = ws
Expand Down Expand Up @@ -111,7 +114,10 @@ impl Packages {
pub fn get_packages<'ws>(&self, ws: &'ws Workspace<'_>) -> CargoResult<Vec<&'ws Package>> {
let packages: Vec<_> = match self {
Packages::Default => ws.default_members().collect(),
Packages::All => ws.members().collect(),
Packages::All(packages) => {
emit_packages_not_found_within_workspace(ws, packages)?;
ws.members().collect()
}
Packages::OptOut(opt_out) => {
let (mut patterns, mut ids) = opt_patterns_and_ids(opt_out)?;
let packages = ws
Expand Down Expand Up @@ -161,7 +167,7 @@ impl Packages {
pub fn needs_spec_flag(&self, ws: &Workspace<'_>) -> bool {
match self {
Packages::Default => ws.default_members().count() > 1,
Packages::All => ws.members().count() > 1,
Packages::All(_) => ws.members().count() > 1,
Packages::Packages(_) => true,
Packages::OptOut(_) => true,
}
Expand Down Expand Up @@ -207,6 +213,32 @@ fn emit_pattern_not_found(
Ok(())
}

fn emit_packages_not_found_within_workspace(
ws: &Workspace<'_>,
packages: &[String],
) -> CargoResult<()> {
let (mut patterns, mut ids) = opt_patterns_and_ids(packages)?;
let _: Vec<_> = ws
.members()
.filter(|pkg| {
let id = ids.iter().find(|id| id.matches(pkg.package_id())).cloned();
if let Some(id) = &id {
ids.remove(id);
}
!id.is_some() && !match_patterns(pkg, &mut patterns)
})
.map(Package::package_id)
.map(|id| id.to_spec())
.collect();
let names = ids
.into_iter()
.map(|id| id.to_string())
.collect::<BTreeSet<_>>();
emit_package_not_found(ws, names, false)?;
emit_pattern_not_found(ws, patterns, false)?;
Ok(())
}

/// Given a list opt-in or opt-out package selection strings, generates two
/// collections that represent glob patterns and package id specs respectively.
fn opt_patterns_and_ids(
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_output_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fn build_resolve_graph(
CompileKind::from_requested_targets(ws.gctx(), &metadata_opts.filter_platforms)?;
let mut target_data = RustcTargetData::new(ws, &requested_kinds)?;
// Resolve entire workspace.
let specs = Packages::All.to_package_id_specs(ws)?;
let specs = Packages::All(Vec::new()).to_package_id_specs(ws)?;
let force_all = if metadata_opts.filter_platforms.is_empty() {
crate::core::resolver::features::ForceAllTargets::Yes
} else {
Expand Down
96 changes: 22 additions & 74 deletions tests/testsuite/workspaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2648,123 +2648,71 @@ fn nonexistence_package_togother_with_workspace() {
let p = p.build();

p.cargo("check --package nonexistence --workspace")
.with_status(101)
.with_stderr_data(
str![[r#"
[CHECKING] foo v0.1.0 ([ROOT]/foo)
[CHECKING] baz v0.1.0 ([ROOT]/foo/baz)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[ERROR] package(s) `nonexistence` not found in workspace `[ROOT]/foo`
"#]]
.unordered(),
)
.run();
// With pattern *
p.cargo("check --package nonpattern* --workspace")
.with_status(101)
.with_stderr_data(str![[r#"
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[ERROR] package pattern(s) `nonpattern*` not found in workspace `[ROOT]/foo`
"#]])
.run();

p.cargo("package --package nonexistence --workspace")
.with_status(101)
.with_stderr_data(str![[r#"
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] baz v0.1.0 ([ROOT]/foo/baz)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.1.0 ([ROOT]/foo)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] baz v0.1.0 ([ROOT]/foo/baz)
[COMPILING] baz v0.1.0 ([ROOT]/foo/target/package/baz-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[VERIFYING] foo v0.1.0 ([ROOT]/foo)
[COMPILING] foo v0.1.0 ([ROOT]/foo/target/package/foo-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[ERROR] package(s) `nonexistence` not found in workspace `[ROOT]/foo`
"#]])
.run();
// With pattern *
p.cargo("package --package nonpattern* --workspace")
.with_status(101)
.with_stderr_data(str![[r#"
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] baz v0.1.0 ([ROOT]/foo/baz)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.1.0 ([ROOT]/foo)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] baz v0.1.0 ([ROOT]/foo/baz)
[COMPILING] baz v0.1.0 ([ROOT]/foo/target/package/baz-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[VERIFYING] foo v0.1.0 ([ROOT]/foo)
[COMPILING] foo v0.1.0 ([ROOT]/foo/target/package/foo-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[ERROR] package pattern(s) `nonpattern*` not found in workspace `[ROOT]/foo`
"#]])
.run();

p.cargo("publish --dry-run --package nonexistence -Zpackage-workspace --workspace")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
[WARNING] crate [email protected] already exists on crates.io index
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] baz v0.1.0 ([ROOT]/foo/baz)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.1.0 ([ROOT]/foo)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] baz v0.1.0 ([ROOT]/foo/baz)
[COMPILING] baz v0.1.0 ([ROOT]/foo/target/package/baz-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[VERIFYING] foo v0.1.0 ([ROOT]/foo)
[COMPILING] foo v0.1.0 ([ROOT]/foo/target/package/foo-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[UPLOADING] baz v0.1.0 ([ROOT]/foo/baz)
[WARNING] aborting upload due to dry run
[UPLOADING] foo v0.1.0 ([ROOT]/foo)
[WARNING] aborting upload due to dry run
[ERROR] package(s) `nonexistence` not found in workspace `[ROOT]/foo`
"#]])
.masquerade_as_nightly_cargo(&["package-workspace"])
.run();
// With pattern *
p.cargo("publish --dry-run --package nonpattern* -Zpackage-workspace --workspace")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
[WARNING] crate [email protected] already exists on crates.io index
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] baz v0.1.0 ([ROOT]/foo/baz)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.1.0 ([ROOT]/foo)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] baz v0.1.0 ([ROOT]/foo/baz)
[COMPILING] baz v0.1.0 ([ROOT]/foo/target/package/baz-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[VERIFYING] foo v0.1.0 ([ROOT]/foo)
[COMPILING] foo v0.1.0 ([ROOT]/foo/target/package/foo-0.1.0)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[UPLOADING] baz v0.1.0 ([ROOT]/foo/baz)
[WARNING] aborting upload due to dry run
[UPLOADING] foo v0.1.0 ([ROOT]/foo)
[WARNING] aborting upload due to dry run
[ERROR] package pattern(s) `nonpattern*` not found in workspace `[ROOT]/foo`
"#]])
.masquerade_as_nightly_cargo(&["package-workspace"])
.run();

p.cargo("tree --package nonexistence --workspace")
.with_stderr_data(str![])
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] package(s) `nonexistence` not found in workspace `[ROOT]/foo`
"#]])
.run();
// With pattern *
p.cargo("tree --package nonpattern* --workspace")
.with_stderr_data(str![])
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] package pattern(s) `nonpattern*` not found in workspace `[ROOT]/foo`
"#]])
.run();
}

0 comments on commit 23ab2af

Please sign in to comment.