Skip to content

Commit 706c291

Browse files
committed
Auto merge of #9632 - weihanglo:issue-6691, r=ehuss
Display registry name instead of registry URL when possible Fixes #6691 This PR can be divided into several parts: - c5be3de: Try to display registry names instead of URLs for `impl Dipslay for SourceId`. This benefits almost all kinds of messages using`SourceId` directly or indrectly. - 9394d48: This fixes `Updating <name> index` part of `[source]` replacement, which previously didn't preserve the registry name information. - 4c2f9b5: This makes its best effort to show registry names for deps from `Cargo.lock`. Since current lockfile format does not serialize any registry name. We here try the best effort to restore registry name from either `[registries]` table or `[source]` replacement table. This is done by manually implementing `Hash` and `PartialEq` for `SourceIdInner`, of which two traits previously are simply derived. To make `SourceIdInner` generate the same hash no matter it contains `name` field or not, here we remove `name` field from hashing and only concern about `kind`, `precise` and `canonical_url`. Feel free to ask me for adding more tests, though I am not sure what tests should be added 😅
2 parents 4e143fd + 8c75e2f commit 706c291

26 files changed

+287
-254
lines changed

src/cargo/core/compiler/rustdoc.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use std::fmt;
1111
use std::hash;
1212
use url::Url;
1313

