Skip to content

Commit 4751950

Browse files
committed
Auto merge of #10707 - ehuss:beta-backport, r=weihanglo
[beta] Backport `cargo publish` fixes Beta backport of #10677. I think it is a serious regression where `cargo publish` may publish the wrong package in some circumstances. I think it warrants a beta backport to get the fix out asap.
2 parents 3f052d8 + 735f2c8 commit 4751950

File tree

3 files changed

+341
-25
lines changed

3 files changed

+341
-25
lines changed

src/cargo/ops/cargo_compile.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,13 @@ impl Packages {
174174
};
175175
if specs.is_empty() {
176176
if ws.is_virtual() {
177-
anyhow::bail!(
177+
bail!(
178178
"manifest path `{}` contains no package: The manifest is virtual, \
179179
and the workspace has no members.",
180180
ws.root().display()
181181
)
182182
}
183-
anyhow::bail!("no packages to compile")
183+
bail!("no packages to compile")
184184
}
185185
Ok(specs)
186186
}

src/cargo/ops/registry.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::core::resolver::CliFeatures;
2323
use crate::core::source::Source;
2424
use crate::core::{Package, SourceId, Workspace};
2525
use crate::ops;
26+
use crate::ops::Packages;
2627
use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_DOMAIN, CRATES_IO_REGISTRY};
2728
use crate::util::config::{self, Config, SslVersionConfig, SslVersionConfigRange};
2829
use crate::util::errors::CargoResult;
@@ -90,7 +91,24 @@ pub struct PublishOpts<'cfg> {
9091

9192
pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
9293
let specs = opts.to_publish.to_package_id_specs(ws)?;
94+
if specs.len() > 1 {
95+
bail!("the `-p` argument must be specified to select a single package to publish")
96+
}
97+
if Packages::Default == opts.to_publish && ws.is_virtual() {
98+
bail!("the `-p` argument must be specified in the root of a virtual workspace")
99+
}
100+
let member_ids = ws.members().map(|p| p.package_id());
101+
// Check that the spec matches exactly one member.
102+
specs[0].query(member_ids)?;
93103
let mut pkgs = ws.members_with_features(&specs, &opts.cli_features)?;
104+
// In `members_with_features_old`, it will add "current" package (determined by the cwd)
105+
// So we need filter
106+
pkgs = pkgs
107+
.into_iter()
108+
.filter(|(m, _)| specs.iter().any(|spec| spec.matches(m.package_id())))
109+
.collect();
110+
// Double check. It is safe theoretically, unless logic has updated.
111+
assert_eq!(pkgs.len(), 1);
94112

95113
let (pkg, cli_features) = pkgs.pop().unwrap();
96114

0 commit comments

Comments
 (0)