Skip to content

Commit 21fe000

Browse files
committed
Auto merge of #6500 - ehuss:metadata-reg, r=alexcrichton
Add dependency `registry` to `cargo metadata`. This adds the `registry` field for dependencies for alternate registries in `cargo metadata`.
2 parents 9bfaf2e + 64042d8 commit 21fe000

File tree

15 files changed

+930
-341
lines changed

15 files changed

+930
-341
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ path = "src/cargo/lib.rs"
1919

2020
[dependencies]
2121
atty = "0.2"
22+
byteorder = "1.2"
2223
bytesize = "1.0"
2324
crates-io = { path = "src/crates-io", version = "0.22" }
2425
crossbeam-utils = "0.6"
@@ -57,6 +58,7 @@ tempfile = "3.0"
5758
termcolor = "1.0"
5859
toml = "0.4.2"
5960
url = "1.1"
61+
url_serde = "0.2.0"
6062
clap = "2.31.2"
6163
unicode-width = "0.1.5"
6264
openssl = { version = '0.10.11', optional = true }

src/cargo/core/dependency.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use semver::ReqParseError;
77
use semver::VersionReq;
88
use serde::ser;
99
use serde::Serialize;
10+
use url::Url;
1011

1112
use crate::core::interning::InternedString;
1213
use crate::core::{PackageId, SourceId, Summary};
@@ -25,6 +26,12 @@ pub struct Dependency {
2526
struct Inner {
2627
name: InternedString,
2728
source_id: SourceId,
29+
/// Source ID for the registry as specified in the manifest.
30+
///
31+
/// This will be None if it is not specified (crates.io dependency).
32+
/// This is different from `source_id` for example when both a `path` and
33+
/// `registry` is specified. Or in the case of a crates.io dependency,
34+
/// `source_id` will be crates.io and this will be None.
2835
registry_id: Option<SourceId>,
2936
req: VersionReq,
3037
specified_req: bool,
@@ -59,6 +66,10 @@ struct SerializedDependency<'a> {
5966
uses_default_features: bool,
6067
features: &'a [InternedString],
6168
target: Option<&'a Platform>,
69+
/// The registry URL this dependency is from.
70+
/// If None, then it comes from the default registry (crates.io).
71+
#[serde(with = "url_serde")]
72+
registry: Option<Url>,
6273
}
6374

6475
impl ser::Serialize for Dependency {
@@ -76,6 +87,7 @@ impl ser::Serialize for Dependency {
7687
features: self.features(),
7788
target: self.platform(),
7889
rename: self.explicit_name_in_toml().map(|s| s.as_str()),
90+
registry: self.registry_id().map(|sid| sid.url().clone()),
7991
}
8092
.serialize(s)
8193
}

src/cargo/core/source/source_id.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct SourceIdInner {
4040
// e.g. the exact git revision of the specified branch for a Git Source
4141
precise: Option<String>,
4242
/// Name of the registry source for alternative registries
43+
/// WARNING: This is not always set for alt-registries when the name is
44+
/// not known.
4345
name: Option<String>,
4446
}
4547

@@ -247,6 +249,8 @@ impl SourceId {
247249
}
248250

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

src/cargo/ops/registry.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,10 @@ fn transmit(
159159
// registry in the dependency.
160160
let dep_registry_id = match dep.registry_id() {
161161
Some(id) => id,
162-
None => failure::bail!("dependency missing registry ID"),
162+
None => SourceId::crates_io(config)?,
163163
};
164+
// In the index and Web API, None means "from the same registry"
165+
// whereas in Cargo.toml, it means "from crates.io".
164166
let dep_registry = if dep_registry_id != registry_id {
165167
Some(dep_registry_id.url().to_string())
166168
} else {

src/cargo/sources/registry/mod.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl<'a> RegistryDependency<'a> {
299299
package,
300300
} = self;
301301

302-
let id = if let Some(registry) = registry {
302+
let id = if let Some(registry) = &registry {
303303
SourceId::for_registry(&registry.to_url()?)?
304304
} else {
305305
default
@@ -328,6 +328,12 @@ impl<'a> RegistryDependency<'a> {
328328
// out here.
329329
features.retain(|s| !s.is_empty());
330330

331+
// In index, "registry" is null if it is from the same index.
332+
// In Cargo.toml, "registry" is None if it is from the default
333+
if !id.is_default_registry() {
334+
dep.set_registry_id(id);
335+
}
336+
331337
dep.set_optional(optional)
332338
.set_default_features(default_features)
333339
.set_features(features)
@@ -486,22 +492,7 @@ impl<'cfg> RegistrySource<'cfg> {
486492
MaybePackage::Ready(pkg) => pkg,
487493
MaybePackage::Download { .. } => unreachable!(),
488494
};
489-
490-
// Unfortunately the index and the actual Cargo.toml in the index can
491-
// differ due to historical Cargo bugs. To paper over these we trash the
492-
// *summary* loaded from the Cargo.toml we just downloaded with the one
493-
// we loaded from the index.
494-
let summaries = self
495-
.index
496-
.summaries(package.name().as_str(), &mut *self.ops)?;
497-
let summary = summaries
498-
.iter()
499-
.map(|s| &s.0)
500-
.find(|s| s.package_id() == package)
501-
.expect("summary not found");
502-
let mut manifest = pkg.manifest().clone();
503-
manifest.set_summary(summary.clone());
504-
Ok(Package::new(manifest, pkg.manifest_path()))
495+
Ok(pkg)
505496
}
506497
}
507498

src/cargo/util/toml/mod.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ impl<'de> de::Deserialize<'de> for TomlDependency {
201201
pub struct DetailedTomlDependency {
202202
version: Option<String>,
203203
registry: Option<String>,
204+
/// The URL of the `registry` field.
205+
/// This is an internal implementation detail. When Cargo creates a
206+
/// package, it replaces `registry` with `registry-index` so that the
207+
/// manifest contains the correct URL. All users won't have the same
208+
/// registry names configured, so Cargo can't rely on just the name for
209+
/// crates published by other users.
204210
registry_index: Option<String>,
205211
path: Option<String>,
206212
git: Option<String>,
@@ -1307,14 +1313,6 @@ impl DetailedTomlDependency {
13071313
}
13081314
}
13091315

1310-
let registry_id = match self.registry {
1311-
Some(ref registry) => {
1312-
cx.features.require(Feature::alternative_registries())?;
1313-
SourceId::alt_registry(cx.config, registry)?
1314-
}
1315-
None => SourceId::crates_io(cx.config)?,
1316-
};
1317-
13181316
let new_source_id = match (
13191317
self.git.as_ref(),
13201318
self.path.as_ref(),
@@ -1410,8 +1408,19 @@ impl DetailedTomlDependency {
14101408
.unwrap_or(true),
14111409
)
14121410
.set_optional(self.optional.unwrap_or(false))
1413-
.set_platform(cx.platform.clone())
1414-
.set_registry_id(registry_id);
1411+
.set_platform(cx.platform.clone());
1412+
if let Some(registry) = &self.registry {
1413+
cx.features.require(Feature::alternative_registries())?;
1414+
let registry_id = SourceId::alt_registry(cx.config, registry)?;
1415+
dep.set_registry_id(registry_id);
1416+
}
1417+
if let Some(registry_index) = &self.registry_index {
1418+
cx.features.require(Feature::alternative_registries())?;
1419+
let url = registry_index.to_url()?;
1420+
let registry_id = SourceId::for_registry(&url)?;
1421+
dep.set_registry_id(registry_id);
1422+
}
1423+
14151424
if let Some(kind) = kind {
14161425
dep.set_kind(kind);
14171426
}

src/doc/man/cargo-metadata.adoc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ The output has the following format:
6161
{
6262
/* The name of the dependency. */
6363
"name": "bitflags",
64-
/* The source ID of the dependency. */
64+
/* The source ID of the dependency. May be null, see
65+
description for the package source.
66+
*/
6567
"source": "registry+https://github.com/rust-lang/crates.io-index",
6668
/* The version requirement for the dependency.
6769
Dependencies without a version requirement have a value of "*".
@@ -84,7 +86,12 @@ The output has the following format:
8486
/* The target platform for the dependency.
8587
null if not a target dependency.
8688
*/
87-
"target": "cfg(windows)"
89+
"target": "cfg(windows)",
90+
/* A string of the URL of the registry this dependency is from.
91+
If not specified or null, the dependency is from the default
92+
registry (crates.io).
93+
*/
94+
"registry": null
8895
}
8996
],
9097
/* Array of Cargo targets. */

0 commit comments

Comments
 (0)