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

publish: rework the crates.io detection logic. #6525

Merged
merged 1 commit into from
Jan 6, 2019
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
7 changes: 0 additions & 7 deletions src/cargo/core/source/source_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,6 @@ impl SourceId {
}
}

/// Is this source from an alternative registry
/// DEPRECATED: This is not correct if the registry name is not known
/// (for example when loaded from an index).
pub fn is_alt_registry(self) -> bool {
self.is_registry() && self.inner.name.is_some()
}

/// Is this source from a git repository
pub fn is_git(self) -> bool {
match self.inner.kind {
Expand Down
27 changes: 19 additions & 8 deletions src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
opts.registry.clone(),
true,
)?;
verify_dependencies(pkg, reg_id)?;
verify_dependencies(pkg, &registry, reg_id)?;

// Prepare a tarball, with a non-surpressable warning if metadata
// is missing since this is being put online.
Expand Down Expand Up @@ -102,7 +102,11 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
Ok(())
}

fn verify_dependencies(pkg: &Package, registry_src: SourceId) -> CargoResult<()> {
fn verify_dependencies(
pkg: &Package,
registry: &Registry,
registry_src: SourceId,
) -> CargoResult<()> {
for dep in pkg.dependencies().iter() {
if dep.source_id().is_path() {
if !dep.specified_req() {
Expand All @@ -115,9 +119,16 @@ fn verify_dependencies(pkg: &Package, registry_src: SourceId) -> CargoResult<()>
}
} else if dep.source_id() != registry_src {
if dep.source_id().is_registry() {
// Block requests to send to a registry if it is not an alternative
// registry
if !registry_src.is_alt_registry() {
// Block requests to send to crates.io with alt-registry deps.
// This extra hostname check is mostly to assist with testing,
// but also prevents someone using `--index` to specify
// something that points to crates.io.
let is_crates_io = registry
.host()
.to_url()
.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\
registries either publish `{}` on crates.io or pull it into this repository\n\
and specify it with a path and version\n\
Expand All @@ -128,9 +139,9 @@ fn verify_dependencies(pkg: &Package, registry_src: SourceId) -> CargoResult<()>
}
} else {
failure::bail!(
"crates cannot be published to crates.io with dependencies sourced from \
a repository\neither publish `{}` as its own crate on crates.io and \
specify a crates.io version as a dependency or pull it into this \
"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 \
repository and specify it with a path and version\n(crate `{}` has \
repository path `{}`)",
dep.package_name(),
Expand Down
32 changes: 31 additions & 1 deletion tests/testsuite/alt_registry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::support::publish::validate_alt_upload;
use crate::support::registry::{self, Package};
use crate::support::{basic_manifest, git, paths, project};
use cargo::util::ToUrl;
use std::fs::{self, File};
use std::io::Write;

Expand Down Expand Up @@ -288,6 +289,8 @@ fn registry_incompatible_with_git() {

#[test]
fn cannot_publish_to_crates_io_with_registry_dependency() {
let fakeio_path = paths::root().join("fake.io");
let fakeio_url = fakeio_path.to_url().unwrap();
let p = project()
.file(
"Cargo.toml",
Expand All @@ -303,12 +306,39 @@ fn cannot_publish_to_crates_io_with_registry_dependency() {
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
".cargo/config",
&format!(
r#"
[registries.fakeio]
index = "{}"
"#,
fakeio_url
),
)
.build();

Package::new("bar", "0.0.1").alternative(true).publish();

// Since this can't really call plain `publish` without fetching the real
// crates.io index, create a fake one that points to the real crates.io.
git::repo(&fakeio_path)
.file(
"config.json",
r#"
{"dl": "https://crates.io/api/v1/crates", "api": "https://crates.io"}
"#,
)
.build();

p.cargo("publish --registry fakeio -Z unstable-options")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr_contains("[ERROR] crates cannot be published to crates.io[..]")
.run();

p.cargo("publish --index")
.arg(registry::registry().to_string())
.arg(fakeio_url.to_string())
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr_contains("[ERROR] crates cannot be published to crates.io[..]")
Expand Down
6 changes: 3 additions & 3 deletions tests/testsuite/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ fn git_deps() {
.with_stderr(
"\
[UPDATING] [..] index
[ERROR] crates cannot be published to crates.io with dependencies sourced from \
a repository\neither publish `foo` as its own crate on crates.io and \
specify a crates.io version as a dependency or pull it into this \
[ERROR] crates cannot be published with dependencies sourced from \
a repository\neither publish `foo` as its own crate and \
specify a version as a dependency or pull it into this \
repository and specify it with a path and version\n\
(crate `foo` has repository path `git://path/to/nowhere`)\
",
Expand Down