diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index 1187def1db4..1f327d75409 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -210,7 +210,10 @@ impl Package { pub fn authors(&self) -> &Vec { &self.manifest().metadata().authors } - /// Returns `true` if the package is set to publish. + + /// Returns `None` if the package is set to publish. + /// Returns `Some(allowed_registries)` if publishing is limited to specified + /// registries or if package is set to not publish. pub fn publish(&self) -> &Option> { self.manifest().publish() } diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index c7cb078045b..438af777cdf 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -52,10 +52,25 @@ pub struct PublishOpts<'cfg> { pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { let pkg = ws.current()?; + let mut publish_registry = opts.registry.clone(); if let Some(ref allowed_registries) = *pkg.publish() { - let reg_name = opts - .registry + if publish_registry.is_none() && allowed_registries.len() == 1 { + // If there is only one allowed registry, push to that one directly, + // even though there is no registry specified in the command. + let default_registry = &allowed_registries[0]; + if default_registry != CRATES_IO_REGISTRY { + // Don't change the registry for crates.io and don't warn the user. + // crates.io will be defaulted even without this. + opts.config.shell().note(&format!( + "Found `{}` as only allowed registry. Publishing to it automatically.", + default_registry + ))?; + publish_registry = Some(default_registry.clone()); + } + } + + let reg_name = publish_registry .clone() .unwrap_or_else(|| CRATES_IO_REGISTRY.to_string()); if !allowed_registries.contains(®_name) { @@ -72,7 +87,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { opts.config, opts.token.clone(), opts.index.clone(), - opts.registry.clone(), + publish_registry, true, !opts.dry_run, )?; diff --git a/src/doc/man/cargo-publish.md b/src/doc/man/cargo-publish.md index 8267a8d4888..f3010f397c5 100644 --- a/src/doc/man/cargo-publish.md +++ b/src/doc/man/cargo-publish.md @@ -51,7 +51,15 @@ Allow working directories with uncommitted VCS changes to be packaged. {{> options-index }} -{{> options-registry }} +{{#option "`--registry` _registry_"}} +Name of the registry to publish to. Registry names are defined in [Cargo +config files](../reference/config.html). If not specified, and there is a +[`package.publish`](../reference/manifest.html#the-publish-field) field in +`Cargo.toml` with a single registry, then it will publish to that registry. +Otherwise it will use the default registry, which is defined by the +[`registry.default`](../reference/config.html#registry-default) config key +which defaults to `crates-io`. +{{/option}} {{/options}} diff --git a/src/doc/man/generated_txt/cargo-publish.txt b/src/doc/man/generated_txt/cargo-publish.txt index ed9234a984a..5e82aa6edf8 100644 --- a/src/doc/man/generated_txt/cargo-publish.txt +++ b/src/doc/man/generated_txt/cargo-publish.txt @@ -56,11 +56,16 @@ OPTIONS The URL of the registry index to use. --registry registry - Name of the registry to use. Registry names are defined in Cargo - config files + Name of the registry to publish to. Registry names are defined in + Cargo config files . If not - specified, the default registry is used, which is defined by the - registry.default config key which defaults to crates-io. + specified, and there is a package.publish + + field in Cargo.toml with a single registry, then it will publish to + that registry. Otherwise it will use the default registry, which is + defined by the registry.default + + config key which defaults to crates-io. Compilation Options --target triple diff --git a/src/doc/src/commands/cargo-publish.md b/src/doc/src/commands/cargo-publish.md index f881c32977e..3778b9edde4 100644 --- a/src/doc/src/commands/cargo-publish.md +++ b/src/doc/src/commands/cargo-publish.md @@ -65,11 +65,13 @@ of the registry in all capital letters.
--registry registry
-
Name of the registry to use. Registry names are defined in Cargo config -files. If not specified, the default registry is used, -which is defined by the registry.default config key which defaults to -crates-io.
- +
Name of the registry to publish to. Registry names are defined in Cargo +config files. If not specified, and there is a +package.publish field in +Cargo.toml with a single registry, then it will publish to that registry. +Otherwise it will use the default registry, which is defined by the +registry.default config key +which defaults to crates-io.
diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md index bac6093f46a..853ffc3c273 100644 --- a/src/doc/src/reference/manifest.md +++ b/src/doc/src/reference/manifest.md @@ -406,6 +406,9 @@ allowed to be published to. publish = ["some-registry-name"] ``` +If publish array contains a single registry, `cargo publish` command will use +it when `--registry` flag is not specified. + #### The `metadata` table diff --git a/src/etc/man/cargo-publish.1 b/src/etc/man/cargo-publish.1 index 1bac92f5ef2..7a8b3d64d03 100644 --- a/src/etc/man/cargo-publish.1 +++ b/src/etc/man/cargo-publish.1 @@ -74,10 +74,13 @@ The URL of the registry index to use. .sp \fB\-\-registry\fR \fIregistry\fR .RS 4 -Name of the registry to use. Registry names are defined in \fICargo config -files\fR \&. If not specified, the default registry is used, -which is defined by the \fBregistry.default\fR config key which defaults to -\fBcrates\-io\fR\&. +Name of the registry to publish to. Registry names are defined in \fICargo +config files\fR \&. If not specified, and there is a +\fI\f(BIpackage.publish\fI\fR field in +\fBCargo.toml\fR with a single registry, then it will publish to that registry. +Otherwise it will use the default registry, which is defined by the +\fI\f(BIregistry.default\fI\fR config key +which defaults to \fBcrates\-io\fR\&. .RE .SS "Compilation Options" .sp diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index 0cc165e395a..502f13c6bb2 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -715,6 +715,82 @@ fn publish_allowed_registry() { ); } +#[cargo_test] +fn publish_implicitly_to_only_allowed_registry() { + registry::init(); + + let p = project().build(); + + let _ = repo(&paths::root().join("foo")) + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + publish = ["alternative"] + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("publish").run(); + + publish::validate_alt_upload( + CLEAN_FOO_JSON, + "foo-0.0.1.crate", + &[ + "Cargo.lock", + "Cargo.toml", + "Cargo.toml.orig", + "src/main.rs", + ".cargo_vcs_info.json", + ], + ); +} + +#[cargo_test] +fn publish_fail_with_no_registry_specified() { + registry::init(); + + let p = project().build(); + + let _ = repo(&paths::root().join("foo")) + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + publish = ["alternative", "test"] + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("publish") + .with_status(101) + .with_stderr( + "\ +[ERROR] `foo` cannot be published. +The registry `crates-io` is not listed in the `publish` value in Cargo.toml. +", + ) + .run(); +} + #[cargo_test] fn block_publish_no_registry() { registry::init();