Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 41 additions & 20 deletions src/cargo/ops/registry/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,26 +126,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
}

let just_pkgs: Vec<_> = pkgs.iter().map(|p| p.0).collect();
let reg_or_index = match opts.reg_or_index.clone() {
Some(r) => {
validate_registry(&just_pkgs, Some(&r))?;
Some(r)
}
None => {
let reg = super::infer_registry(&just_pkgs)?;
validate_registry(&just_pkgs, reg.as_ref())?;
if let Some(RegistryOrIndex::Registry(registry)) = &reg {
if registry != CRATES_IO_REGISTRY {
// Don't warn for crates.io.
opts.gctx.shell().note(&format!(
"found `{}` as only allowed registry. Publishing to it automatically.",
registry
))?;
}
}
reg
}
};
let reg_or_index = resolve_registry_or_index(opts, &just_pkgs)?;

// This is only used to confirm that we can create a token before we build the package.
// This causes the credential provider to be called an extra time, but keeps the same order of errors.
Expand Down Expand Up @@ -814,6 +795,46 @@ fn package_list(pkgs: impl IntoIterator<Item = PackageId>, final_sep: &str) -> S
}
}

fn resolve_registry_or_index(
opts: &PublishOpts<'_>,
just_pkgs: &[&Package],
) -> CargoResult<Option<RegistryOrIndex>> {
let opt_index_or_registry = opts.reg_or_index.clone();

let res = match opt_index_or_registry {
ref r @ Some(ref registry_or_index) => {
validate_registry(just_pkgs, r.as_ref())?;

let registry_is_specified_by_any_package = just_pkgs
.iter()
.any(|pkg| pkg.publish().as_ref().map(|v| v.len()).unwrap_or(0) > 0);

if registry_is_specified_by_any_package && registry_or_index.is_index() {
opts.gctx.shell().warn(r#"`--index` will ignore registries set by `package.publish` in Cargo.toml, and may cause unexpected push to prohibited registry
help: use `--registry` instead or set `publish = true` in Cargo.toml to suppress this warning"#)?;
}

r.clone()
}
None => {
let reg = super::infer_registry(&just_pkgs)?;
validate_registry(&just_pkgs, reg.as_ref())?;
if let Some(RegistryOrIndex::Registry(registry)) = &reg {
if registry != CRATES_IO_REGISTRY {
// Don't warn for crates.io.
opts.gctx.shell().note(&format!(
"found `{}` as only allowed registry. Publishing to it automatically.",
registry
))?;
}
}
reg
}
};

Ok(res)
}

fn validate_registry(pkgs: &[&Package], reg_or_index: Option<&RegistryOrIndex>) -> CargoResult<()> {
let reg_name = match reg_or_index {
Some(RegistryOrIndex::Registry(r)) => Some(r.as_str()),
Expand Down
55 changes: 55 additions & 0 deletions tests/testsuite/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,60 @@ fn publish_implicitly_to_only_allowed_registry() {
);
}

#[cargo_test]
fn publish_when_both_publish_and_index_specified() {
let registry = RegistryBuilder::new()
.http_api()
.http_index()
.alternative()
.build();

let p = project().build();

let _ = repo(&paths::root().join("foo"))
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
authors = []
license = "MIT"
description = "foo"
documentation = "foo"
homepage = "foo"
repository = "foo"
publish = ["registry"]
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("publish")
.arg("--index")
.arg(registry.index_url().as_str())
.arg("--token")
.arg(registry.token())
.with_stderr_data(str![[r#"
[WARNING] `cargo publish --token` is deprecated in favor of using `cargo login` and environment variables
[WARNING] `--index` will ignore registries set by `package.publish` in Cargo.toml, and may cause unexpected push to prohibited registry
[HELP] use `--registry` instead or set `publish = true` in Cargo.toml to suppress this warning
[UPDATING] [..] index
[PACKAGING] foo v0.0.1 ([ROOT]/foo)
[PACKAGED] 5 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] foo v0.0.1 ([ROOT]/foo)
[COMPILING] foo v0.0.1 ([ROOT]/foo/target/package/foo-0.0.1)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[UPLOADING] foo v0.0.1 ([ROOT]/foo)
[UPLOADED] foo v0.0.1 to registry [..]
[NOTE] waiting for foo v0.0.1 to be available at registry [..]
[HELP] you may press ctrl-c to skip waiting; the crate should be available shortly
[PUBLISHED] foo v0.0.1 at registry [..]
"#]])
.run();
}

#[cargo_test]
fn publish_failed_with_index_and_only_allowed_registry() {
let registry = RegistryBuilder::new()
Expand Down Expand Up @@ -1014,6 +1068,7 @@ fn publish_failed_with_index_and_only_allowed_registry() {
.arg(registry.index_url().as_str())
.with_status(101)
.with_stderr_data(str![[r#"
...
[ERROR] command-line argument --index requires --token to be specified

"#]])
Expand Down