From: Chris Swindle Date: Wed, 1 Nov 2017 22:14:33 +0000 (+0000) Subject: Include registry in dependencies in the index. X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~5^2~1^2~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=ef4a920425016fde172216fae7afa7801c821c9b;p=cargo.git Include registry in dependencies in the index. --- diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 955ecca21..e7b430894 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -44,6 +44,8 @@ enum Kind { Path, /// represents a remote registry Registry, + /// represents a remote alternative registry + AltRegistry, /// represents a local filesystem-based registry LocalRegistry, /// represents a directory-based registry @@ -148,6 +150,11 @@ impl SourceId { SourceId::new(Kind::Registry, url.clone()) } + /// Create a SourceId from an alternative registry url + pub fn for_alt_registry(url: &Url) -> CargoResult { + SourceId::new(Kind::AltRegistry, url.clone()) + } + /// Create a SourceId from a local registry path pub fn for_local_registry(path: &Path) -> CargoResult { let url = path.to_url()?; @@ -186,7 +193,7 @@ impl SourceId { let url = config.get_registry_index(key)?; Ok(SourceId { inner: Arc::new(SourceIdInner { - kind: Kind::Registry, + kind: Kind::AltRegistry, canonical_url: git::canonicalize_url(&url)?, url: url, precise: None, @@ -211,11 +218,16 @@ impl SourceId { /// Is this source from a registry (either local or not) pub fn is_registry(&self) -> bool { match self.inner.kind { - Kind::Registry | Kind::LocalRegistry => true, - _ => false, + Kind::Registry | Kind::AltRegistry | Kind::LocalRegistry => true, + _ => false, } } + /// Is this source from an alternative registry + pub fn is_alt_registry(&self) -> bool { + self.inner.kind == Kind::AltRegistry + } + /// Is this source from a git repository pub fn is_git(&self) -> bool { match self.inner.kind { @@ -236,7 +248,7 @@ impl SourceId { }; Ok(Box::new(PathSource::new(&path, self, config))) } - Kind::Registry => Ok(Box::new(RegistrySource::remote(self, config))), + Kind::Registry | Kind::AltRegistry => Ok(Box::new(RegistrySource::remote(self, config))), Kind::LocalRegistry => { let path = match self.inner.url.to_file_path() { Ok(p) => p, @@ -361,6 +373,7 @@ impl fmt::Display for SourceId { Ok(()) } SourceIdInner { kind: Kind::Registry, ref url, .. } | + SourceIdInner { kind: Kind::AltRegistry, ref url, .. } | SourceIdInner { kind: Kind::LocalRegistry, ref url, .. } => { write!(f, "registry `{}`", url) } @@ -458,7 +471,8 @@ impl<'a> fmt::Display for SourceIdToUrl<'a> { } Ok(()) } - SourceIdInner { kind: Kind::Registry, ref url, .. } => { + SourceIdInner { kind: Kind::Registry, ref url, .. } | + SourceIdInner { kind: Kind::AltRegistry, ref url, .. } => { write!(f, "registry+{}", url) } SourceIdInner { kind: Kind::LocalRegistry, ref url, .. } => { diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index a7e8ef82b..9b536b21d 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -74,7 +74,7 @@ pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> { // Upload said tarball to the specified destination opts.config.shell().status("Uploading", pkg.package_id().to_string())?; - transmit(opts.config, pkg, tarball.file(), &mut registry, opts.dry_run)?; + transmit(opts.config, pkg, tarball.file(), &mut registry, ®_id, opts.dry_run)?; Ok(()) } @@ -90,10 +90,14 @@ fn verify_dependencies(pkg: &Package, registry_src: &SourceId) } } else if dep.source_id() != registry_src { if dep.source_id().is_registry() { - 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 {}", dep.name(), dep.name(), dep.source_id()); + // Block requests to send to a registry if it is not an alternative + // registry + if !registry_src.is_alt_registry() { + 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 {}", dep.name(), dep.name(), dep.source_id()); + } } else { bail!("crates cannot be published to crates.io with dependencies sourced from \ a repository\neither publish `{}` as its own crate on crates.io and \ @@ -110,8 +114,19 @@ fn transmit(config: &Config, pkg: &Package, tarball: &File, registry: &mut Registry, + registry_id: &SourceId, dry_run: bool) -> CargoResult<()> { + let deps = pkg.dependencies().iter().map(|dep| { + + // If the dependency is from a different registry, then include the + // registry in the dependency. + let dep_registry = if dep.source_id() != registry_id { + Some(dep.source_id().url().to_string()) + } else { + None + }; + NewCrateDependency { optional: dep.is_optional(), default_features: dep.uses_default_features(), @@ -124,6 +139,7 @@ fn transmit(config: &Config, Kind::Build => "build", Kind::Development => "dev", }.to_string(), + registry: dep_registry, } }).collect::>(); let manifest = pkg.manifest(); @@ -226,9 +242,10 @@ pub fn registry(config: &Config, index: index_config, } = registry_configuration(config, registry.clone())?; let token = token.or(token_config); - let sid = match (index_config, index) { - (Some(index), _) | (None, Some(index)) => SourceId::for_registry(&index.to_url()?)?, - (None, None) => SourceId::crates_io(config)?, + let sid = match (index_config, index, registry) { + (Some(index), _, Some(_registry)) => SourceId::for_alt_registry(&index.to_url()?)?, + (Some(index), _, _) | (None, Some(index), _) => SourceId::for_registry(&index.to_url()?)?, + (None, None, _) => SourceId::crates_io(config)?, }; let api_host = { let mut src = RegistrySource::remote(&sid, config); diff --git a/src/crates-io/lib.rs b/src/crates-io/lib.rs index 4ccfea2d8..9645be81a 100644 --- a/src/crates-io/lib.rs +++ b/src/crates-io/lib.rs @@ -100,6 +100,8 @@ pub struct NewCrateDependency { pub version_req: String, pub target: Option, pub kind: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub registry: Option, } #[derive(Deserialize)] diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index 42770296e..45ef21535 100644 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -65,11 +65,13 @@ fn depend_on_alt_registry() { // Don't download a second time assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(0).with_stderr(&format!("\ +[UPDATING] registry `{reg}` [COMPILING] bar v0.0.1 (registry `file://[..]`) [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs ", - dir = p.url()))); + dir = p.url(), + reg = registry::alt_registry()))); } #[test] @@ -91,7 +93,7 @@ fn depend_on_alt_registry_depends_on_same_registry() { .build(); Package::new("baz", "0.0.1").alternative(true).publish(); - Package::new("bar", "0.0.1").registry_dep("baz", "0.0.1", registry::alt_registry().as_str()).alternative(true).publish(); + Package::new("bar", "0.0.1").dep("baz", "0.0.1").alternative(true).publish(); assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(0).with_stderr(&format!("\ @@ -107,7 +109,6 @@ fn depend_on_alt_registry_depends_on_same_registry() { reg = registry::alt_registry()))); } - #[test] fn depend_on_alt_registry_depends_on_crates_io() { let p = project("foo") @@ -192,7 +193,7 @@ fn registry_incompatible_with_git() { } #[test] -fn cannot_publish_with_registry_dependency() { +fn publish_with_registry_dependency() { let p = project("foo") .file("Cargo.toml", r#" cargo-features = ["alternative-registries"] @@ -211,9 +212,14 @@ fn cannot_publish_with_registry_dependency() { Package::new("bar", "0.0.1").alternative(true).publish(); + // Login so that we have the token available + assert_that(p.cargo("login").masquerade_as_nightly_cargo() + .arg("--registry").arg("alternative").arg("TOKEN").arg("-Zunstable-options"), + execs().with_status(0)); + assert_that(p.cargo("publish").masquerade_as_nightly_cargo() - .arg("--index").arg(registry::alt_registry().to_string()), - execs().with_status(101)); + .arg("--registry").arg("alternative").arg("-Zunstable-options"), + execs().with_status(0)); } #[test] @@ -288,6 +294,8 @@ fn block_publish_due_to_no_token() { fn publish_to_alt_registry() { let p = project("foo") .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + [project] name = "foo" version = "0.0.1" @@ -301,7 +309,7 @@ fn publish_to_alt_registry() { // Login so that we have the token available assert_that(p.cargo("login").masquerade_as_nightly_cargo() - .arg("--registry").arg("alternative").arg("TOKEN").arg("-Zunstable-options"), + .arg("--registry").arg("alternative").arg("TOKEN").arg("-Zunstable-options"), execs().with_status(0)); // Now perform the actual publish @@ -312,3 +320,34 @@ fn publish_to_alt_registry() { // Ensure that the crate is uploaded assert!(alt_dl_path().join("api/v1/crates/new").exists()); } + +#[test] +fn publish_with_crates_io_dep() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = ["me"] + license = "MIT" + description = "foo" + + [dependencies.bar] + version = "0.0.1" + "#) + .file("src/main.rs", "fn main() {}") + .build(); + + Package::new("bar", "0.0.1").publish(); + + // Login so that we have the token available + assert_that(p.cargo("login").masquerade_as_nightly_cargo() + .arg("--registry").arg("alternative").arg("TOKEN").arg("-Zunstable-options"), + execs().with_status(0)); + + assert_that(p.cargo("publish").masquerade_as_nightly_cargo() + .arg("--registry").arg("alternative").arg("-Zunstable-options"), + execs().with_status(0)); +}