Skip to content

Commit

Permalink
Fix printing multiple warning messages for unused fields in [registri…
Browse files Browse the repository at this point in the history
…es] table
  • Loading branch information
arlosi committed Aug 2, 2023
1 parent baebd2b commit 9ab8d61
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 10 deletions.
36 changes: 26 additions & 10 deletions src/cargo/util/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use cargo_credential::{

use core::fmt;
use serde::Deserialize;
use std::collections::HashMap;
use std::error::Error;
use time::{Duration, OffsetDateTime};
use url::Url;
Expand All @@ -31,7 +30,7 @@ use super::{
/// `[registries.NAME]` tables.
///
/// The values here should be kept in sync with `RegistryConfigExtended`
#[derive(Deserialize)]
#[derive(Deserialize, Clone, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct RegistryConfig {
pub index: Option<String>,
Expand Down Expand Up @@ -207,6 +206,19 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
pub fn registry_credential_config_raw(
config: &Config,
sid: &SourceId,
) -> CargoResult<Option<RegistryConfig>> {
let mut cache = config.registry_config();
if let Some(cfg) = cache.get(&sid) {
return Ok(cfg.clone());
}
let cfg = registry_credential_config_raw_uncached(config, sid)?;
cache.insert(*sid, cfg.clone());
return Ok(cfg);
}

fn registry_credential_config_raw_uncached(
config: &Config,
sid: &SourceId,
) -> CargoResult<Option<RegistryConfig>> {
log::trace!("loading credential config for {}", sid);
config.load_credentials()?;
Expand Down Expand Up @@ -237,6 +249,7 @@ pub fn registry_credential_config_raw(
// This also allows the authorization token for a registry to be set
// without knowing the registry name by using the _INDEX and _TOKEN
// environment variables.

let name = {
// Discover names from environment variables.
let index = sid.canonical_url();
Expand All @@ -256,14 +269,17 @@ pub fn registry_credential_config_raw(

// Discover names from the configuration only if none were found in the environment.
if names.len() == 0 {
names = config
.get::<HashMap<String, RegistryConfig>>("registries")?
.iter()
.filter_map(|(k, v)| Some((k, v.index.as_deref()?)))
.filter_map(|(k, v)| Some((k, CanonicalUrl::new(&v.into_url().ok()?).ok()?)))
.filter(|(_, v)| v == index)
.map(|(k, _)| k.to_string())
.collect();
if let Some(registries) = config.values()?.get("registries") {
let (registries, _) = registries.table("registries")?;
for (name, value) in registries {
if let Some(v) = value.table(&format!("registries.{name}"))?.0.get("index") {
let (v, _) = v.string(&format!("registries.{name}.index"))?;
if index == &CanonicalUrl::new(&v.into_url()?)? {
names.push(name.clone());
}
}
}
}
}
names.sort();
match names.len() {
Expand Down
12 changes: 12 additions & 0 deletions src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub use target::{TargetCfgConfig, TargetConfig};
mod environment;
use environment::Env;

use super::auth::RegistryConfig;

// Helper macro for creating typed access methods.
macro_rules! get_value_typed {
($name:ident, $ty:ty, $variant:ident, $expected:expr) => {
Expand Down Expand Up @@ -208,6 +210,8 @@ pub struct Config {
/// Cache of credentials from configuration or credential providers.
/// Maps from url to credential value.
credential_cache: LazyCell<RefCell<HashMap<CanonicalUrl, CredentialCacheValue>>>,
/// Cache of registry config from from the [registries] table.
registry_config: LazyCell<RefCell<HashMap<SourceId, Option<RegistryConfig>>>>,
/// Lock, if held, of the global package cache along with the number of
/// acquisitions so far.
package_cache_lock: RefCell<Option<(Option<FileLock>, usize)>>,
Expand Down Expand Up @@ -299,6 +303,7 @@ impl Config {
env,
updated_sources: LazyCell::new(),
credential_cache: LazyCell::new(),
registry_config: LazyCell::new(),
package_cache_lock: RefCell::new(None),
http_config: LazyCell::new(),
future_incompat_config: LazyCell::new(),
Expand Down Expand Up @@ -488,6 +493,13 @@ impl Config {
.borrow_mut()
}

/// Cache of already parsed registries from the [registries] table.
pub(crate) fn registry_config(&self) -> RefMut<'_, HashMap<SourceId, Option<RegistryConfig>>> {
self.registry_config
.borrow_with(|| RefCell::new(HashMap::new()))
.borrow_mut()
}

/// Gets all config values from disk.
///
/// This will lazy-load the values as necessary. Callers are responsible
Expand Down
41 changes: 41 additions & 0 deletions tests/testsuite/alt_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,3 +1506,44 @@ fn publish_with_transitive_dep() {
.build();
p2.cargo("publish").run();
}

#[cargo_test]
fn warn_for_unused_fields() {
let _ = RegistryBuilder::new()
.no_configure_token()
.alternative()
.build();
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
"[registry]
unexpected-field = 'foo'
[registries.alternative]
unexpected-field = 'foo'
",
)
.build();

p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr(
"\
[UPDATING] `alternative` index
[WARNING] unused config key `registries.alternative.unexpected-field` in `[..]config.toml`
[ERROR] no token found for `alternative`, please run `cargo login --registry alternative`
or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN",
)
.run();

p.cargo("publish --registry crates-io")
.with_status(101)
.with_stderr(
"\
[UPDATING] crates.io index
[WARNING] unused config key `registry.unexpected-field` in `[..]config.toml`
[ERROR] no token found, please run `cargo login`
or use environment variable CARGO_REGISTRY_TOKEN",
)
.run();
}

0 comments on commit 9ab8d61

Please sign in to comment.