Skip to content

Commit

Permalink
Improve error message for publish key restriction.
Browse files Browse the repository at this point in the history
The existing error message didn't really recognize that `publish` can be a
list.

This also adds support for `publish = ["crates-io"]` to restrict publishing
to crates.io only.
  • Loading branch information
ehuss committed Apr 11, 2019
1 parent 449411f commit bf23a7e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 28 deletions.
43 changes: 23 additions & 20 deletions src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{cmp, env};

use crates_io::{NewCrate, NewCrateDependency, Registry};
use curl::easy::{Easy, InfoType, SslOpt};
use failure::{bail, format_err};
use log::{log, Level};
use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET};

Expand All @@ -16,7 +17,7 @@ use crate::core::manifest::ManifestMetadata;
use crate::core::source::Source;
use crate::core::{Package, SourceId, Workspace};
use crate::ops;
use crate::sources::{RegistrySource, SourceConfigMap};
use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_REGISTRY};
use crate::util::config::{self, Config};
use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::important_paths::find_root_manifest_for_wd;
Expand Down Expand Up @@ -48,14 +49,16 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
let pkg = ws.current()?;

if let Some(ref allowed_registries) = *pkg.publish() {
if !match opts.registry {
Some(ref registry) => allowed_registries.contains(registry),
None => false,
} {
failure::bail!(
"some crates cannot be published.\n\
`{}` is marked as unpublishable",
pkg.name()
let reg_name = opts
.registry
.clone()
.unwrap_or_else(|| CRATES_IO_REGISTRY.to_string());
if !allowed_registries.contains(&reg_name) {
bail!(
"`{}` cannot be published.\n\
The registry `{}` is not listed in the `publish` value in Cargo.toml.",
pkg.name(),
reg_name
);
}
}
Expand Down Expand Up @@ -112,7 +115,7 @@ fn verify_dependencies(
for dep in pkg.dependencies().iter() {
if dep.source_id().is_path() {
if !dep.specified_req() {
failure::bail!(
bail!(
"all path dependencies must have a version specified \
when publishing.\ndependency `{}` does not specify \
a version",
Expand All @@ -131,7 +134,7 @@ fn verify_dependencies(
.map(|u| u.host_str() == Some("crates.io"))
.unwrap_or(false);
if registry_src.is_default_registry() || is_crates_io {
failure::bail!("crates cannot be published to crates.io with dependencies sourced from other\n\
bail!("crates cannot be published to crates.io with dependencies sourced from other\n\
registries either publish `{}` on crates.io or pull it into this repository\n\
and specify it with a path and version\n\
(crate `{}` is pulled from {})",
Expand All @@ -140,7 +143,7 @@ fn verify_dependencies(
dep.source_id());
}
} else {
failure::bail!(
bail!(
"crates cannot be published with dependencies sourced from \
a repository\neither publish `{}` as its own crate and \
specify a version as a dependency or pull it into this \
Expand Down Expand Up @@ -221,7 +224,7 @@ fn transmit(
};
if let Some(ref file) = *license_file {
if fs::metadata(&pkg.root().join(file)).is_err() {
failure::bail!("the license file `{}` does not exist", file)
bail!("the license file `{}` does not exist", file)
}
}

Expand Down Expand Up @@ -357,7 +360,7 @@ pub fn registry(
cfg.unwrap()
};
cfg.and_then(|cfg| cfg.api)
.ok_or_else(|| failure::format_err!("{} does not support API commands", sid))?
.ok_or_else(|| format_err!("{} does not support API commands", sid))?
};
let handle = http_handle(config)?;
Ok((Registry::new_handle(api_host, token, handle), sid))
Expand All @@ -372,13 +375,13 @@ pub fn http_handle(config: &Config) -> CargoResult<Easy> {

pub fn http_handle_and_timeout(config: &Config) -> CargoResult<(Easy, HttpTimeout)> {
if config.frozen() {
failure::bail!(
bail!(
"attempting to make an HTTP request, but --frozen was \
specified"
)
}
if !config.network_allowed() {
failure::bail!("can't make HTTP request in the offline mode")
bail!("can't make HTTP request in the offline mode")
}

// The timeout option for libcurl by default times out the entire transfer,
Expand Down Expand Up @@ -605,9 +608,9 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {

if let Some(ref v) = opts.to_add {
let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
let msg = registry.add_owners(&name, &v).map_err(|e| {
failure::format_err!("failed to invite owners to crate {}: {}", name, e)
})?;
let msg = registry
.add_owners(&name, &v)
.map_err(|e| format_err!("failed to invite owners to crate {}: {}", name, e))?;

config.shell().status("Owner", msg)?;
}
Expand Down Expand Up @@ -658,7 +661,7 @@ pub fn yank(
};
let version = match version {
Some(v) => v,
None => failure::bail!("a version must be specified to yank"),
None => bail!("a version must be specified to yank"),
};

let (mut registry, _) = registry(config, token, index, reg, true)?;
Expand Down
50 changes: 42 additions & 8 deletions tests/testsuite/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,8 @@ fn unpublishable_crate() {
.with_status(101)
.with_stderr(
"\
[ERROR] some crates cannot be published.
`foo` is marked as unpublishable
[ERROR] `foo` cannot be published.
The registry `crates-io` is not listed in the `publish` value in Cargo.toml.
",
)
.run();
Expand Down Expand Up @@ -644,8 +644,8 @@ fn registry_not_in_publish_list() {
.with_status(101)
.with_stderr(
"\
[ERROR] some crates cannot be published.
`foo` is marked as unpublishable
[ERROR] `foo` cannot be published.
The registry `alternative` is not listed in the `publish` value in Cargo.toml.
",
)
.run();
Expand Down Expand Up @@ -675,8 +675,8 @@ fn publish_empty_list() {
.with_status(101)
.with_stderr(
"\
[ERROR] some crates cannot be published.
`foo` is marked as unpublishable
[ERROR] `foo` cannot be published.
The registry `alternative` is not listed in the `publish` value in Cargo.toml.
",
)
.run();
Expand Down Expand Up @@ -745,13 +745,47 @@ fn block_publish_no_registry() {
.with_status(101)
.with_stderr(
"\
[ERROR] some crates cannot be published.
`foo` is marked as unpublishable
[ERROR] `foo` cannot be published.
The registry `alternative` is not listed in the `publish` value in Cargo.toml.
",
)
.run();
}

#[test]
fn publish_with_crates_io_explicit() {
// Explicitly setting `crates-io` in the publish list.
registry::init();

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.0.1"
authors = []
license = "MIT"
description = "foo"
publish = ["crates-io"]
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr(
"\
[ERROR] `foo` cannot be published.
The registry `alternative` is not listed in the `publish` value in Cargo.toml.
",
)
.run();

p.cargo("publish").run();
}

#[test]
fn publish_with_select_features() {
registry::init();
Expand Down

0 comments on commit bf23a7e

Please sign in to comment.