Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix(publish): add more check when use publish -p <SPEC> #10677

Merged
merged 13 commits into from
May 27, 2022
4 changes: 2 additions & 2 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,13 @@ impl Packages {
};
if specs.is_empty() {
if ws.is_virtual() {
anyhow::bail!(
bail!(
"manifest path `{}` contains no package: The manifest is virtual, \
and the workspace has no members.",
ws.root().display()
)
}
anyhow::bail!("no packages to compile")
bail!("no packages to compile")
}
Ok(specs)
}
Expand Down
31 changes: 31 additions & 0 deletions src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use anyhow::{bail, format_err, Context as _};
use cargo_util::paths;
use crates_io::{self, NewCrate, NewCrateDependency, Registry};
use curl::easy::{Easy, InfoType, SslOpt, SslVersion};
use itertools::Itertools;
use log::{log, Level};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use termcolor::Color::Green;
Expand All @@ -23,6 +24,7 @@ use crate::core::resolver::CliFeatures;
use crate::core::source::Source;
use crate::core::{Package, SourceId, Workspace};
use crate::ops;
use crate::ops::Packages::Packages;
use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_DOMAIN, CRATES_IO_REGISTRY};
use crate::util::config::{self, Config, SslVersionConfig, SslVersionConfigRange};
use crate::util::errors::CargoResult;
Expand Down Expand Up @@ -90,8 +92,37 @@ pub struct PublishOpts<'cfg> {

pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
let specs = opts.to_publish.to_package_id_specs(ws)?;

let mut pkgs = ws.members_with_features(&specs, &opts.cli_features)?;

if let Packages(opt_in) = &opts.to_publish {
if ws.is_virtual() {
bail!("can't use \"--package <SPEC>\" in virtual manifest")
}
let matched_packages = ws
.members()
.filter(|m| specs.iter().any(|spec| spec.matches(m.package_id())))
.collect::<Vec<_>>();
if matched_packages.is_empty() {
bail!(
"not found `{}` in manifest members. Check in manifest path `{}`",
opt_in.get(0).unwrap(),
ws.root().display()
)
}
if matched_packages.len() > 1 {
bail!(
"found multiple `{}` in manifest members. Check in manifest path `{}`",
opt_in.get(0).unwrap(),
ws.root().display()
)
}
pkgs = pkgs
.into_iter()
.filter(|(m, _)| specs.iter().any(|spec| spec.matches(m.package_id())))
.collect_vec();
}

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

let mut publish_registry = opts.registry.clone();
Expand Down
159 changes: 132 additions & 27 deletions tests/testsuite/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,30 @@ fn validate_upload_foo() {
);
}

fn validate_upload_bar() {
fn validate_upload_li() {
publish::validate_upload(
r#"
{
"authors": [],
"badges": {},
"categories": [],
"deps": [],
"description": "bar",
"description": "li",
"documentation": null,
"features": {},
"homepage": null,
"keywords": [],
"license": "MIT",
"license_file": null,
"links": null,
"name": "bar",
"name": "li",
"readme": null,
"readme_file": null,
"repository": null,
"vers": "0.0.1"
}
"#,
"bar-0.0.1.crate",
"li-0.0.1.crate",
&["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
);
}
Expand Down Expand Up @@ -1665,15 +1665,60 @@ Caused by:
}

#[cargo_test]
fn in_workspace() {
fn in_package_workspace() {
registry::init();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[workspace]
members = ["li"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"li/Cargo.toml",
r#"
[package]
name = "li"
version = "0.0.1"
description = "li"
license = "MIT"
"#,
)
.file("li/src/main.rs", "fn main() {}")
.build();

p.cargo("publish -p li --no-verify --token sekrit")
.with_stderr(
"\
[UPDATING] [..]
[WARNING] manifest has no documentation, homepage or repository.
See [..]
[PACKAGING] li v0.0.1 ([CWD]/li)
[UPLOADING] li v0.0.1 ([CWD]/li)
",
)
.run();

validate_upload_li();
}

#[cargo_test]
fn in_virtual_workspace() {
registry::init();

let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo", "bar"]
members = ["foo"]
"#,
)
.file(
Expand All @@ -1688,46 +1733,106 @@ fn in_workspace() {
"#,
)
.file("foo/src/main.rs", "fn main() {}")
.build();

p.cargo("publish --no-verify --token sekrit -p foo")
.with_status(101)
.with_stderr("error: can't use \"--package <SPEC>\" in virtual manifest")
.run();
}

#[cargo_test]
fn in_package_workspace_not_found() {
registry::init();

let p = project()
.file(
"bar/Cargo.toml",
"Cargo.toml",
r#"
[project]
name = "bar"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[workspace]
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"li/Cargo.toml",
r#"
[package]
name = "li"
version = "0.0.1"
edition = "2021"
authors = []
license = "MIT"
description = "bar"
workspace = ".."
description = "li"
"#,
)
.file("bar/src/main.rs", "fn main() {}")
.file("li/src/main.rs", "fn main() {}")
.build();

p.cargo("publish --no-verify --token sekrit -p foo")
p.cargo("publish -p li --no-verify --token sekrit ")
.with_status(101)
.with_stderr(
"\
[UPDATING] [..]
[WARNING] manifest has no documentation, [..]
See [..]
[PACKAGING] foo v0.0.1 ([CWD]/foo)
[UPLOADING] foo v0.0.1 ([CWD]/foo)
error: not found `li` in manifest members. Check in manifest path `[CWD]`
",
)
.run();
}

validate_upload_foo();
#[cargo_test]
fn in_package_workspace_found_mutilate() {
registry::init();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[workspace]
members = ["li","lii"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"li/Cargo.toml",
r#"
[package]
name = "li"
version = "0.0.1"
edition = "2021"
authors = []
license = "MIT"
description = "li"
"#,
)
.file("li/src/main.rs", "fn main() {}")
.file(
"lii/Cargo.toml",
r#"
[package]
name = "lii"
version = "0.0.1"
edition = "2021"
authors = []
license = "MIT"
description = "lii"
"#,
)
.file("lii/src/main.rs", "fn main() {}")
.build();

p.cargo("publish --no-verify --token sekrit -p bar")
p.cargo("publish -p li* --no-verify --token sekrit ")
.with_status(101)
.with_stderr(
"\
[UPDATING] [..]
[WARNING] manifest has no documentation, [..]
See [..]
[PACKAGING] bar v0.0.1 ([CWD]/bar)
[UPLOADING] bar v0.0.1 ([CWD]/bar)
error: found multiple `li*` in manifest members. Check in manifest path `[CWD]`
",
)
.run();

validate_upload_bar();
}