From d89cd9037ed46438e5c694782bc6230a9db61232 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Tue, 29 Aug 2017 22:55:31 -0700 Subject: [PATCH 01/13] Alternate registries. Allow users to add dependencies which are in alternate registries. The alternate registries are listed in the .cargo/config, and must there have a link to a conforming crate index. --- src/bin/login.rs | 2 +- src/cargo/core/features.rs | 5 +- src/cargo/core/source/mod.rs | 157 ++++++++++++ .../core/{source.rs => source/source_id.rs} | 225 +++++------------- src/cargo/ops/registry.rs | 19 +- src/cargo/sources/registry/mod.rs | 2 +- src/cargo/sources/registry/remote.rs | 3 +- src/cargo/util/config.rs | 2 +- src/cargo/util/toml/mod.rs | 30 ++- tests/alt-registry.rs | 145 +++++++++++ tests/bad-config.rs | 6 +- tests/cargotest/support/registry.rs | 30 ++- 12 files changed, 429 insertions(+), 197 deletions(-) create mode 100644 src/cargo/core/source/mod.rs rename src/cargo/core/{source.rs => source/source_id.rs} (76%) create mode 100644 tests/alt-registry.rs diff --git a/src/bin/login.rs b/src/bin/login.rs index c41118cc350..5e8e0e2db96 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -51,7 +51,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult { let mut src = RegistrySource::remote(&src, config); src.update()?; let config = src.config()?.unwrap(); - let host = options.flag_host.clone().unwrap_or(config.api); + let host = options.flag_host.clone().unwrap_or(config.api.unwrap()); println!("please visit {}me and paste the API Token below", host); let mut line = String::new(); let input = io::stdin(); diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 4bfafc174dd..d4e91c01013 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -31,7 +31,7 @@ //! })?; //! ``` //! -//! Notably you'll notice the `require` funciton called with your `Feature`, and +//! Notably you'll notice the `require` function called with your `Feature`, and //! then you use `chain_err` to tack on more context for why the feature was //! required when the feature isn't activated. //! @@ -122,6 +122,9 @@ features! { // A dummy feature that gates the usage of the `im-a-teapot` manifest // entry. This is basically just intended for tests. [unstable] test_dummy_unstable: bool, + + // Downloading packages from alternative registry indexes. + [unstable] alternative_registries: bool, } } diff --git a/src/cargo/core/source/mod.rs b/src/cargo/core/source/mod.rs new file mode 100644 index 00000000000..bc54fa1848f --- /dev/null +++ b/src/cargo/core/source/mod.rs @@ -0,0 +1,157 @@ +use std::collections::hash_map::{HashMap, Values, IterMut}; + +use core::{Package, PackageId, Registry}; +use util::CargoResult; + +mod source_id; + +pub use self::source_id::{SourceId, GitReference}; + +/// A Source finds and downloads remote packages based on names and +/// versions. +pub trait Source: Registry { + /// Returns the `SourceId` corresponding to this source + fn source_id(&self) -> &SourceId; + + /// The update method performs any network operations required to + /// get the entire list of all names, versions and dependencies of + /// packages managed by the Source. + fn update(&mut self) -> CargoResult<()>; + + /// The download method fetches the full package for each name and + /// version specified. + fn download(&mut self, package: &PackageId) -> CargoResult; + + /// Generates a unique string which represents the fingerprint of the + /// current state of the source. + /// + /// This fingerprint is used to determine the "fresheness" of the source + /// later on. It must be guaranteed that the fingerprint of a source is + /// constant if and only if the output product will remain constant. + /// + /// The `pkg` argument is the package which this fingerprint should only be + /// interested in for when this source may contain multiple packages. + fn fingerprint(&self, pkg: &Package) -> CargoResult; + + /// If this source supports it, verifies the source of the package + /// specified. + /// + /// Note that the source may also have performed other checksum-based + /// verification during the `download` step, but this is intended to be run + /// just before a crate is compiled so it may perform more expensive checks + /// which may not be cacheable. + fn verify(&self, _pkg: &PackageId) -> CargoResult<()> { + Ok(()) + } +} + +impl<'a, T: Source + ?Sized + 'a> Source for Box { + /// Forwards to `Source::source_id` + fn source_id(&self) -> &SourceId { + (**self).source_id() + } + + /// Forwards to `Source::update` + fn update(&mut self) -> CargoResult<()> { + (**self).update() + } + + /// Forwards to `Source::download` + fn download(&mut self, id: &PackageId) -> CargoResult { + (**self).download(id) + } + + /// Forwards to `Source::fingerprint` + fn fingerprint(&self, pkg: &Package) -> CargoResult { + (**self).fingerprint(pkg) + } + + /// Forwards to `Source::verify` + fn verify(&self, pkg: &PackageId) -> CargoResult<()> { + (**self).verify(pkg) + } +} + +/// A `HashMap` of `SourceId` -> `Box` +#[derive(Default)] +pub struct SourceMap<'src> { + map: HashMap>, +} + +/// A `std::collection::hash_map::Values` for `SourceMap` +pub type Sources<'a, 'src> = Values<'a, SourceId, Box>; + +/// A `std::collection::hash_map::IterMut` for `SourceMap` +pub struct SourcesMut<'a, 'src: 'a> { + inner: IterMut<'a, SourceId, Box>, +} + +impl<'src> SourceMap<'src> { + /// Create an empty map + pub fn new() -> SourceMap<'src> { + SourceMap { map: HashMap::new() } + } + + /// Like `HashMap::contains_key` + pub fn contains(&self, id: &SourceId) -> bool { + self.map.contains_key(id) + } + + /// Like `HashMap::get` + pub fn get(&self, id: &SourceId) -> Option<&(Source + 'src)> { + let source = self.map.get(id); + + source.map(|s| { + let s: &(Source + 'src) = &**s; + s + }) + } + + /// Like `HashMap::get_mut` + pub fn get_mut(&mut self, id: &SourceId) -> Option<&mut (Source + 'src)> { + self.map.get_mut(id).map(|s| { + let s: &mut (Source + 'src) = &mut **s; + s + }) + } + + /// Like `HashMap::get`, but first calculates the `SourceId` from a + /// `PackageId` + pub fn get_by_package_id(&self, pkg_id: &PackageId) -> Option<&(Source + 'src)> { + self.get(pkg_id.source_id()) + } + + /// Like `HashMap::insert`, but derives the SourceId key from the Source + pub fn insert(&mut self, source: Box) { + let id = source.source_id().clone(); + self.map.insert(id, source); + } + + /// Like `HashMap::is_empty` + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Like `HashMap::len` + pub fn len(&self) -> usize { + self.map.len() + } + + /// Like `HashMap::values` + pub fn sources<'a>(&'a self) -> Sources<'a, 'src> { + self.map.values() + } + + /// Like `HashMap::iter_mut` + pub fn sources_mut<'a>(&'a mut self) -> SourcesMut<'a, 'src> { + SourcesMut { inner: self.map.iter_mut() } + } +} + +impl<'a, 'src> Iterator for SourcesMut<'a, 'src> { + type Item = (&'a SourceId, &'a mut (Source + 'src)); + fn next(&mut self) -> Option<(&'a SourceId, &'a mut (Source + 'src))> { + self.inner.next().map(|(a, b)| (a, &mut **b)) + } +} + diff --git a/src/cargo/core/source.rs b/src/cargo/core/source/source_id.rs similarity index 76% rename from src/cargo/core/source.rs rename to src/cargo/core/source/source_id.rs index 01d65991908..1c37d31995d 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source/source_id.rs @@ -1,5 +1,4 @@ use std::cmp::{self, Ordering}; -use std::collections::hash_map::{HashMap, Values, IterMut}; use std::fmt::{self, Formatter}; use std::hash::{self, Hash}; use std::path::Path; @@ -11,76 +10,28 @@ use serde::ser; use serde::de; use url::Url; -use core::{Package, PackageId, Registry}; use ops; use sources::git; use sources::{PathSource, GitSource, RegistrySource, CRATES_IO}; use sources::DirectorySource; -use util::{Config, CargoResult, ToUrl}; +use util::{Config, ConfigValue as CV, CargoResult, ToUrl}; -/// A Source finds and downloads remote packages based on names and -/// versions. -pub trait Source: Registry { - /// Returns the `SourceId` corresponding to this source - fn source_id(&self) -> &SourceId; - - /// The update method performs any network operations required to - /// get the entire list of all names, versions and dependencies of - /// packages managed by the Source. - fn update(&mut self) -> CargoResult<()>; - - /// The download method fetches the full package for each name and - /// version specified. - fn download(&mut self, package: &PackageId) -> CargoResult; - - /// Generates a unique string which represents the fingerprint of the - /// current state of the source. - /// - /// This fingerprint is used to determine the "fresheness" of the source - /// later on. It must be guaranteed that the fingerprint of a source is - /// constant if and only if the output product will remain constant. - /// - /// The `pkg` argument is the package which this fingerprint should only be - /// interested in for when this source may contain multiple packages. - fn fingerprint(&self, pkg: &Package) -> CargoResult; - - /// If this source supports it, verifies the source of the package - /// specified. - /// - /// Note that the source may also have performed other checksum-based - /// verification during the `download` step, but this is intended to be run - /// just before a crate is compiled so it may perform more expensive checks - /// which may not be cacheable. - fn verify(&self, _pkg: &PackageId) -> CargoResult<()> { - Ok(()) - } +/// Unique identifier for a source of packages. +#[derive(Clone, Eq, Debug)] +pub struct SourceId { + inner: Arc, } -impl<'a, T: Source + ?Sized + 'a> Source for Box { - /// Forwards to `Source::source_id` - fn source_id(&self) -> &SourceId { - (**self).source_id() - } - - /// Forwards to `Source::update` - fn update(&mut self) -> CargoResult<()> { - (**self).update() - } - - /// Forwards to `Source::download` - fn download(&mut self, id: &PackageId) -> CargoResult { - (**self).download(id) - } - - /// Forwards to `Source::fingerprint` - fn fingerprint(&self, pkg: &Package) -> CargoResult { - (**self).fingerprint(pkg) - } - - /// Forwards to `Source::verify` - fn verify(&self, pkg: &PackageId) -> CargoResult<()> { - (**self).verify(pkg) - } +#[derive(Eq, Clone, Debug)] +struct SourceIdInner { + /// The source URL + url: Url, + /// `git::canonicalize_url(url)` for the url field + canonical_url: Url, + /// The source kind + kind: Kind, + // e.g. the exact git revision of the specified branch for a Git Source + precise: Option, } /// The possible kinds of code source. Along with a URL, this fully defines the @@ -91,7 +42,7 @@ enum Kind { Git(GitReference), /// represents a local path Path, - /// represents the central registry + /// represents a remote registry Registry, /// represents a local filesystem-based registry LocalRegistry, @@ -110,25 +61,6 @@ pub enum GitReference { Rev(String), } -/// Unique identifier for a source of packages. -#[derive(Clone, Eq, Debug)] -pub struct SourceId { - inner: Arc, -} - -/// Unique identifier for a source of packages. -#[derive(Eq, Clone, Debug)] -struct SourceIdInner { - /// The source URL - url: Url, - /// `git::canonicalize_url(url)` for the url field - canonical_url: Url, - /// The source kind - kind: Kind, - // e.g. the exact git revision of the specified branch for a Git Source - precise: Option, -} - impl SourceId { /// Create a SourceId object from the kind and url. /// @@ -250,11 +182,44 @@ impl SourceId { SourceId::for_registry(&url) } + pub fn alt_registry(config: &Config, key: &str) -> CargoResult { + let registries = config.get_table("registries")?; + match registries.as_ref().and_then(|registries| registries.val.get(key)) { + Some(registry) => { + let index = match *registry { + CV::Table(ref registry, _) => { + match registry.get("index") { + Some(index) => index.string(&format!("registries.{}", key))?.0, + None => return Err(format!("No index for registry `{}`", key).into()), + } + } + _ => registry.expected("table", &format!("registries.{}", key))? + }; + + let url = index.to_url()?; + + Ok(SourceId { + inner: Arc::new(SourceIdInner { + kind: Kind::Registry, + canonical_url: git::canonicalize_url(&url)?, + url: url, + precise: None, + }), + }) + } + None => Err(format!("Required unknown registry source: `{}`", key).into()) + } + } + /// Get this source URL pub fn url(&self) -> &Url { &self.inner.url } + pub fn display_registry(&self) -> String { + format!("registry `{}`", self.url()) + } + /// Is this source from a filesystem path pub fn is_path(&self) -> bool { self.inner.kind == Kind::Path @@ -262,7 +227,10 @@ impl SourceId { /// Is this source from a registry (either local or not) pub fn is_registry(&self) -> bool { - self.inner.kind == Kind::Registry || self.inner.kind == Kind::LocalRegistry + match self.inner.kind { + Kind::Registry | Kind::LocalRegistry => true, + _ => false, + } } /// Is this source from a git repository @@ -274,7 +242,7 @@ impl SourceId { } /// Creates an implementation of `Source` corresponding to this ID. - pub fn load<'a>(&self, config: &'a Config) -> CargoResult> { + pub fn load<'a>(&self, config: &'a Config) -> CargoResult> { trace!("loading SourceId; {}", self); match self.inner.kind { Kind::Git(..) => Ok(Box::new(GitSource::new(self, config)?)), @@ -411,7 +379,7 @@ impl fmt::Display for SourceId { } SourceIdInner { kind: Kind::Registry, ref url, .. } | SourceIdInner { kind: Kind::LocalRegistry, ref url, .. } => { - write!(f, "registry {}", url) + write!(f, "registry `{}`", url) } SourceIdInner { kind: Kind::Directory, ref url, .. } => { write!(f, "dir {}", url) @@ -546,89 +514,6 @@ impl<'a> fmt::Display for PrettyRef<'a> { } } -/// A `HashMap` of `SourceId` -> `Box` -#[derive(Default)] -pub struct SourceMap<'src> { - map: HashMap>, -} - -/// A `std::collection::hash_map::Values` for `SourceMap` -pub type Sources<'a, 'src> = Values<'a, SourceId, Box>; - -/// A `std::collection::hash_map::IterMut` for `SourceMap` -pub struct SourcesMut<'a, 'src: 'a> { - inner: IterMut<'a, SourceId, Box>, -} - -impl<'src> SourceMap<'src> { - /// Create an empty map - pub fn new() -> SourceMap<'src> { - SourceMap { map: HashMap::new() } - } - - /// Like `HashMap::contains_key` - pub fn contains(&self, id: &SourceId) -> bool { - self.map.contains_key(id) - } - - /// Like `HashMap::get` - pub fn get(&self, id: &SourceId) -> Option<&(Source + 'src)> { - let source = self.map.get(id); - - source.map(|s| { - let s: &(Source + 'src) = &**s; - s - }) - } - - /// Like `HashMap::get_mut` - pub fn get_mut(&mut self, id: &SourceId) -> Option<&mut (Source + 'src)> { - self.map.get_mut(id).map(|s| { - let s: &mut (Source + 'src) = &mut **s; - s - }) - } - - /// Like `HashMap::get`, but first calculates the `SourceId` from a - /// `PackageId` - pub fn get_by_package_id(&self, pkg_id: &PackageId) -> Option<&(Source + 'src)> { - self.get(pkg_id.source_id()) - } - - /// Like `HashMap::insert`, but derives the SourceId key from the Source - pub fn insert(&mut self, source: Box) { - let id = source.source_id().clone(); - self.map.insert(id, source); - } - - /// Like `HashMap::is_empty` - pub fn is_empty(&self) -> bool { - self.map.is_empty() - } - - /// Like `HashMap::len` - pub fn len(&self) -> usize { - self.map.len() - } - - /// Like `HashMap::values` - pub fn sources<'a>(&'a self) -> Sources<'a, 'src> { - self.map.values() - } - - /// Like `HashMap::iter_mut` - pub fn sources_mut<'a>(&'a mut self) -> SourcesMut<'a, 'src> { - SourcesMut { inner: self.map.iter_mut() } - } -} - -impl<'a, 'src> Iterator for SourcesMut<'a, 'src> { - type Item = (&'a SourceId, &'a mut (Source + 'src)); - fn next(&mut self) -> Option<(&'a SourceId, &'a mut (Source + 'src))> { - self.inner.next().map(|(a, b)| (a, &mut **b)) - } -} - #[cfg(test)] mod tests { use super::{SourceId, Kind, GitReference}; diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 42ff2f87207..4d21be92260 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -83,11 +83,18 @@ fn verify_dependencies(pkg: &Package, registry_src: &SourceId) a version", dep.name()) } } else if dep.source_id() != registry_src { - 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 \ - repository and specify it with a path and version\n(crate `{}` has \ - repository path `{}`)", dep.name(), dep.name(), dep.source_id()); + 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()); + } 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 \ + specify a crates.io version as a dependency or pull it into this \ + repository and specify it with a path and version\n(crate `{}` has \ + repository path `{}`)", dep.name(), dep.name(), dep.source_id()); + } } } Ok(()) @@ -205,7 +212,7 @@ pub fn registry(config: &Config, src.update().chain_err(|| { format!("failed to update {}", sid) })?; - (src.config()?).unwrap().api + (src.config()?).unwrap().api.unwrap() }; let handle = http_handle(config)?; Ok((Registry::new_handle(api_host, token, handle), sid)) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index c967e2ebcd3..8b907f7d33c 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -198,7 +198,7 @@ pub struct RegistryConfig { /// API endpoint for the registry. This is what's actually hit to perform /// operations like yanks, owner modifications, publish new crates, etc. - pub api: String, + pub api: Option, } #[derive(Deserialize)] diff --git a/src/cargo/sources/registry/remote.rs b/src/cargo/sources/registry/remote.rs index 6704282b897..84622610714 100644 --- a/src/cargo/sources/registry/remote.rs +++ b/src/cargo/sources/registry/remote.rs @@ -166,8 +166,7 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { let _lock = self.index_path.open_rw(Path::new(INDEX_LOCK), self.config, "the registry index")?; - self.config.shell().status("Updating", - format!("registry `{}`", self.source_id.url()))?; + self.config.shell().status("Updating", self.source_id.display_registry())?; // git fetch origin master let url = self.source_id.url(); diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 38e2e303fab..252d8cb01a2 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -762,7 +762,7 @@ impl ConfigValue { } } - fn expected(&self, wanted: &str, key: &str) -> CargoResult { + pub fn expected(&self, wanted: &str, key: &str) -> CargoResult { Err(format!("expected a {}, but found a {} for `{}` in {}", wanted, self.desc(), key, self.definition_path().display()).into()) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index c2220ac2d6e..487d46f93c9 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -14,7 +14,7 @@ use url::Url; use core::{SourceId, Profiles, PackageIdSpec, GitReference, WorkspaceConfig}; use core::{Summary, Manifest, Target, Dependency, PackageId}; -use core::{EitherManifest, VirtualManifest, Features}; +use core::{EitherManifest, VirtualManifest, Features, Feature}; use core::dependency::{Kind, Platform}; use core::manifest::{LibKind, Profile, ManifestMetadata}; use sources::CRATES_IO; @@ -184,6 +184,7 @@ impl<'de> de::Deserialize<'de> for TomlDependency { #[derive(Deserialize, Serialize, Clone, Debug, Default)] pub struct DetailedTomlDependency { version: Option, + registry: Option, path: Option, git: Option, branch: Option, @@ -429,6 +430,7 @@ struct Context<'a, 'b> { warnings: &'a mut Vec, platform: Option, root: &'a Path, + features: &'a Features, } impl TomlManifest { @@ -511,6 +513,11 @@ impl TomlManifest { let mut warnings = vec![]; let mut errors = vec![]; + // Parse features first so they will be available when parsing other parts of the toml + let empty = Vec::new(); + let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); + let features = Features::new(&cargo_features, &mut warnings)?; + let project = me.project.as_ref().or_else(|| me.package.as_ref()); let project = project.ok_or_else(|| { CargoError::from("no `package` or `project` section found.") @@ -551,6 +558,7 @@ impl TomlManifest { nested_paths: &mut nested_paths, config: config, warnings: &mut warnings, + features: &features, platform: None, root: package_root, }; @@ -649,9 +657,6 @@ impl TomlManifest { }; let profiles = build_profiles(&me.profile); let publish = project.publish.unwrap_or(true); - let empty = Vec::new(); - let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); - let features = Features::new(cargo_features, &mut warnings)?; let mut manifest = Manifest::new(summary, targets, exclude, @@ -721,6 +726,7 @@ impl TomlManifest { config: config, warnings: &mut warnings, platform: None, + features: &Features::default(), // @alex: is this right? root: root }; (me.replace(&mut cx)?, me.patch(&mut cx)?) @@ -867,8 +873,12 @@ impl TomlDependency { } } - let new_source_id = match (details.git.as_ref(), details.path.as_ref()) { - (Some(git), maybe_path) => { + let new_source_id = match (details.git.as_ref(), details.path.as_ref(), details.registry.as_ref()) { + (Some(_), _, Some(_)) => bail!("dependency ({}) specification is ambiguous. \ + Only one of `git` or `registry` is allowed.", name), + (_, Some(_), Some(_)) => bail!("dependency ({}) specification is ambiguous. \ + Only one of `path` or `registry` is allowed.", name), + (Some(git), maybe_path, _) => { if maybe_path.is_some() { let msg = format!("dependency ({}) specification is ambiguous. \ Only one of `git` or `path` is allowed. \ @@ -895,7 +905,7 @@ impl TomlDependency { let loc = git.to_url()?; SourceId::for_git(&loc, reference)? }, - (None, Some(path)) => { + (None, Some(path), _) => { cx.nested_paths.push(PathBuf::from(path)); // If the source id for the package we're parsing is a path // source, then we normalize the path here to get rid of @@ -913,7 +923,11 @@ impl TomlDependency { cx.source_id.clone() } }, - (None, None) => SourceId::crates_io(cx.config)?, + (None, None, Some(registry)) => { + cx.features.require(Feature::alternative_registries())?; + SourceId::alt_registry(cx.config, registry)? + } + (None, None, None) => SourceId::crates_io(cx.config)?, }; let version = details.version.as_ref().map(|v| &v[..]); diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs new file mode 100644 index 00000000000..9d701ba6b44 --- /dev/null +++ b/tests/alt-registry.rs @@ -0,0 +1,145 @@ +extern crate cargotest; +extern crate hamcrest; + +use cargotest::ChannelChanger; +use cargotest::support::registry::{self, Package}; +use cargotest::support::{project, execs}; +use hamcrest::assert_that; + +#[test] +fn is_feature_gated() { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("bar", "0.0.1").alternative(true).publish(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(101) + .with_stderr_contains(" feature `alternative-registries` is required")); +} + +#[test] +fn depend_on_alt_registry() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("bar", "0.0.1").alternative(true).publish(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(0).with_stderr(&format!("\ +[UPDATING] registry `{reg}` +[DOWNLOADING] bar v0.0.1 (registry `file://[..]`) +[COMPILING] bar v0.0.1 (registry `file://[..]`) +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs +", + dir = p.url(), + reg = registry::alt_registry()))); + + assert_that(p.cargo("clean").masquerade_as_nightly_cargo(), execs().with_status(0)); + + // Don't download a second time + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(0).with_stderr(&format!("\ +[COMPILING] bar v0.0.1 (registry `file://[..]`) +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs +", + dir = p.url()))); +} + +#[test] +fn registry_incompatible_with_path() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + path = "" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(101) + .with_stderr_contains(" dependency (bar) specification is ambiguous. Only one of `path` or `registry` is allowed.")); +} + +#[test] +fn registry_incompatible_with_git() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + git = "" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(101) + .with_stderr_contains(" dependency (bar) specification is ambiguous. Only one of `git` or `registry` is allowed.")); +} + + +#[test] +fn cannot_publish_with_registry_dependency() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("bar", "0.0.1").alternative(true).publish(); + + assert_that(p.cargo("publish").masquerade_as_nightly_cargo() + .arg("--index").arg(registry::alt_registry().to_string()), + execs().with_status(101)); +} diff --git a/tests/bad-config.rs b/tests/bad-config.rs index cff576dbb47..30746f0c917 100644 --- a/tests/bad-config.rs +++ b/tests/bad-config.rs @@ -794,7 +794,7 @@ fn bad_source_config2() { error: failed to load source for a dependency on `bar` Caused by: - Unable to update registry https://[..] + Unable to update registry `https://[..]` Caused by: could not find a configured source with the name `bar` \ @@ -826,7 +826,7 @@ fn bad_source_config3() { error: failed to load source for a dependency on `bar` Caused by: - Unable to update registry https://[..] + Unable to update registry `https://[..]` Caused by: detected a cycle of `replace-with` sources, [..] @@ -861,7 +861,7 @@ fn bad_source_config4() { error: failed to load source for a dependency on `bar` Caused by: - Unable to update registry https://[..] + Unable to update registry `https://[..]` Caused by: detected a cycle of `replace-with` sources, the source `crates-io` is \ diff --git a/tests/cargotest/support/registry.rs b/tests/cargotest/support/registry.rs index 3046d2e20c5..1e0b28cd025 100644 --- a/tests/cargotest/support/registry.rs +++ b/tests/cargotest/support/registry.rs @@ -18,6 +18,8 @@ pub fn registry_path() -> PathBuf { paths::root().join("registry") } pub fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() } pub fn dl_path() -> PathBuf { paths::root().join("dl") } pub fn dl_url() -> Url { Url::from_file_path(&*dl_path()).ok().unwrap() } +pub fn alt_registry_path() -> PathBuf { paths::root().join("alternative-registry") } +pub fn alt_registry() -> Url { Url::from_file_path(&*alt_registry_path()).ok().unwrap() } pub struct Package { name: String, @@ -28,6 +30,7 @@ pub struct Package { yanked: bool, features: HashMap>, local: bool, + alternative: bool, } struct Dependency { @@ -54,7 +57,10 @@ pub fn init() { [source.dummy-registry] registry = '{reg}' - "#, reg = registry()).as_bytes())); + + [registries.alternative] + index = '{alt}' + "#, reg = registry(), alt = alt_registry()).as_bytes())); // Init a new registry repo(®istry_path()) @@ -63,6 +69,14 @@ pub fn init() { "#, dl_url())) .build(); fs::create_dir_all(dl_path().join("api/v1/crates")).unwrap(); + + // Init an alt registry + repo(&alt_registry_path()) + .file("config.json", &format!(r#" + {{"dl":"{0}","api":"{0}"}} + "#, dl_url())) + .build(); + fs::create_dir_all(dl_path().join("api/v1/crates")).unwrap(); } impl Package { @@ -77,6 +91,7 @@ impl Package { yanked: false, features: HashMap::new(), local: false, + alternative: false, } } @@ -85,6 +100,11 @@ impl Package { self } + pub fn alternative(&mut self, alternative: bool) -> &mut Package { + self.alternative = alternative; + self + } + pub fn file(&mut self, name: &str, contents: &str) -> &mut Package { self.files.push((name.to_string(), contents.to_string())); self @@ -174,11 +194,13 @@ impl Package { _ => format!("{}/{}/{}", &self.name[0..2], &self.name[2..4], self.name), }; + let registry_path = if self.alternative { alt_registry_path() } else { registry_path() }; + // Write file/line in the index let dst = if self.local { - registry_path().join("index").join(&file) + registry_path.join("index").join(&file) } else { - registry_path().join(&file) + registry_path.join(&file) }; let mut prev = String::new(); let _ = File::open(&dst).and_then(|mut f| f.read_to_string(&mut prev)); @@ -188,7 +210,7 @@ impl Package { // Add the new file to the index if !self.local { - let repo = t!(git2::Repository::open(®istry_path())); + let repo = t!(git2::Repository::open(®istry_path)); let mut index = t!(repo.index()); t!(index.add_path(Path::new(&file))); t!(index.write()); From fb293fabfc0f4866fae3857c1b95c67fba42ce37 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Wed, 4 Oct 2017 13:36:04 -0700 Subject: [PATCH 02/13] Add backticks. --- tests/directory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/directory.rs b/tests/directory.rs index dab2dcdfbc5..72082029999 100644 --- a/tests/directory.rs +++ b/tests/directory.rs @@ -196,7 +196,7 @@ error: failed to compile `bar v0.1.0`, intermediate artifacts can be found at `[ Caused by: no matching package named `baz` found (required by `bar`) -location searched: registry https://github.com/rust-lang/crates.io-index +location searched: registry `https://github.com/rust-lang/crates.io-index` version required: ^9.8.7 ")); } From 8a70ffb03bd76a3235145668d91e660d317d8ef8 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Wed, 4 Oct 2017 15:07:01 -0700 Subject: [PATCH 03/13] Fix tests (to do with printing). --- src/cargo/ops/cargo_install.rs | 2 +- src/cargo/sources/replaced.rs | 6 ++--- tests/install.rs | 10 +++---- tests/local-registry.rs | 4 +-- tests/registry.rs | 48 +++++++++++++++++----------------- tests/resolve.rs | 2 +- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 12fe51c441e..4c88e8951f7 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -390,7 +390,7 @@ fn select_pkg<'a, T>(mut source: T, None => { let vers_info = vers.map(|v| format!(" with version `{}`", v)) .unwrap_or_default(); - Err(format!("could not find `{}` in `{}`{}", name, + Err(format!("could not find `{}` in {}{}", name, source.source_id(), vers_info).into()) } } diff --git a/src/cargo/sources/replaced.rs b/src/cargo/sources/replaced.rs index 5048f618661..88390614608 100644 --- a/src/cargo/sources/replaced.rs +++ b/src/cargo/sources/replaced.rs @@ -29,7 +29,7 @@ impl<'cfg> Registry for ReplacedSource<'cfg> { self.inner.query(&dep, &mut |summary| { f(summary.map_source(replace_with, to_replace)) }).chain_err(|| { - format!("failed to query replaced source `{}`", + format!("failed to query replaced source {}", self.to_replace) }) } @@ -50,7 +50,7 @@ impl<'cfg> Source for ReplacedSource<'cfg> { fn update(&mut self) -> CargoResult<()> { self.inner.update().chain_err(|| { - format!("failed to update replaced source `{}`", + format!("failed to update replaced source {}", self.to_replace) }) } @@ -58,7 +58,7 @@ impl<'cfg> Source for ReplacedSource<'cfg> { fn download(&mut self, id: &PackageId) -> CargoResult { let id = id.with_source_id(&self.replace_with); let pkg = self.inner.download(&id).chain_err(|| { - format!("failed to download replaced source `{}`", + format!("failed to download replaced source {}", self.to_replace) })?; Ok(pkg.map_source(&self.replace_with, &self.to_replace)) diff --git a/tests/install.rs b/tests/install.rs index 3ed4bf0d9a5..9e59f4c0a1e 100644 --- a/tests/install.rs +++ b/tests/install.rs @@ -62,17 +62,17 @@ fn multiple_pkgs() { assert_that(cargo_process("install").args(&["foo", "bar", "baz"]), execs().with_status(101).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] foo v0.0.1 (registry file://[..]) +[DOWNLOADING] foo v0.0.1 (registry `file://[..]`) [INSTALLING] foo v0.0.1 [COMPILING] foo v0.0.1 [FINISHED] release [optimized] target(s) in [..] [INSTALLING] {home}[..]bin[..]foo[..] -[DOWNLOADING] bar v0.0.2 (registry file://[..]) +[DOWNLOADING] bar v0.0.2 (registry `file://[..]`) [INSTALLING] bar v0.0.2 [COMPILING] bar v0.0.2 [FINISHED] release [optimized] target(s) in [..] [INSTALLING] {home}[..]bin[..]bar[..] -error: could not find `baz` in `registry [..]` +error: could not find `baz` in registry `[..]` Summary: Successfully installed foo, bar! Failed to install baz (see error(s) above). warning: be sure to add `[..]` to your PATH to be able to run the installed binaries @@ -121,7 +121,7 @@ fn missing() { assert_that(cargo_process("install").arg("bar"), execs().with_status(101).with_stderr("\ [UPDATING] registry [..] -[ERROR] could not find `bar` in `registry [..]` +[ERROR] could not find `bar` in registry `[..]` ")); } @@ -131,7 +131,7 @@ fn bad_version() { assert_that(cargo_process("install").arg("foo").arg("--vers=0.2.0"), execs().with_status(101).with_stderr("\ [UPDATING] registry [..] -[ERROR] could not find `foo` in `registry [..]` with version `=0.2.0` +[ERROR] could not find `foo` in registry `[..]` with version `=0.2.0` ")); } diff --git a/tests/local-registry.rs b/tests/local-registry.rs index 7643a92aa57..227289334a9 100644 --- a/tests/local-registry.rs +++ b/tests/local-registry.rs @@ -287,10 +287,10 @@ fn invalid_dir_bad() { [ERROR] failed to load source for a dependency on `foo` Caused by: - Unable to update registry https://[..] + Unable to update registry `https://[..]` Caused by: - failed to update replaced source `registry https://[..]` + failed to update replaced source registry `https://[..]` Caused by: local registry path is not a directory: [..]path[..]to[..]nowhere diff --git a/tests/registry.rs b/tests/registry.rs index c63310e6486..33677bdb5bd 100644 --- a/tests/registry.rs +++ b/tests/registry.rs @@ -38,7 +38,7 @@ fn simple() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `{reg}` -[DOWNLOADING] bar v0.0.1 (registry file://[..]) +[DOWNLOADING] bar v0.0.1 (registry `file://[..]`) [COMPILING] bar v0.0.1 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -78,8 +78,8 @@ fn deps() { assert_that(p.cargo_process("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `{reg}` -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) [COMPILING] baz v0.0.1 [COMPILING] bar v0.0.1 [COMPILING] foo v0.0.1 ({dir}) @@ -175,10 +175,10 @@ fn bad_cksum() { [ERROR] unable to get packages from source Caused by: - failed to download replaced source `registry https://[..]` + failed to download replaced source registry `https://[..]` Caused by: - failed to verify the checksum of `bad-cksum v0.0.1 (registry file://[..])` + failed to verify the checksum of `bad-cksum v0.0.1 (registry `file://[..]`)` ")); } @@ -210,7 +210,7 @@ version required: >= 0.0.0 assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `{reg}` -[DOWNLOADING] notyet v0.0.1 (registry file://[..]) +[DOWNLOADING] notyet v0.0.1 (registry `file://[..]`) [COMPILING] notyet v0.0.1 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -264,7 +264,7 @@ version required: ^0.0.1 [PACKAGING] foo v0.0.1 ({dir}) [VERIFYING] foo v0.0.1 ({dir}) [UPDATING] registry `[..]` -[DOWNLOADING] notyet v0.0.1 (registry file://[..]) +[DOWNLOADING] notyet v0.0.1 (registry `file://[..]`) [COMPILING] notyet v0.0.1 [COMPILING] foo v0.0.1 ({dir}[..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -291,7 +291,7 @@ fn lockfile_locks() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] bar v0.0.1 (registry file://[..]) +[DOWNLOADING] bar v0.0.1 (registry `file://[..]`) [COMPILING] bar v0.0.1 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -326,8 +326,8 @@ fn lockfile_locks_transitively() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) [COMPILING] baz v0.0.1 [COMPILING] bar v0.0.1 [COMPILING] foo v0.0.1 ({dir}) @@ -366,8 +366,8 @@ fn yanks_are_not_used() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) [COMPILING] baz v0.0.1 [COMPILING] bar v0.0.1 [COMPILING] foo v0.0.1 ({dir}) @@ -462,7 +462,7 @@ fn update_with_lockfile_if_packages_missing() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr("\ [UPDATING] registry `[..]` -[DOWNLOADING] bar v0.0.1 (registry file://[..]) +[DOWNLOADING] bar v0.0.1 (registry `file://[..]`) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs ")); } @@ -501,7 +501,7 @@ fn update_lockfile() { println!("0.0.2 build"); assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ -[DOWNLOADING] [..] v0.0.2 (registry file://[..]) +[DOWNLOADING] [..] v0.0.2 (registry `file://[..]`) [COMPILING] bar v0.0.2 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -519,7 +519,7 @@ fn update_lockfile() { println!("0.0.3 build"); assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ -[DOWNLOADING] [..] v0.0.3 (registry file://[..]) +[DOWNLOADING] [..] v0.0.3 (registry `file://[..]`) [COMPILING] bar v0.0.3 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -569,7 +569,7 @@ fn dev_dependency_not_used() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] [..] v0.0.1 (registry file://[..]) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) [COMPILING] bar v0.0.1 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -652,7 +652,7 @@ fn updating_a_dep() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] bar v0.0.1 (registry file://[..]) +[DOWNLOADING] bar v0.0.1 (registry `file://[..]`) [COMPILING] bar v0.0.1 [COMPILING] a v0.0.1 ({dir}/a) [COMPILING] foo v0.0.1 ({dir}) @@ -675,7 +675,7 @@ fn updating_a_dep() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] registry `[..]` -[DOWNLOADING] bar v0.1.0 (registry file://[..]) +[DOWNLOADING] bar v0.1.0 (registry `file://[..]`) [COMPILING] bar v0.1.0 [COMPILING] a v0.0.1 ({dir}/a) [COMPILING] foo v0.0.1 ({dir}) @@ -721,7 +721,7 @@ fn git_and_registry_dep() { execs().with_status(0).with_stderr(&format!("\ [UPDATING] [..] [UPDATING] [..] -[DOWNLOADING] a v0.0.1 (registry file://[..]) +[DOWNLOADING] a v0.0.1 (registry `file://[..]`) [COMPILING] a v0.0.1 [COMPILING] b v0.0.1 ([..]) [COMPILING] foo v0.0.1 ({dir}) @@ -787,7 +787,7 @@ fn update_publish_then_update() { assert_that(p.cargo("build"), execs().with_status(0).with_stderr(&format!("\ [UPDATING] [..] -[DOWNLOADING] a v0.1.1 (registry file://[..]) +[DOWNLOADING] a v0.1.1 (registry `file://[..]`) [COMPILING] a v0.1.1 [COMPILING] foo v0.5.0 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs @@ -854,7 +854,7 @@ fn update_transitive_dependency() { assert_that(p.cargo("build"), execs().with_status(0) .with_stderr("\ -[DOWNLOADING] b v0.1.1 (registry file://[..]) +[DOWNLOADING] b v0.1.1 (registry `file://[..]`) [COMPILING] b v0.1.1 [COMPILING] a v0.1.0 [COMPILING] foo v0.5.0 ([..]) @@ -945,11 +945,11 @@ fn update_multiple_packages() { assert_that(p.cargo("build"), execs().with_status(0) .with_stderr_contains("\ -[DOWNLOADING] a v0.1.1 (registry file://[..])") +[DOWNLOADING] a v0.1.1 (registry `file://[..]`)") .with_stderr_contains("\ -[DOWNLOADING] b v0.1.1 (registry file://[..])") +[DOWNLOADING] b v0.1.1 (registry `file://[..]`)") .with_stderr_contains("\ -[DOWNLOADING] c v0.1.1 (registry file://[..])") +[DOWNLOADING] c v0.1.1 (registry `file://[..]`)") .with_stderr_contains("\ [COMPILING] a v0.1.1") .with_stderr_contains("\ diff --git a/tests/resolve.rs b/tests/resolve.rs index 2b84106a657..31f7abaa6e4 100644 --- a/tests/resolve.rs +++ b/tests/resolve.rs @@ -376,7 +376,7 @@ fn resolving_but_no_exists() { assert_eq!(res.err().unwrap().to_string(), "\ no matching package named `foo` found (required by `root`) -location searched: registry http://example.com/ +location searched: registry `http://example.com/` version required: ^1\ "); } From 2d11c7b536d1b8a82bbefe9ff3f37bebfc7742c5 Mon Sep 17 00:00:00 2001 From: boats Date: Thu, 5 Oct 2017 23:11:40 +0000 Subject: [PATCH 04/13] Clean up --- src/cargo/core/source/source_id.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 1c37d31995d..6719b6ed9be 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -186,23 +186,13 @@ impl SourceId { let registries = config.get_table("registries")?; match registries.as_ref().and_then(|registries| registries.val.get(key)) { Some(registry) => { - let index = match *registry { - CV::Table(ref registry, _) => { - match registry.get("index") { - Some(index) => index.string(&format!("registries.{}", key))?.0, - None => return Err(format!("No index for registry `{}`", key).into()), - } - } - _ => registry.expected("table", &format!("registries.{}", key))? - }; - - let url = index.to_url()?; + let index = config.get_str(&format!("registries.{}.index", key))?.to_url()?; Ok(SourceId { inner: Arc::new(SourceIdInner { kind: Kind::Registry, - canonical_url: git::canonicalize_url(&url)?, - url: url, + canonical_url: git::canonicalize_url(&index)?, + url: index, precise: None, }), }) From 5c1fcb4a5552a813b772849a346556cb1d2ac868 Mon Sep 17 00:00:00 2001 From: boats Date: Thu, 5 Oct 2017 23:13:53 +0000 Subject: [PATCH 05/13] Get features in virtual manifest. --- src/cargo/util/toml/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 487d46f93c9..c5566b9cb2d 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -717,6 +717,10 @@ impl TomlManifest { let mut nested_paths = Vec::new(); let mut warnings = Vec::new(); let mut deps = Vec::new(); + let empty = Vec::new(); + let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); + let features = Features::new(&cargo_features, &mut warnings)?; + let (replace, patch) = { let mut cx = Context { pkgid: None, @@ -726,7 +730,7 @@ impl TomlManifest { config: config, warnings: &mut warnings, platform: None, - features: &Features::default(), // @alex: is this right? + features: &features, root: root }; (me.replace(&mut cx)?, me.patch(&mut cx)?) From 0da34699a481aec56fe25a3551e0251bbf0e2378 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Fri, 6 Oct 2017 13:29:37 -0700 Subject: [PATCH 06/13] Clean up alt registries lookup. --- src/cargo/core/source/source_id.rs | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 6719b6ed9be..75d180d0f13 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -14,7 +14,7 @@ use ops; use sources::git; use sources::{PathSource, GitSource, RegistrySource, CRATES_IO}; use sources::DirectorySource; -use util::{Config, ConfigValue as CV, CargoResult, ToUrl}; +use util::{Config, CargoResult, ToUrl}; /// Unique identifier for a source of packages. #[derive(Clone, Eq, Debug)] @@ -183,22 +183,17 @@ impl SourceId { } pub fn alt_registry(config: &Config, key: &str) -> CargoResult { - let registries = config.get_table("registries")?; - match registries.as_ref().and_then(|registries| registries.val.get(key)) { - Some(registry) => { - let index = config.get_str(&format!("registries.{}.index", key))?.to_url()?; - - Ok(SourceId { - inner: Arc::new(SourceIdInner { - kind: Kind::Registry, - canonical_url: git::canonicalize_url(&index)?, - url: index, - precise: None, - }), - }) - } - None => Err(format!("Required unknown registry source: `{}`", key).into()) - } + if let Some(index) = config.get_string(&format!("registries.{}.index", key))? { + let url = index.val.to_url()?; + Ok(SourceId { + inner: Arc::new(SourceIdInner { + kind: Kind::Registry, + canonical_url: git::canonicalize_url(&url)?, + url: url, + precise: None, + }), + }) + } else { Err(format!("No index found for registry: `{}`", key).into()) } } /// Get this source URL From 76b29e97a1c6e2b9ba180e66aa6016f9e2667630 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Sat, 21 Oct 2017 20:10:25 +0100 Subject: [PATCH 07/13] Adding some extra tests. --- tests/alt-registry.rs | 84 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) mode change 100644 => 100755 tests/alt-registry.rs diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs old mode 100644 new mode 100755 index 9d701ba6b44..fed6ae0c793 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -118,7 +118,6 @@ fn registry_incompatible_with_git() { .with_stderr_contains(" dependency (bar) specification is ambiguous. Only one of `git` or `registry` is allowed.")); } - #[test] fn cannot_publish_with_registry_dependency() { let p = project("foo") @@ -143,3 +142,86 @@ fn cannot_publish_with_registry_dependency() { .arg("--index").arg(registry::alt_registry().to_string()), execs().with_status(101)); } + +#[test] +fn alt_registry_and_crates_io_deps() { + + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + crates_io_dep = "0.0.1" + + [dependencies.alt_reg_dep] + version = "0.1.0" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("crates_io_dep", "0.0.1").publish(); + Package::new("alt_reg_dep", "0.1.0").alternative(true).publish(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(0) + .with_stderr_contains(format!("\ +[UPDATING] registry `{}`", registry::alt_registry())) + .with_stderr_contains(&format!("\ +[UPDATING] registry `{}`", registry::registry())) + .with_stderr_contains("\ +[DOWNLOADING] crates_io_dep v0.0.1 (registry `file://[..]`)") + .with_stderr_contains("\ +[DOWNLOADING] alt_reg_dep v0.1.0 (registry `file://[..]`)") + .with_stderr_contains("\ +[COMPILING] alt_reg_dep v0.1.0 (registry `file://[..]`)") + .with_stderr_contains("\ +[COMPILING] crates_io_dep v0.0.1") + .with_stderr_contains(&format!("\ +[COMPILING] foo v0.0.1 ({})", p.url())) + .with_stderr_contains("\ +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs")) + +} + +#[test] +fn alt_registry_dep_with_crates_io_dep() { + + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.alt_reg_dep] + version = "0.1.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("alt_reg_dep", "0.1.1").alternative(true).dep("crates_io_dep", "0.0.2").publish(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(0).with_stderr(&format!("\ +[UPDATING] registry `{alt_reg}` +[UPDATING] registry `{crates_io_reg}` +[DOWNLOADING] alt_reg_dep v0.1.1 (registry `file://[..]`) +[DOWNLOADING] crates_io_dep v0.0.2 (registry `file://[..]`) +[COMPILING] alt_reg_dep v0.1.1 (registry `file://[..]`) +[COMPILING] crates_io_dep v0.0.2 +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs +", + dir = p.url(), + crates_io_reg = registry::registry(), + alt_reg = registry::alt_registry()))); +} From 280f10ecb4d8a1e4487e7d39547b31e66aedf802 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Sun, 22 Oct 2017 07:46:50 +0100 Subject: [PATCH 08/13] Add support for other registries in dependencies. --- src/cargo/core/dependency.rs | 0 src/cargo/core/resolver/mod.rs | 0 src/cargo/sources/registry/mod.rs | 17 +++++++++++++---- tests/alt-registry.rs | 5 +++-- tests/cargotest/support/registry.rs | 21 ++++++++++++++++----- 5 files changed, 32 insertions(+), 11 deletions(-) mode change 100644 => 100755 src/cargo/core/dependency.rs mode change 100644 => 100755 src/cargo/core/resolver/mod.rs mode change 100644 => 100755 src/cargo/sources/registry/mod.rs mode change 100644 => 100755 tests/cargotest/support/registry.rs diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs old mode 100644 new mode 100755 diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs old mode 100644 new mode 100755 diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs old mode 100644 new mode 100755 index 8b907f7d33c..4a49ee1b9b9 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -175,6 +175,7 @@ use sources::PathSource; use util::{CargoResult, Config, internal, FileLock, Filesystem}; use util::errors::CargoResultExt; use util::hex; +use util::to_url::ToUrl; const INDEX_LOCK: &'static str = ".cargo-index-lock"; pub static CRATES_IO: &'static str = "https://github.com/rust-lang/crates.io-index"; @@ -224,6 +225,7 @@ struct RegistryDependency<'a> { default_features: bool, target: Option>, kind: Option>, + index: Option, } pub trait RegistryData { @@ -483,12 +485,18 @@ impl<'de> de::Deserialize<'de> for DependencyList { fn parse_registry_dependency(dep: RegistryDependency) -> CargoResult { let RegistryDependency { - name, req, features, optional, default_features, target, kind + name, req, features, optional, default_features, target, kind, index } = dep; - let mut dep = DEFAULT_ID.with(|id| { - Dependency::parse_no_deprecated(&name, Some(&req), id) - })?; + let id = if let Some(index) = index { + SourceId::for_registry(&index.to_url()?)? + } else { + DEFAULT_ID.with(|id| { + id.clone() + }) + }; + + let mut dep = Dependency::parse_no_deprecated(&name, Some(&req), &id)?; let kind = match kind.as_ref().map(|s| &s[..]).unwrap_or("") { "dev" => Kind::Development, "build" => Kind::Build, @@ -512,5 +520,6 @@ fn parse_registry_dependency(dep: RegistryDependency) .set_features(features) .set_platform(platform) .set_kind(kind); + Ok(dep) } diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index fed6ae0c793..fdd5354561b 100755 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -208,7 +208,8 @@ fn alt_registry_dep_with_crates_io_dep() { .file("src/main.rs", "fn main() {}"); p.build(); - Package::new("alt_reg_dep", "0.1.1").alternative(true).dep("crates_io_dep", "0.0.2").publish(); + Package::new("crates_io_dep", "0.0.2").publish(); + Package::new("alt_reg_dep", "0.1.1").alternative(true).registry_dep("crates_io_dep", "0.0.2", registry::registry().as_str()).publish(); assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(0).with_stderr(&format!("\ @@ -216,8 +217,8 @@ fn alt_registry_dep_with_crates_io_dep() { [UPDATING] registry `{crates_io_reg}` [DOWNLOADING] alt_reg_dep v0.1.1 (registry `file://[..]`) [DOWNLOADING] crates_io_dep v0.0.2 (registry `file://[..]`) +[COMPILING] crates_io_dep v0.0.2 (registry `file://[..]`) [COMPILING] alt_reg_dep v0.1.1 (registry `file://[..]`) -[COMPILING] crates_io_dep v0.0.2 [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs ", diff --git a/tests/cargotest/support/registry.rs b/tests/cargotest/support/registry.rs old mode 100644 new mode 100755 index 1e0b28cd025..b303d4dc261 --- a/tests/cargotest/support/registry.rs +++ b/tests/cargotest/support/registry.rs @@ -39,6 +39,7 @@ struct Dependency { kind: String, target: Option, features: Vec, + index: Option, } pub fn init() { @@ -116,25 +117,32 @@ impl Package { } pub fn dep(&mut self, name: &str, vers: &str) -> &mut Package { - self.full_dep(name, vers, None, "normal", &[]) + self.full_dep(name, vers, None, "normal", &[], None) } pub fn feature_dep(&mut self, name: &str, vers: &str, features: &[&str]) -> &mut Package { - self.full_dep(name, vers, None, "normal", features) + self.full_dep(name, vers, None, "normal", features, None) } pub fn target_dep(&mut self, name: &str, vers: &str, target: &str) -> &mut Package { - self.full_dep(name, vers, Some(target), "normal", &[]) + self.full_dep(name, vers, Some(target), "normal", &[], None) + } + + pub fn registry_dep(&mut self, + name: &str, + vers: &str, + index: &str) -> &mut Package { + self.full_dep(name, vers, None, "normal", &[], Some(index)) } pub fn dev_dep(&mut self, name: &str, vers: &str) -> &mut Package { - self.full_dep(name, vers, None, "dev", &[]) + self.full_dep(name, vers, None, "dev", &[], None) } fn full_dep(&mut self, @@ -142,13 +150,15 @@ impl Package { vers: &str, target: Option<&str>, kind: &str, - features: &[&str]) -> &mut Package { + features: &[&str], + index: Option<&str>) -> &mut Package { self.deps.push(Dependency { name: name.to_string(), vers: vers.to_string(), kind: kind.to_string(), target: target.map(|s| s.to_string()), features: features.iter().map(|s| s.to_string()).collect(), + index: index.map(|s| s.to_string()), }); self } @@ -171,6 +181,7 @@ impl Package { "target": dep.target, "optional": false, "kind": dep.kind, + "index": dep.index, }) }).collect::>(); let cksum = { From 8e2d01159d7a22cd7b4742c5914c44b43b3cd2da Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Sun, 22 Oct 2017 07:47:32 +0100 Subject: [PATCH 09/13] Sorting out file permissions. --- src/cargo/core/dependency.rs | 0 src/cargo/core/resolver/mod.rs | 0 src/cargo/sources/registry/mod.rs | 0 tests/cargotest/support/registry.rs | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/cargo/core/dependency.rs mode change 100755 => 100644 src/cargo/core/resolver/mod.rs mode change 100755 => 100644 src/cargo/sources/registry/mod.rs mode change 100755 => 100644 tests/cargotest/support/registry.rs diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs old mode 100755 new mode 100644 diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs old mode 100755 new mode 100644 diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs old mode 100755 new mode 100644 diff --git a/tests/cargotest/support/registry.rs b/tests/cargotest/support/registry.rs old mode 100755 new mode 100644 From eb75b07573883f133c51514ff34f956b0366a475 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Sun, 22 Oct 2017 08:44:11 +0100 Subject: [PATCH 10/13] Switch to use registry in the dependency so that it matches RFC2141. --- src/cargo/sources/registry/mod.rs | 8 ++++---- tests/cargotest/support/registry.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index 4a49ee1b9b9..2d1e4a00e42 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -225,7 +225,7 @@ struct RegistryDependency<'a> { default_features: bool, target: Option>, kind: Option>, - index: Option, + registry: Option, } pub trait RegistryData { @@ -485,11 +485,11 @@ impl<'de> de::Deserialize<'de> for DependencyList { fn parse_registry_dependency(dep: RegistryDependency) -> CargoResult { let RegistryDependency { - name, req, features, optional, default_features, target, kind, index + name, req, features, optional, default_features, target, kind, registry } = dep; - let id = if let Some(index) = index { - SourceId::for_registry(&index.to_url()?)? + let id = if let Some(registry) = registry { + SourceId::for_registry(®istry.to_url()?)? } else { DEFAULT_ID.with(|id| { id.clone() diff --git a/tests/cargotest/support/registry.rs b/tests/cargotest/support/registry.rs index b303d4dc261..ff4a711cdc9 100644 --- a/tests/cargotest/support/registry.rs +++ b/tests/cargotest/support/registry.rs @@ -39,7 +39,7 @@ struct Dependency { kind: String, target: Option, features: Vec, - index: Option, + registry: Option, } pub fn init() { @@ -137,8 +137,8 @@ impl Package { pub fn registry_dep(&mut self, name: &str, vers: &str, - index: &str) -> &mut Package { - self.full_dep(name, vers, None, "normal", &[], Some(index)) + registry: &str) -> &mut Package { + self.full_dep(name, vers, None, "normal", &[], Some(registry)) } pub fn dev_dep(&mut self, name: &str, vers: &str) -> &mut Package { @@ -151,14 +151,14 @@ impl Package { target: Option<&str>, kind: &str, features: &[&str], - index: Option<&str>) -> &mut Package { + registry: Option<&str>) -> &mut Package { self.deps.push(Dependency { name: name.to_string(), vers: vers.to_string(), kind: kind.to_string(), target: target.map(|s| s.to_string()), features: features.iter().map(|s| s.to_string()).collect(), - index: index.map(|s| s.to_string()), + registry: registry.map(|s| s.to_string()), }); self } @@ -181,7 +181,7 @@ impl Package { "target": dep.target, "optional": false, "kind": dep.kind, - "index": dep.index, + "registry": dep.registry, }) }).collect::>(); let cksum = { From 827db91b7a450efb23a9766438d27206af830bc2 Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Mon, 23 Oct 2017 06:54:25 +0100 Subject: [PATCH 11/13] Adding test for alternate registry dependency, with alternate registry dependency. --- tests/alt-registry.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index fdd5354561b..3f1b91c99c8 100755 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -226,3 +226,39 @@ fn alt_registry_dep_with_crates_io_dep() { crates_io_reg = registry::registry(), alt_reg = registry::alt_registry()))); } + +#[test] +fn alt_reg_dep_with_alt_reg_dep() { + + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.1.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("baz", "0.0.2").alternative(true).publish(); + Package::new("bar", "0.1.1").alternative(true).registry_dep("baz", "0.0.2", registry::alt_registry().as_str()).publish(); + + assert_that(p.cargo("build").masquerade_as_nightly_cargo(), + execs().with_status(0).with_stderr(&format!("\ +[UPDATING] registry `{alt_reg}` +[DOWNLOADING] bar v0.1.1 (registry `file://[..]`) +[DOWNLOADING] baz v0.0.2 (registry `file://[..]`) +[COMPILING] baz v0.0.2 (registry `file://[..]`) +[COMPILING] bar v0.1.1 (registry `file://[..]`) +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs +", + dir = p.url(), + alt_reg = registry::alt_registry()))); +} From c0be7f4b6d8e232fa51a6d0135b02eca1e13b788 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Fri, 6 Oct 2017 15:34:00 -0700 Subject: [PATCH 12/13] Add tests of transitive dependencies. --- tests/alt-registry.rs | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index 3f1b91c99c8..5d992d2320b 100755 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -72,6 +72,77 @@ fn depend_on_alt_registry() { dir = p.url()))); } +#[test] +fn depend_on_alt_registry_depends_on_same_registry() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("baz", "0.0.1").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!("\ +[UPDATING] registry `{reg}` +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[COMPILING] baz v0.0.1 (registry `file://[..]`) +[COMPILING] bar v0.0.1 (registry `file://[..]`) +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs +", + dir = p.url(), + reg = registry::alt_registry()))); +} + + +#[test] +fn depend_on_alt_registry_depends_on_crates_io() { + let p = project("foo") + .file("Cargo.toml", r#" + cargo-features = ["alternative-registries"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "alternative" + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + Package::new("baz", "0.0.1").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!("\ +[UPDATING] registry `{reg}` +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) +[COMPILING] baz v0.0.1 +[COMPILING] bar v0.0.1 +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs +", + dir = p.url(), + reg = registry::alt_registry()))); +} + #[test] fn registry_incompatible_with_path() { let p = project("foo") From 2445497a936e78d91aee8254a9f764d270b82b5b Mon Sep 17 00:00:00 2001 From: Chris Swindle Date: Tue, 24 Oct 2017 21:24:12 +0100 Subject: [PATCH 13/13] Update alt-registry tests to the use the new interface. --- tests/alt-registry.rs | 119 +++++++++--------------------------------- 1 file changed, 24 insertions(+), 95 deletions(-) diff --git a/tests/alt-registry.rs b/tests/alt-registry.rs index 5d992d2320b..9c1072fd733 100755 --- a/tests/alt-registry.rs +++ b/tests/alt-registry.rs @@ -1,3 +1,4 @@ +#[macro_use] extern crate cargotest; extern crate hamcrest; @@ -19,8 +20,8 @@ fn is_feature_gated() { version = "0.0.1" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); Package::new("bar", "0.0.1").alternative(true).publish(); @@ -44,8 +45,8 @@ fn depend_on_alt_registry() { version = "0.0.1" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); Package::new("bar", "0.0.1").alternative(true).publish(); @@ -87,11 +88,11 @@ fn depend_on_alt_registry_depends_on_same_registry() { version = "0.0.1" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); Package::new("baz", "0.0.1").alternative(true).publish(); - Package::new("bar", "0.0.1").dep("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(); assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(0).with_stderr(&format!("\ @@ -123,24 +124,26 @@ fn depend_on_alt_registry_depends_on_crates_io() { version = "0.0.1" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); Package::new("baz", "0.0.1").publish(); - Package::new("bar", "0.0.1").dep("baz", "0.0.1").alternative(true).publish(); + Package::new("bar", "0.0.1").registry_dep("baz", "0.0.1", registry::registry().as_str()).alternative(true).publish(); assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(0).with_stderr(&format!("\ +[UPDATING] registry `{alt_reg}` [UPDATING] registry `{reg}` [DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) [DOWNLOADING] [..] v0.0.1 (registry `file://[..]`) -[COMPILING] baz v0.0.1 -[COMPILING] bar v0.0.1 +[COMPILING] baz v0.0.1 (registry `file://[..]`) +[COMPILING] bar v0.0.1 (registry `file://[..]`) [COMPILING] foo v0.0.1 ({dir}) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs ", dir = p.url(), - reg = registry::alt_registry()))); + alt_reg = registry::alt_registry(), + reg = registry::registry()))); } #[test] @@ -158,8 +161,8 @@ fn registry_incompatible_with_path() { path = "" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(101) @@ -181,8 +184,8 @@ fn registry_incompatible_with_git() { git = "" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); assert_that(p.cargo("build").masquerade_as_nightly_cargo(), execs().with_status(101) @@ -204,8 +207,8 @@ fn cannot_publish_with_registry_dependency() { version = "0.0.1" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); Package::new("bar", "0.0.1").alternative(true).publish(); @@ -233,8 +236,8 @@ fn alt_registry_and_crates_io_deps() { version = "0.1.0" registry = "alternative" "#) - .file("src/main.rs", "fn main() {}"); - p.build(); + .file("src/main.rs", "fn main() {}") + .build(); Package::new("crates_io_dep", "0.0.1").publish(); Package::new("alt_reg_dep", "0.1.0").alternative(true).publish(); @@ -259,77 +262,3 @@ fn alt_registry_and_crates_io_deps() { [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs")) } - -#[test] -fn alt_registry_dep_with_crates_io_dep() { - - let p = project("foo") - .file("Cargo.toml", r#" - cargo-features = ["alternative-registries"] - - [project] - name = "foo" - version = "0.0.1" - authors = [] - - [dependencies.alt_reg_dep] - version = "0.1.1" - registry = "alternative" - "#) - .file("src/main.rs", "fn main() {}"); - p.build(); - - Package::new("crates_io_dep", "0.0.2").publish(); - Package::new("alt_reg_dep", "0.1.1").alternative(true).registry_dep("crates_io_dep", "0.0.2", registry::registry().as_str()).publish(); - - assert_that(p.cargo("build").masquerade_as_nightly_cargo(), - execs().with_status(0).with_stderr(&format!("\ -[UPDATING] registry `{alt_reg}` -[UPDATING] registry `{crates_io_reg}` -[DOWNLOADING] alt_reg_dep v0.1.1 (registry `file://[..]`) -[DOWNLOADING] crates_io_dep v0.0.2 (registry `file://[..]`) -[COMPILING] crates_io_dep v0.0.2 (registry `file://[..]`) -[COMPILING] alt_reg_dep v0.1.1 (registry `file://[..]`) -[COMPILING] foo v0.0.1 ({dir}) -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs -", - dir = p.url(), - crates_io_reg = registry::registry(), - alt_reg = registry::alt_registry()))); -} - -#[test] -fn alt_reg_dep_with_alt_reg_dep() { - - let p = project("foo") - .file("Cargo.toml", r#" - cargo-features = ["alternative-registries"] - - [project] - name = "foo" - version = "0.0.1" - authors = [] - - [dependencies.bar] - version = "0.1.1" - registry = "alternative" - "#) - .file("src/main.rs", "fn main() {}"); - p.build(); - - Package::new("baz", "0.0.2").alternative(true).publish(); - Package::new("bar", "0.1.1").alternative(true).registry_dep("baz", "0.0.2", registry::alt_registry().as_str()).publish(); - - assert_that(p.cargo("build").masquerade_as_nightly_cargo(), - execs().with_status(0).with_stderr(&format!("\ -[UPDATING] registry `{alt_reg}` -[DOWNLOADING] bar v0.1.1 (registry `file://[..]`) -[DOWNLOADING] baz v0.0.2 (registry `file://[..]`) -[COMPILING] baz v0.0.2 (registry `file://[..]`) -[COMPILING] bar v0.1.1 (registry `file://[..]`) -[COMPILING] foo v0.0.1 ({dir}) -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs -", - dir = p.url(), - alt_reg = registry::alt_registry()))); -}