diff --git a/src/cargo/ops/registry/publish.rs b/src/cargo/ops/registry/publish.rs index 16c0348be65..1abd00a4330 100644 --- a/src/cargo/ops/registry/publish.rs +++ b/src/cargo/ops/registry/publish.rs @@ -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)) = ® { - 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. @@ -814,6 +795,46 @@ fn package_list(pkgs: impl IntoIterator, final_sep: &str) -> S } } +fn resolve_registry_or_index( + opts: &PublishOpts<'_>, + just_pkgs: &[&Package], +) -> CargoResult> { + 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)) = ® { + 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()), diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index cbe36d6d83c..aeba4cebf13 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -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() @@ -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 "#]])