Skip to content

Commit 735f2c8

Browse files
borsehuss
authored andcommitted
Auto merge of #10677 - likzn:fix_publish_p, r=ehuss
fix(publish): add more check when use `publish -p <SPEC>` ### Main issue As issue say #10536 , we need add more check when user use `cargo publish -p <SPEC>` >`@ehuss` point outs: >From a behavior standpoint, here are some things to check: > - In the root of a virtual workspace, it should be an error to run without -p. >- It should be an error to pass -p for a non-workspace member. >- It should be an error for -p to match multiple packages. >- When using -p, it should publish that package, not the one in the current directory (which can be different).
1 parent 3f052d8 commit 735f2c8

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)