Skip to content
New issue

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

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

Already on GitHub? Sign in 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
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
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")
}
likzn marked this conversation as resolved.
Show resolved Hide resolved
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()
)
}
likzn marked this conversation as resolved.
Show resolved Hide resolved
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
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() {
likzn marked this conversation as resolved.
Show resolved Hide resolved
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();
}