Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix printing multiple warning messages for unused fields in [registries] table #12439

Merged
merged 1 commit into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
}