14+
const DOCS_RS_URL: &'static str = "https://docs.rs/";
15+
1416
/// Mode used for `std`.
1517
#[derive(Debug, Hash)]
1618
pub enum RustdocExternMode {
@@ -63,7 +65,7 @@ pub struct RustdocExternMap {
6365
impl Default for RustdocExternMap {
6466
fn default() -> Self {
6567
let mut registries = HashMap::new();
66-
registries.insert("crates-io".into(), "https://docs.rs/".into());
68+
registries.insert(CRATES_IO_REGISTRY.into(), DOCS_RS_URL.into());
6769
Self {
6870
registries,
6971
std: None,
@@ -76,8 +78,8 @@ fn default_crates_io_to_docs_rs<'de, D: serde::Deserializer<'de>>(
7678
) -> Result<HashMap<String, String>, D::Error> {
7779
use serde::Deserialize;
7880
let mut registries = HashMap::deserialize(de)?;
79-
if !registries.contains_key("crates-io") {
80-
registries.insert("crates-io".into(), "https://docs.rs/".into());
81+
if !registries.contains_key(CRATES_IO_REGISTRY) {
82+
registries.insert(CRATES_IO_REGISTRY.into(), DOCS_RS_URL.into());
8183
}
8284
Ok(registries)
8385
}

src/cargo/core/package_id.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,15 @@ mod tests {
252252
let loc = CRATES_IO_INDEX.into_url().unwrap();
253253
let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
254254
assert_eq!(
255-
r#"PackageId { name: "foo", version: "1.0.0", source: "registry `https://github.com/rust-lang/crates.io-index`" }"#,
255+
r#"PackageId { name: "foo", version: "1.0.0", source: "registry `crates-io`" }"#,
256256
format!("{:?}", pkg_id)
257257
);
258258

259259
let expected = r#"
260260
PackageId {
261261
name: "foo",
262262
version: "1.0.0",
263-
source: "registry `https://github.com/rust-lang/crates.io-index`",
263+
source: "registry `crates-io`",
264264
}
265265
"#
266266
.trim();
@@ -271,7 +271,7 @@ PackageId {
271271
PackageId {
272272
name: "foo",
273273
version: "1.0.0",
274-
source: "registry `https://github.com/rust-lang/crates.io-index`"
274+
source: "registry `crates-io`"
275275
}
276276
"#
277277
.trim();

src/cargo/core/source/source_id.rs

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::core::PackageId;
2-
use crate::sources::DirectorySource;
3-
use crate::sources::{GitSource, PathSource, RegistrySource, CRATES_IO_INDEX};
2+
use crate::sources::{DirectorySource, CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
3+
use crate::sources::{GitSource, PathSource, RegistrySource};
44
use crate::util::{CanonicalUrl, CargoResult, Config, IntoUrl};
55
use log::trace;
66
use serde::de;
@@ -24,7 +24,7 @@ pub struct SourceId {
2424
inner: &'static SourceIdInner,
2525
}
2626

27-
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
27+
#[derive(Eq, Clone, Debug)]
2828
struct SourceIdInner {
2929
/// The source URL.
3030
url: Url,
@@ -73,13 +73,13 @@ impl SourceId {
7373
/// Creates a `SourceId` object from the kind and URL.
7474
///
7575
/// The canonical url will be calculated, but the precise field will not
76-
fn new(kind: SourceKind, url: Url) -> CargoResult<SourceId> {
76+
fn new(kind: SourceKind, url: Url, name: Option<&str>) -> CargoResult<SourceId> {
7777
let source_id = SourceId::wrap(SourceIdInner {
7878
kind,
7979
canonical_url: CanonicalUrl::new(&url)?,
8080
url,
8181
precise: None,
82-
name: None,
82+
name: name.map(|n| n.into()),
8383
});
8484
Ok(source_id)
8585
}
@@ -132,12 +132,12 @@ impl SourceId {
132132
}
133133
"registry" => {
134134
let url = url.into_url()?;
135-
Ok(SourceId::new(SourceKind::Registry, url)?
135+
Ok(SourceId::new(SourceKind::Registry, url, None)?
136136
.with_precise(Some("locked".to_string())))
137137
}
138138
"path" => {
139139
let url = url.into_url()?;
140-
SourceId::new(SourceKind::Path, url)
140+
SourceId::new(SourceKind::Path, url, None)
141141
}
142142
kind => Err(anyhow::format_err!("unsupported source protocol: {}", kind)),
143143
}
@@ -155,43 +155,53 @@ impl SourceId {
155155
/// `path`: an absolute path.
156156
pub fn for_path(path: &Path) -> CargoResult<SourceId> {
157157
let url = path.into_url()?;
158-
SourceId::new(SourceKind::Path, url)
158+
SourceId::new(SourceKind::Path, url, None)
159159
}
160160

161161
/// Creates a `SourceId` from a Git reference.
162162
pub fn for_git(url: &Url, reference: GitReference) -> CargoResult<SourceId> {
163-
SourceId::new(SourceKind::Git(reference), url.clone())
163+
SourceId::new(SourceKind::Git(reference), url.clone(), None)
164164
}
165165

166-
/// Creates a SourceId from a registry URL.
166+
/// Creates a SourceId from a remote registry URL when the registry name
167+
/// cannot be determined, e.g. an user passes `--index` directly from CLI.
168+
///
169+
/// Use [`SourceId::for_alt_registry`] if a name can provided, which
170+
/// generates better messages for cargo.
167171
pub fn for_registry(url: &Url) -> CargoResult<SourceId> {
168-
SourceId::new(SourceKind::Registry, url.clone())
172+
SourceId::new(SourceKind::Registry, url.clone(), None)
173+
}
174+
175+
/// Creates a `SourceId` from a remote registry URL with given name.
176+
pub fn for_alt_registry(url: &Url, name: &str) -> CargoResult<SourceId> {
177+
SourceId::new(SourceKind::Registry, url.clone(), Some(name))
169178
}
170179

171180
/// Creates a SourceId from a local registry path.
172181
pub fn for_local_registry(path: &Path) -> CargoResult<SourceId> {
173182
let url = path.into_url()?;
174-
SourceId::new(SourceKind::LocalRegistry, url)
183+
SourceId::new(SourceKind::LocalRegistry, url, None)
175184
}
176185

177186
/// Creates a `SourceId` from a directory path.
178187
pub fn for_directory(path: &Path) -> CargoResult<SourceId> {
179188
let url = path.into_url()?;
180-
SourceId::new(SourceKind::Directory, url)
189+
SourceId::new(SourceKind::Directory, url, None)
181190
}
182191

183192
/// Returns the `SourceId` corresponding to the main repository.
184193
///
185194
/// This is the main cargo registry by default, but it can be overridden in
186-
/// a `.cargo/config`.
195+
/// a `.cargo/config.toml`.
187196
pub fn crates_io(config: &Config) -> CargoResult<SourceId> {
188197
config.crates_io_source_id(|| {
189198
config.check_registry_index_not_set()?;
190199
let url = CRATES_IO_INDEX.into_url().unwrap();
191-
SourceId::for_registry(&url)
200+
SourceId::new(SourceKind::Registry, url, Some(CRATES_IO_REGISTRY))
192201
})
193202
}
194203

204+
/// Gets the `SourceId` associated with given name of the remote regsitry.
195205
pub fn alt_registry(config: &Config, key: &str) -> CargoResult<SourceId> {
196206
let url = config.get_registry_index(key)?;
197207
Ok(SourceId::wrap(SourceIdInner {
@@ -216,17 +226,21 @@ impl SourceId {
216226

217227
pub fn display_index(self) -> String {
218228
if self.is_default_registry() {
219-
"crates.io index".to_string()
229+
format!("{} index", CRATES_IO_DOMAIN)
220230
} else {
221-
format!("`{}` index", url_display(self.url()))
231+
format!("`{}` index", self.display_registry_name())
222232
}
223233
}
224234

225235
pub fn display_registry_name(self) -> String {
226236
if self.is_default_registry() {
227-
"crates.io".to_string()
237+
CRATES_IO_REGISTRY.to_string()
228238
} else if let Some(name) = &self.inner.name {
229239
name.clone()
240+
} else if self.precise().is_some() {
241+
// We remove `precise` here to retrieve an permissive version of
242+
// `SourceIdInner`, which may contain the registry name.
243+
self.with_precise(None).display_registry_name()
230244
} else {
231245
url_display(self.url())
232246
}
@@ -463,7 +477,7 @@ impl fmt::Display for SourceId {
463477
Ok(())
464478
}
465479
SourceKind::Path => write!(f, "{}", url_display(&self.inner.url)),
466-
SourceKind::Registry => write!(f, "registry `{}`", url_display(&self.inner.url)),
480+
SourceKind::Registry => write!(f, "registry `{}`", self.display_registry_name()),
467481
SourceKind::LocalRegistry => write!(f, "registry `{}`", url_display(&self.inner.url)),
468482
SourceKind::Directory => write!(f, "dir {}", url_display(&self.inner.url)),
469483
}
@@ -483,6 +497,29 @@ impl Hash for SourceId {
483497
}
484498
}
485499

500+
impl Hash for SourceIdInner {
501+
/// The hash of `SourceIdInner` is used to retrieve its interned value. We
502+
/// only care about fields that make `SourceIdInner` unique, which are:
503+
///
504+
/// - `kind`
505+
/// - `precise`
506+
/// - `canonical_url`
507+
fn hash<S: hash::Hasher>(&self, into: &mut S) {
508+
self.kind.hash(into);
509+
self.precise.hash(into);
510+
self.canonical_url.hash(into);
511+
}
512+
}
513+
514+
impl PartialEq for SourceIdInner {
515+
/// This implementation must be synced with [`SourceIdInner::hash`].
516+
fn eq(&self, other: &Self) -> bool {
517+
self.kind == other.kind
518+
&& self.precise == other.precise
519+
&& self.canonical_url == other.canonical_url
520+
}
521+
}
522+
486523
// forward to `Ord`
487524
impl PartialOrd for SourceKind {
488525
fn partial_cmp(&self, other: &SourceKind) -> Option<Ordering> {
@@ -670,15 +707,15 @@ mod tests {
670707
fn github_sources_equal() {
671708
let loc = "https://github.com/foo/bar".into_url().unwrap();
672709
let default = SourceKind::Git(GitReference::DefaultBranch);
673-
let s1 = SourceId::new(default.clone(), loc).unwrap();
710+
let s1 = SourceId::new(default.clone(), loc, None).unwrap();
674711

675712
let loc = "git://github.com/foo/bar".into_url().unwrap();
676-
let s2 = SourceId::new(default, loc.clone()).unwrap();
713+
let s2 = SourceId::new(default, loc.clone(), None).unwrap();
677714

678715
assert_eq!(s1, s2);
679716

680717
let foo = SourceKind::Git(GitReference::Branch("foo".to_string()));
681-
let s3 = SourceId::new(foo, loc).unwrap();
718+
let s3 = SourceId::new(foo, loc, None).unwrap();
682719
assert_ne!(s1, s3);
683720
}
684721
}

src/cargo/ops/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::sources::CRATES_IO_DOMAIN;
2+
13
pub use self::cargo_clean::{clean, CleanOptions};
24
pub use self::cargo_compile::{
35
compile, compile_with_exec, compile_ws, create_bcx, print, resolve_all_features, CompileOptions,
@@ -66,7 +68,7 @@ fn check_dep_has_version(dep: &crate::core::Dependency, publish: bool) -> crate:
6668

6769
if !dep.specified_req() && dep.is_transitive() {
6870
let dep_version_source = dep.registry_id().map_or_else(
69-
|| "crates.io".to_string(),
71+
|| CRATES_IO_DOMAIN.to_string(),
7072
|registry_id| registry_id.display_registry_name(),
7173
);
7274
anyhow::bail!(

src/cargo/ops/registry.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::core::resolver::CliFeatures;
2020
use crate::core::source::Source;
2121
use crate::core::{Package, SourceId, Workspace};
2222
use crate::ops;
23-
use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_REGISTRY};
23+
use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_DOMAIN, CRATES_IO_REGISTRY};
2424
use crate::util::config::{self, Config, SslVersionConfig, SslVersionConfigRange};
2525
use crate::util::errors::CargoResult;
2626
use crate::util::important_paths::find_root_manifest_for_wd;
@@ -730,15 +730,15 @@ pub fn registry_login(
730730
"Login",
731731
format!(
732732
"token for `{}` saved",
733-
reg.as_ref().map_or("crates.io", String::as_str)
733+
reg.as_ref().map_or(CRATES_IO_DOMAIN, String::as_str)
734734
),
735735
)?;
736736
Ok(())
737737
}
738738

739739
pub fn registry_logout(config: &Config, reg: Option<String>) -> CargoResult<()> {
740740
let (registry, reg_cfg, _) = registry(config, None, None, reg.clone(), false, false)?;
741-
let reg_name = reg.as_deref().unwrap_or("crates.io");
741+
let reg_name = reg.as_deref().unwrap_or(CRATES_IO_DOMAIN);
742742
if reg_cfg.credential_process.is_none() && reg_cfg.token.is_none() {
743743
config.shell().status(
744744
"Logout",

src/cargo/ops/vendor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::core::shell::Verbosity;
22
use crate::core::{GitReference, Workspace};
33
use crate::ops;
44
use crate::sources::path::PathSource;
5+
use crate::sources::CRATES_IO_REGISTRY;
56
use crate::util::{CargoResult, Config};
67
use anyhow::{bail, Context as _};
78
use cargo_util::{paths, Sha256};
@@ -248,7 +249,7 @@ fn sync(
248249
// replace original sources with vendor
249250
for source_id in sources {
250251
let name = if source_id.is_default_registry() {
251-
"crates-io".to_string()
252+
CRATES_IO_REGISTRY.to_string()
252253
} else {
253254
source_id.url().to_string()
254255
};

src/cargo/sources/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ restore the source replacement configuration to continue the build
207207
let mut srcs = Vec::new();
208208
if let Some(registry) = def.registry {
209209
let url = url(&registry, &format!("source.{}.registry", name))?;
210-
srcs.push(SourceId::for_registry(&url)?);
210+
srcs.push(SourceId::for_alt_registry(&url, &name)?);
211211
}
212212
if let Some(local_registry) = def.local_registry {
213213
let path = local_registry.resolve_path(self.config);
@@ -247,7 +247,7 @@ restore the source replacement configuration to continue the build
247247
check_not_set("tag", def.tag)?;
248248
check_not_set("rev", def.rev)?;
249249
}
250-
if name == "crates-io" && srcs.is_empty() {
250+
if name == CRATES_IO_REGISTRY && srcs.is_empty() {
251251
srcs.push(SourceId::crates_io(self.config)?);
252252
}
253253

src/cargo/sources/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub use self::config::SourceConfigMap;
22
pub use self::directory::DirectorySource;
33
pub use self::git::GitSource;
44
pub use self::path::PathSource;
5-
pub use self::registry::{RegistrySource, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
5+
pub use self::registry::{RegistrySource, CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
66
pub use self::replaced::ReplacedSource;
77

88
pub mod config;

src/cargo/sources/registry/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ use crate::util::{restricted_names, CargoResult, Config, Filesystem, OptVersionR
184184
const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok";
185185
pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index";
186186
pub const CRATES_IO_REGISTRY: &str = "crates-io";
187+
pub const CRATES_IO_DOMAIN: &str = "crates.io";
187188
const CRATE_TEMPLATE: &str = "{crate}";
188189
const VERSION_TEMPLATE: &str = "{version}";
189190
const PREFIX_TEMPLATE: &str = "{prefix}";

0 commit comments

Comments
 (0)