From 593fa5a7cb7a9f47c53dfd3150c3d406a1b75b5b Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 14:07:40 -0500 Subject: [PATCH 01/16] Implement the [registries] table --- Cargo.toml | 2 ++ bench/bench.rs | 2 ++ src/de.rs | 27 ++++++++++++++++++++++++++- src/easy.rs | 40 +++++++++++++++++++++++++++++++++++++++- src/env.rs | 41 +++++++++++++++++++++++++++++++++++++++-- src/resolve.rs | 2 ++ 6 files changed, 110 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fa13479..8326ad9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = ["bench", "tests/helper/build-info", "tools/codegen"] doc-scrape-examples = false # Note: serde is public dependencies. +# Note: url is public dependencies. [dependencies] cfg-expr = "0.14" home = "0.5" @@ -30,6 +31,7 @@ once_cell = { version = "1", default-features = false } serde = { version = "1.0.103", features = ["derive"] } shell-escape = "0.1.5" toml = { version = "0.7", default-features = false, features = ["parse"] } +url = { version = "2", features = ["serde"] } [dev-dependencies] anyhow = "1" diff --git a/bench/bench.rs b/bench/bench.rs index 07617c0..a3d960a 100644 --- a/bench/bench.rs +++ b/bench/bench.rs @@ -64,6 +64,8 @@ fn reference(c: &mut Criterion) { ("CARGO_NET_RETRY", "1"), ("CARGO_NET_GIT_FETCH_WITH_CLI", "false"), ("CARGO_NET_OFFLINE", "false"), + ("CARGO_REGISTRIES_crates.io_INDEX", "https://github.com/rust-lang/crates.io-index"), + ("CARGO_REGISTRIES_crates.io_TOKEN", "00000000000000000000000000000000000"), ("CARGO_TERM_QUIET", "false"), ("CARGO_TERM_VERBOSE", "false"), ("CARGO_TERM_COLOR", "auto"), diff --git a/src/de.rs b/src/de.rs index 5d5c046..1a4efea 100644 --- a/src/de.rs +++ b/src/de.rs @@ -15,6 +15,7 @@ use std::{ }; use serde::{Deserialize, Serialize}; +use url::Url; pub use crate::value::{Definition, Value}; use crate::{ @@ -71,7 +72,12 @@ pub struct Config { pub net: NetConfig, // TODO: patch // TODO: profile - // TODO: registries + /// The `[registries]` table. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries) + #[serde(default)] + #[serde(skip_serializing_if = "BTreeMap::is_empty")] + pub registries: BTreeMap, // TODO: registry // TODO: source /// The `[target]` table. @@ -441,6 +447,25 @@ pub struct NetConfig { pub offline: Option>, } +/// A value of the `[registries]` table. +/// +/// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries) +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +#[non_exhaustive] +pub struct RegistriesConfigValue { + /// Specifies the URL of the git index for the registry. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnameindex) + #[serde(skip_serializing_if = "Option::is_none")] + pub index: Option>, + /// Specifies the authentication token for the given registry. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnametoken) + #[serde(skip_serializing_if = "Option::is_none")] + pub token: Option>, +} + /// The `[term]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#term) diff --git a/src/easy.rs b/src/easy.rs index 19e3128..cd5d524 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -9,6 +9,7 @@ use std::{ }; use serde::Serialize; +use url::Url; use crate::{ de::{self, split_encoded, split_space_separated, Color, Frequency, When}, @@ -65,7 +66,12 @@ pub struct Config { pub net: NetConfig, // TODO: patch // TODO: profile - // TODO: registries + /// The `[registries]` table. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries) + #[serde(default)] + #[serde(skip_serializing_if = "BTreeMap::is_empty")] + pub registries: BTreeMap, // TODO: registry // TODO: source /// The resolved `[target]` table. @@ -137,6 +143,10 @@ impl Config { let future_incompat_report = FutureIncompatReportConfig::from_unresolved(de.future_incompat_report); let net = NetConfig::from_unresolved(de.net); + let mut registries = BTreeMap::new(); + for (k, v) in de.registries { + registries.insert(k, RegistriesConfigValue::from_unresolved(v)); + } let term = TermConfig::from_unresolved(de.term); Ok(Self { @@ -146,6 +156,7 @@ impl Config { env, future_incompat_report, net, + registries, target: RefCell::new(BTreeMap::new()), de_target: de.target, term, @@ -701,6 +712,33 @@ impl NetConfig { } } +/// A value of the `[registries]` table. +/// +/// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries) +#[derive(Debug, Clone, Default, Serialize)] +#[serde(rename_all = "kebab-case")] +#[non_exhaustive] +pub struct RegistriesConfigValue { + /// Specifies the URL of the git index for the registry. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnameindex) + #[serde(skip_serializing_if = "Option::is_none")] + pub index: Option, + /// Specifies the authentication token for the given registry. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnametoken) + #[serde(skip_serializing_if = "Option::is_none")] + pub token: Option, +} + +impl RegistriesConfigValue { + pub(crate) fn from_unresolved(de: de::RegistriesConfigValue) -> Self { + let index = de.index.map(|v| v.val); + let token = de.token.map(|v| v.val); + Self { index, token } + } +} + /// The `[term]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#term) diff --git a/src/env.rs b/src/env.rs index 5ae594f..edd0e32 100644 --- a/src/env.rs +++ b/src/env.rs @@ -4,7 +4,7 @@ use crate::{ de::{ BuildConfig, Config, DocConfig, Flags, FutureIncompatReportConfig, NetConfig, PathAndArgs, - StringList, StringOrArray, TermConfig, TermProgress, + RegistriesConfigValue, StringList, StringOrArray, TermConfig, TermProgress, }, error::{Context as _, Error, Result}, resolve::ResolveContext, @@ -26,8 +26,8 @@ impl Config { /// (e.g., In environment variables, `-` and `.` in the target triple are replaced by `_`) #[doc(hidden)] // Not public API. pub fn apply_env(&mut self, cx: &ResolveContext) -> Result<()> { - // https://doc.rust-lang.org/nightly/cargo/reference/config.html#alias for (k, v) in &cx.env { + // https://doc.rust-lang.org/nightly/cargo/reference/config.html#alias if let Some(k) = k.strip_prefix("CARGO_ALIAS_") { self.alias.insert( k.to_owned(), @@ -38,6 +38,43 @@ impl Config { ); continue; } + + // https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries + if let Some(k) = k.strip_prefix("CARGO_REGISTRIES_") { + if let Some(k) = k.strip_suffix("_INDEX") { + let v = v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?; + let index = Some( + Value { + val: v.to_owned(), + definition: Some(Definition::Environment(k.to_owned().into())), + } + .parse() + .with_context(|| format!("failed to parse URL `{v}`"))?, + ); + if let Some(registries_config_value) = self.registries.get_mut(k) { + registries_config_value.index = index; + } else { + self.registries + .insert(k.to_owned(), RegistriesConfigValue { index, token: None }); + } + continue; + } + + if let Some(k) = k.strip_suffix("_TOKEN") { + let v = v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?; + let token = Some(Value { + val: v.to_owned(), + definition: Some(Definition::Environment(k.to_owned().into())), + }); + if let Some(registries_config_value) = self.registries.get_mut(k) { + registries_config_value.token = token; + } else { + self.registries + .insert(k.to_owned(), RegistriesConfigValue { index: None, token }); + } + continue; + } + } } // For self.target, we handle it in Config::resolve. diff --git a/src/resolve.rs b/src/resolve.rs index f9bd922..d6c961a 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -669,6 +669,8 @@ mod tests { ("CARGO_NET_RETRY", "1"), ("CARGO_NET_GIT_FETCH_WITH_CLI", "false"), ("CARGO_NET_OFFLINE", "false"), + ("CARGO_REGISTRIES_crates.io_INDEX", "https://github.com/rust-lang/crates.io-index"), + ("CARGO_REGISTRIES_crates.io_TOKEN", "00000000000000000000000000000000000"), ("CARGO_TERM_QUIET", "false"), ("CARGO_TERM_VERBOSE", "false"), ("CARGO_TERM_COLOR", "auto"), From 22f9ece043ed3ad195b76973dceeee57bef9738b Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 15:02:14 -0500 Subject: [PATCH 02/16] Fix CI failures --- .external-types.toml | 1 + src/gen/assert_impl.rs | 10 ++++++++++ src/gen/de.rs | 15 +++++++++++++++ src/gen/is_none.rs | 10 ++++++++++ 4 files changed, 36 insertions(+) diff --git a/.external-types.toml b/.external-types.toml index 2368e7c..9b5a81e 100644 --- a/.external-types.toml +++ b/.external-types.toml @@ -4,4 +4,5 @@ # The following are external types that are allowed to be exposed in our public API. allowed_external_types = [ "serde::*", + "url::Url", ] diff --git a/src/gen/assert_impl.rs b/src/gen/assert_impl.rs index 4c2cefb..ba5aca3 100644 --- a/src/gen/assert_impl.rs +++ b/src/gen/assert_impl.rs @@ -94,6 +94,11 @@ const _: fn() = || { assert_unpin::(); assert_unwind_safe::(); assert_ref_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unpin::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); assert_send::(); assert_sync::(); assert_unpin::(); @@ -179,6 +184,11 @@ const _: fn() = || { assert_unpin::(); assert_unwind_safe::(); assert_ref_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unpin::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); assert_send::(); assert_sync::(); assert_unpin::(); diff --git a/src/gen/de.rs b/src/gen/de.rs index 8b96c9e..e95d243 100644 --- a/src/gen/de.rs +++ b/src/gen/de.rs @@ -13,6 +13,7 @@ impl Merge for crate::de::Config { self.env.merge(from.env, force)?; self.future_incompat_report.merge(from.future_incompat_report, force)?; self.net.merge(from.net, force)?; + self.registries.merge(from.registries, force)?; self.target.merge(from.target, force)?; self.term.merge(from.term, force)?; Ok(()) @@ -26,6 +27,7 @@ impl SetPath for crate::de::Config { self.env.set_path(path); self.future_incompat_report.set_path(path); self.net.set_path(path); + self.registries.set_path(path); self.target.set_path(path); self.term.set_path(path); } @@ -127,6 +129,19 @@ impl SetPath for crate::de::NetConfig { self.offline.set_path(path); } } +impl Merge for crate::de::RegistriesConfigValue { + fn merge(&mut self, from: Self, force: bool) -> Result<()> { + self.index.merge(from.index, force)?; + self.token.merge(from.token, force)?; + Ok(()) + } +} +impl SetPath for crate::de::RegistriesConfigValue { + fn set_path(&mut self, path: &Path) { + self.index.set_path(path); + self.token.set_path(path); + } +} impl Merge for crate::de::TermConfig { fn merge(&mut self, from: Self, force: bool) -> Result<()> { self.quiet.merge(from.quiet, force)?; diff --git a/src/gen/is_none.rs b/src/gen/is_none.rs index 65f76e9..27140db 100644 --- a/src/gen/is_none.rs +++ b/src/gen/is_none.rs @@ -28,6 +28,11 @@ impl crate::easy::NetConfig { && self.offline.is_none() } } +impl crate::easy::RegistriesConfigValue { + pub(crate) fn is_none(&self) -> bool { + self.index.is_none() && self.token.is_none() + } +} impl crate::easy::TermConfig { pub(crate) fn is_none(&self) -> bool { self.quiet.is_none() && self.verbose.is_none() && self.color.is_none() @@ -64,6 +69,11 @@ impl crate::de::NetConfig { && self.offline.is_none() } } +impl crate::de::RegistriesConfigValue { + pub(crate) fn is_none(&self) -> bool { + self.index.is_none() && self.token.is_none() + } +} impl crate::de::TermConfig { pub(crate) fn is_none(&self) -> bool { self.quiet.is_none() && self.verbose.is_none() && self.color.is_none() From 33b620645db922dec71d5e99890e807e6360cc1e Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 15:16:54 -0500 Subject: [PATCH 03/16] Fix CI failures... again --- src/gen/is_none.rs | 10 ---------- src/merge.rs | 3 +++ tools/codegen/src/main.rs | 2 ++ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/gen/is_none.rs b/src/gen/is_none.rs index 27140db..65f76e9 100644 --- a/src/gen/is_none.rs +++ b/src/gen/is_none.rs @@ -28,11 +28,6 @@ impl crate::easy::NetConfig { && self.offline.is_none() } } -impl crate::easy::RegistriesConfigValue { - pub(crate) fn is_none(&self) -> bool { - self.index.is_none() && self.token.is_none() - } -} impl crate::easy::TermConfig { pub(crate) fn is_none(&self) -> bool { self.quiet.is_none() && self.verbose.is_none() && self.color.is_none() @@ -69,11 +64,6 @@ impl crate::de::NetConfig { && self.offline.is_none() } } -impl crate::de::RegistriesConfigValue { - pub(crate) fn is_none(&self) -> bool { - self.index.is_none() && self.token.is_none() - } -} impl crate::de::TermConfig { pub(crate) fn is_none(&self) -> bool { self.quiet.is_none() && self.verbose.is_none() && self.color.is_none() diff --git a/src/merge.rs b/src/merge.rs index 43c838c..b8d48aa 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -1,5 +1,7 @@ use std::collections::{btree_map, BTreeMap}; +use url::Url; + use crate::{ de, error::{Context as _, Result}, @@ -47,6 +49,7 @@ merge_non_container!(String); merge_non_container!(Color); merge_non_container!(Frequency); merge_non_container!(When); +merge_non_container!(Url); impl Merge for Option { fn merge(&mut self, from: Self, force: bool) -> Result<()> { diff --git a/tools/codegen/src/main.rs b/tools/codegen/src/main.rs index 3540298..7eaa9bf 100644 --- a/tools/codegen/src/main.rs +++ b/tools/codegen/src/main.rs @@ -209,12 +209,14 @@ fn gen_is_none() -> Result<()> { "de::PathAndArgs", "de::StringList", "de::TargetConfig", + "de::RegistriesConfigValue", "easy::Config", "easy::EnvConfigValue", "easy::Flags", "easy::PathAndArgs", "easy::StringList", "easy::TargetConfig", + "easy::RegistriesConfigValue", ]; let workspace_root = &workspace_root(); From 36eb3d2f761d2ed76292597c91043fb5f2fe4b0b Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 16:00:56 -0500 Subject: [PATCH 04/16] Implement the [registry] table --- bench/bench.rs | 2 ++ src/de.rs | 29 ++++++++++++++++++++++++++++- src/easy.rs | 39 ++++++++++++++++++++++++++++++++++++++- src/env.rs | 17 ++++++++++++++++- src/gen/assert_impl.rs | 10 ++++++++++ src/gen/de.rs | 15 +++++++++++++++ src/gen/is_none.rs | 10 ++++++++++ src/lib.rs | 3 ++- src/resolve.rs | 2 ++ 9 files changed, 123 insertions(+), 4 deletions(-) diff --git a/bench/bench.rs b/bench/bench.rs index a3d960a..fc3d997 100644 --- a/bench/bench.rs +++ b/bench/bench.rs @@ -66,6 +66,8 @@ fn reference(c: &mut Criterion) { ("CARGO_NET_OFFLINE", "false"), ("CARGO_REGISTRIES_crates.io_INDEX", "https://github.com/rust-lang/crates.io-index"), ("CARGO_REGISTRIES_crates.io_TOKEN", "00000000000000000000000000000000000"), + ("CARGO_REGISTRY_DEFAULT", "crates.io"), + ("CARGO_REGISTRY_TOKEN", "00000000000000000000000000000000000"), ("CARGO_TERM_QUIET", "false"), ("CARGO_TERM_VERBOSE", "false"), ("CARGO_TERM_COLOR", "auto"), diff --git a/src/de.rs b/src/de.rs index 1a4efea..4c97ea9 100644 --- a/src/de.rs +++ b/src/de.rs @@ -78,7 +78,12 @@ pub struct Config { #[serde(default)] #[serde(skip_serializing_if = "BTreeMap::is_empty")] pub registries: BTreeMap, - // TODO: registry + /// The `[registry]` table. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) + #[serde(default)] + #[serde(skip_serializing_if = "RegistryConfig::is_none")] + pub registry: RegistryConfig, // TODO: source /// The `[target]` table. /// @@ -466,6 +471,28 @@ pub struct RegistriesConfigValue { pub token: Option>, } +/// The `[registry]` table. +/// +/// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +#[non_exhaustive] +pub struct RegistryConfig { + /// The name of the registry (from the + /// [`registries` table](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries)) + /// to use by default for registry commands like + /// [`cargo publish`](https://doc.rust-lang.org/nightly/cargo/commands/cargo-publish.html). + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrydefault) + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option>, + /// Specifies the authentication token for [crates.io](https://crates.io/). + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrytoken) + #[serde(skip_serializing_if = "Option::is_none")] + pub token: Option>, +} + /// The `[term]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#term) diff --git a/src/easy.rs b/src/easy.rs index cd5d524..c92f3cb 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -72,7 +72,12 @@ pub struct Config { #[serde(default)] #[serde(skip_serializing_if = "BTreeMap::is_empty")] pub registries: BTreeMap, - // TODO: registry + /// The `[registry]` table. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) + #[serde(default)] + #[serde(skip_serializing_if = "RegistryConfig::is_none")] + pub registry: RegistryConfig, // TODO: source /// The resolved `[target]` table. #[serde(skip_deserializing)] @@ -147,6 +152,7 @@ impl Config { for (k, v) in de.registries { registries.insert(k, RegistriesConfigValue::from_unresolved(v)); } + let registry = RegistryConfig::from_unresolved(de.registry); let term = TermConfig::from_unresolved(de.term); Ok(Self { @@ -157,6 +163,7 @@ impl Config { future_incompat_report, net, registries, + registry, target: RefCell::new(BTreeMap::new()), de_target: de.target, term, @@ -739,6 +746,36 @@ impl RegistriesConfigValue { } } +/// The `[registry]` table. +/// +/// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) +#[derive(Debug, Clone, Default, Serialize)] +#[serde(rename_all = "kebab-case")] +#[non_exhaustive] +pub struct RegistryConfig { + /// The name of the registry (from the + /// [`registries` table](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries)) + /// to use by default for registry commands like + /// [`cargo publish`](https://doc.rust-lang.org/nightly/cargo/commands/cargo-publish.html). + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrydefault) + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + /// Specifies the authentication token for [crates.io](https://crates.io/). + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrytoken) + #[serde(skip_serializing_if = "Option::is_none")] + pub token: Option, +} + +impl RegistryConfig { + pub(crate) fn from_unresolved(de: de::RegistryConfig) -> Self { + let default = de.default.map(|v| v.val); + let token = de.token.map(|v| v.val); + Self { default, token } + } +} + /// The `[term]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#term) diff --git a/src/env.rs b/src/env.rs index edd0e32..cd2bf6f 100644 --- a/src/env.rs +++ b/src/env.rs @@ -4,7 +4,7 @@ use crate::{ de::{ BuildConfig, Config, DocConfig, Flags, FutureIncompatReportConfig, NetConfig, PathAndArgs, - RegistriesConfigValue, StringList, StringOrArray, TermConfig, TermProgress, + RegistriesConfigValue, RegistryConfig, StringList, StringOrArray, TermConfig, TermProgress, }, error::{Context as _, Error, Result}, resolve::ResolveContext, @@ -83,6 +83,7 @@ impl Config { self.doc.apply_env(cx)?; self.future_incompat_report.apply_env(cx)?; self.net.apply_env(cx)?; + self.registry.apply_env(cx)?; self.term.apply_env(cx)?; Ok(()) } @@ -271,6 +272,20 @@ impl ApplyEnv for NetConfig { } } +impl ApplyEnv for RegistryConfig { + fn apply_env(&mut self, cx: &ResolveContext) -> Result<()> { + // https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrydefault + if let Some(default) = cx.env_parse("CARGO_REGISTRY_DEFAULT")? { + self.default = Some(default); + } + // https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrytoken + if let Some(token) = cx.env_parse("CARGO_REGISTRY_TOKEN")? { + self.token = Some(token); + } + Ok(()) + } +} + impl ApplyEnv for TermConfig { fn apply_env(&mut self, cx: &ResolveContext) -> Result<()> { // https://doc.rust-lang.org/nightly/cargo/reference/config.html#termquiet diff --git a/src/gen/assert_impl.rs b/src/gen/assert_impl.rs index ba5aca3..436a298 100644 --- a/src/gen/assert_impl.rs +++ b/src/gen/assert_impl.rs @@ -99,6 +99,11 @@ const _: fn() = || { assert_unpin::(); assert_unwind_safe::(); assert_ref_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unpin::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); assert_send::(); assert_sync::(); assert_unpin::(); @@ -189,6 +194,11 @@ const _: fn() = || { assert_unpin::(); assert_unwind_safe::(); assert_ref_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unpin::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); assert_send::(); assert_sync::(); assert_unpin::(); diff --git a/src/gen/de.rs b/src/gen/de.rs index e95d243..7795ad8 100644 --- a/src/gen/de.rs +++ b/src/gen/de.rs @@ -14,6 +14,7 @@ impl Merge for crate::de::Config { self.future_incompat_report.merge(from.future_incompat_report, force)?; self.net.merge(from.net, force)?; self.registries.merge(from.registries, force)?; + self.registry.merge(from.registry, force)?; self.target.merge(from.target, force)?; self.term.merge(from.term, force)?; Ok(()) @@ -28,6 +29,7 @@ impl SetPath for crate::de::Config { self.future_incompat_report.set_path(path); self.net.set_path(path); self.registries.set_path(path); + self.registry.set_path(path); self.target.set_path(path); self.term.set_path(path); } @@ -142,6 +144,19 @@ impl SetPath for crate::de::RegistriesConfigValue { self.token.set_path(path); } } +impl Merge for crate::de::RegistryConfig { + fn merge(&mut self, from: Self, force: bool) -> Result<()> { + self.default.merge(from.default, force)?; + self.token.merge(from.token, force)?; + Ok(()) + } +} +impl SetPath for crate::de::RegistryConfig { + fn set_path(&mut self, path: &Path) { + self.default.set_path(path); + self.token.set_path(path); + } +} impl Merge for crate::de::TermConfig { fn merge(&mut self, from: Self, force: bool) -> Result<()> { self.quiet.merge(from.quiet, force)?; diff --git a/src/gen/is_none.rs b/src/gen/is_none.rs index 65f76e9..74313aa 100644 --- a/src/gen/is_none.rs +++ b/src/gen/is_none.rs @@ -28,6 +28,11 @@ impl crate::easy::NetConfig { && self.offline.is_none() } } +impl crate::easy::RegistryConfig { + pub(crate) fn is_none(&self) -> bool { + self.default.is_none() && self.token.is_none() + } +} impl crate::easy::TermConfig { pub(crate) fn is_none(&self) -> bool { self.quiet.is_none() && self.verbose.is_none() && self.color.is_none() @@ -64,6 +69,11 @@ impl crate::de::NetConfig { && self.offline.is_none() } } +impl crate::de::RegistryConfig { + pub(crate) fn is_none(&self) -> bool { + self.default.is_none() && self.token.is_none() + } +} impl crate::de::TermConfig { pub(crate) fn is_none(&self) -> bool { self.quiet.is_none() && self.verbose.is_none() && self.color.is_none() diff --git a/src/lib.rs b/src/lib.rs index 8168806..93a0408 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,7 +89,8 @@ pub use crate::de::{Color, Frequency, When}; pub use crate::{ easy::{ BuildConfig, Config, DocConfig, EnvConfigValue, Flags, FutureIncompatReportConfig, - NetConfig, PathAndArgs, StringList, TargetConfig, TermConfig, TermProgressConfig, + NetConfig, PathAndArgs, RegistriesConfigValue, RegistryConfig, StringList, TargetConfig, + TermConfig, TermProgressConfig, }, error::Error, resolve::{ResolveOptions, TargetTriple, TargetTripleRef}, diff --git a/src/resolve.rs b/src/resolve.rs index d6c961a..8fc7547 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -671,6 +671,8 @@ mod tests { ("CARGO_NET_OFFLINE", "false"), ("CARGO_REGISTRIES_crates.io_INDEX", "https://github.com/rust-lang/crates.io-index"), ("CARGO_REGISTRIES_crates.io_TOKEN", "00000000000000000000000000000000000"), + ("CARGO_REGISTRY_DEFAULT", "crates.io"), + ("CARGO_REGISTRY_TOKEN", "00000000000000000000000000000000000"), ("CARGO_TERM_QUIET", "false"), ("CARGO_TERM_VERBOSE", "false"), ("CARGO_TERM_COLOR", "auto"), From fc394691b754e859f2bcde40540fb0661c76586e Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 16:20:52 -0500 Subject: [PATCH 05/16] Add tests for the [registries] and [registry] table --- bench/bench.rs | 4 ++-- src/resolve.rs | 4 ++-- tests/fixtures/reference/.cargo/config.toml | 15 ++++++++------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bench/bench.rs b/bench/bench.rs index fc3d997..53c622b 100644 --- a/bench/bench.rs +++ b/bench/bench.rs @@ -64,8 +64,8 @@ fn reference(c: &mut Criterion) { ("CARGO_NET_RETRY", "1"), ("CARGO_NET_GIT_FETCH_WITH_CLI", "false"), ("CARGO_NET_OFFLINE", "false"), - ("CARGO_REGISTRIES_crates.io_INDEX", "https://github.com/rust-lang/crates.io-index"), - ("CARGO_REGISTRIES_crates.io_TOKEN", "00000000000000000000000000000000000"), + ("CARGO_REGISTRIES_crates-io_INDEX", "https://github.com/rust-lang/crates.io-index"), + ("CARGO_REGISTRIES_crates-io_TOKEN", "00000000000000000000000000000000000"), ("CARGO_REGISTRY_DEFAULT", "crates.io"), ("CARGO_REGISTRY_TOKEN", "00000000000000000000000000000000000"), ("CARGO_TERM_QUIET", "false"), diff --git a/src/resolve.rs b/src/resolve.rs index 8fc7547..cca4cfa 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -669,8 +669,8 @@ mod tests { ("CARGO_NET_RETRY", "1"), ("CARGO_NET_GIT_FETCH_WITH_CLI", "false"), ("CARGO_NET_OFFLINE", "false"), - ("CARGO_REGISTRIES_crates.io_INDEX", "https://github.com/rust-lang/crates.io-index"), - ("CARGO_REGISTRIES_crates.io_TOKEN", "00000000000000000000000000000000000"), + ("CARGO_REGISTRIES_crates-io_INDEX", "https://github.com/rust-lang/crates.io-index"), + ("CARGO_REGISTRIES_crates-io_TOKEN", "00000000000000000000000000000000000"), ("CARGO_REGISTRY_DEFAULT", "crates.io"), ("CARGO_REGISTRY_TOKEN", "00000000000000000000000000000000000"), ("CARGO_TERM_QUIET", "false"), diff --git a/tests/fixtures/reference/.cargo/config.toml b/tests/fixtures/reference/.cargo/config.toml index 2a0ac1e..779c6cb 100644 --- a/tests/fixtures/reference/.cargo/config.toml +++ b/tests/fixtures/reference/.cargo/config.toml @@ -82,13 +82,14 @@ offline = true # do not access the network # [profile..package.] # Override profile for a package. # # Same keys for a normal profile (minus `panic`, `lto`, and `rpath`). -# [registries.] # registries other than crates.io -# index = "…" # URL of the registry index -# token = "…" # authentication token for the registry - -# [registry] -# default = "…" # name of the default registry -# token = "…" # authentication token for crates.io +[registries.crates-io] # registries other than crates.io +index = "https://github.com/rust-lang/crates.io-index" # URL of the registry index +token = "00000000000000000000000000000000000" # authentication token for the registry +protocol = "git" + +[registry] +default = "crates-io" # name of the default registry +token = "00000000000000000000000000000000000" # authentication token for crates.io # [source.] # source definition and replacement # replace-with = "…" # replace this source with the given named source From f60b1e18b149a2c72b9ddb86eda77c501a238c3e Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 17:26:25 -0500 Subject: [PATCH 06/16] Implement the registries.crates-io.protocol value --- src/de.rs | 33 +++++++++++++++++++++++++++++++++ src/easy.rs | 27 ++++++++++++++++++++++++++- src/env.rs | 42 +++++++++++++++++++++++++++++++++--------- src/gen/assert_impl.rs | 10 ++++++++++ src/gen/de.rs | 2 ++ src/lib.rs | 4 ++-- src/merge.rs | 3 ++- 7 files changed, 108 insertions(+), 13 deletions(-) diff --git a/src/de.rs b/src/de.rs index 4c97ea9..a34e288 100644 --- a/src/de.rs +++ b/src/de.rs @@ -469,6 +469,39 @@ pub struct RegistriesConfigValue { /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnametoken) #[serde(skip_serializing_if = "Option::is_none")] pub token: Option>, + /// Specifies the protocol used to access crates.io. + /// Not allowed for any registries besides crates.io. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriescrates-ioprotocol) + #[serde(skip_serializing_if = "Option::is_none")] + pub protocol: Option>, +} + +/// Specifies the protocol used to access crates.io. +/// +/// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriescrates-ioprotocol) +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +#[non_exhaustive] +pub enum RegistriesProtocol { + /// Causes Cargo to clone the entire index of all packages ever published to + /// [crates.io](https://crates.io/) from . + Git, + /// A newer protocol which uses HTTPS to download only what is necessary from + /// . + Sparse, +} + +impl FromStr for RegistriesProtocol { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s { + "git" => Ok(RegistriesProtocol::Git), + "sparse" => Ok(RegistriesProtocol::Sparse), + _ => bail!("CARGO_REGISTRIES_CRATES_IO_PROTOCOL environment variable must be `git` or `sparse`"), + } + } } /// The `[registry]` table. diff --git a/src/easy.rs b/src/easy.rs index c92f3cb..638b156 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -736,16 +736,41 @@ pub struct RegistriesConfigValue { /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnametoken) #[serde(skip_serializing_if = "Option::is_none")] pub token: Option, + /// Specifies the protocol used to access crates.io. + /// Not allowed for any registries besides crates.io. + /// + /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriescrates-ioprotocol) + #[serde(skip_serializing_if = "Option::is_none")] + pub protocol: Option, } impl RegistriesConfigValue { pub(crate) fn from_unresolved(de: de::RegistriesConfigValue) -> Self { let index = de.index.map(|v| v.val); let token = de.token.map(|v| v.val); - Self { index, token } + let protocol = de.protocol.map(|v| match v.val { + de::RegistriesProtocol::Git => RegistriesProtocol::Git, + de::RegistriesProtocol::Sparse => RegistriesProtocol::Sparse, + }); + Self { index, token, protocol } } } +/// Specifies the protocol used to access crates.io. +/// +/// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriescrates-ioprotocol) +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "kebab-case")] +#[non_exhaustive] +pub enum RegistriesProtocol { + /// Causes Cargo to clone the entire index of all packages ever published to + /// [crates.io](https://crates.io/) from . + Git, + /// A newer protocol which uses HTTPS to download only what is necessary from + /// . + Sparse, +} + /// The `[registry]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) diff --git a/src/env.rs b/src/env.rs index cd2bf6f..a1293bb 100644 --- a/src/env.rs +++ b/src/env.rs @@ -38,9 +38,8 @@ impl Config { ); continue; } - // https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries - if let Some(k) = k.strip_prefix("CARGO_REGISTRIES_") { + else if let Some(k) = k.strip_prefix("CARGO_REGISTRIES_") { if let Some(k) = k.strip_suffix("_INDEX") { let v = v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?; let index = Some( @@ -54,13 +53,13 @@ impl Config { if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.index = index; } else { - self.registries - .insert(k.to_owned(), RegistriesConfigValue { index, token: None }); + self.registries.insert( + k.to_owned(), + RegistriesConfigValue { index, token: None, protocol: None }, + ); } continue; - } - - if let Some(k) = k.strip_suffix("_TOKEN") { + } else if let Some(k) = k.strip_suffix("_TOKEN") { let v = v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?; let token = Some(Value { val: v.to_owned(), @@ -69,8 +68,33 @@ impl Config { if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.token = token; } else { - self.registries - .insert(k.to_owned(), RegistriesConfigValue { index: None, token }); + self.registries.insert( + k.to_owned(), + RegistriesConfigValue { index: None, token, protocol: None }, + ); + } + continue; + } else if k == "CRATES_IO_PROTOCOL" { + let k = "crates-io"; + let v = v.to_str().ok_or_else(|| { + Error::env_not_unicode("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", v.clone()) + })?; + let protocol = Some( + Value { + val: v.to_owned(), + definition: Some(Definition::Environment( + "CARGO_REGISTRIES_CRATES_IO_PROTOCOL".into(), + )), + } + .parse()?, + ); + if let Some(registries_config_value) = self.registries.get_mut(k) { + registries_config_value.protocol = protocol; + } else { + self.registries.insert( + k.to_owned(), + RegistriesConfigValue { index: None, token: None, protocol }, + ); } continue; } diff --git a/src/gen/assert_impl.rs b/src/gen/assert_impl.rs index 436a298..c658878 100644 --- a/src/gen/assert_impl.rs +++ b/src/gen/assert_impl.rs @@ -99,6 +99,11 @@ const _: fn() = || { assert_unpin::(); assert_unwind_safe::(); assert_ref_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unpin::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); assert_send::(); assert_sync::(); assert_unpin::(); @@ -194,6 +199,11 @@ const _: fn() = || { assert_unpin::(); assert_unwind_safe::(); assert_ref_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unpin::(); + assert_unwind_safe::(); + assert_ref_unwind_safe::(); assert_send::(); assert_sync::(); assert_unpin::(); diff --git a/src/gen/de.rs b/src/gen/de.rs index 7795ad8..0af2c55 100644 --- a/src/gen/de.rs +++ b/src/gen/de.rs @@ -135,6 +135,7 @@ impl Merge for crate::de::RegistriesConfigValue { fn merge(&mut self, from: Self, force: bool) -> Result<()> { self.index.merge(from.index, force)?; self.token.merge(from.token, force)?; + self.protocol.merge(from.protocol, force)?; Ok(()) } } @@ -142,6 +143,7 @@ impl SetPath for crate::de::RegistriesConfigValue { fn set_path(&mut self, path: &Path) { self.index.set_path(path); self.token.set_path(path); + self.protocol.set_path(path); } } impl Merge for crate::de::RegistryConfig { diff --git a/src/lib.rs b/src/lib.rs index 93a0408..fb1b53c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,8 +89,8 @@ pub use crate::de::{Color, Frequency, When}; pub use crate::{ easy::{ BuildConfig, Config, DocConfig, EnvConfigValue, Flags, FutureIncompatReportConfig, - NetConfig, PathAndArgs, RegistriesConfigValue, RegistryConfig, StringList, TargetConfig, - TermConfig, TermProgressConfig, + NetConfig, PathAndArgs, RegistriesConfigValue, RegistriesProtocol, RegistryConfig, + StringList, TargetConfig, TermConfig, TermProgressConfig, }, error::Error, resolve::{ResolveOptions, TargetTriple, TargetTripleRef}, diff --git a/src/merge.rs b/src/merge.rs index b8d48aa..af20d67 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -3,7 +3,7 @@ use std::collections::{btree_map, BTreeMap}; use url::Url; use crate::{ - de, + de::{self, RegistriesProtocol}, error::{Context as _, Result}, value::Value, Color, Frequency, When, @@ -50,6 +50,7 @@ merge_non_container!(Color); merge_non_container!(Frequency); merge_non_container!(When); merge_non_container!(Url); +merge_non_container!(RegistriesProtocol); impl Merge for Option { fn merge(&mut self, from: Self, force: bool) -> Result<()> { From d375db582565d9b331e4b7546b9d0eba4dab2d40 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 18:01:51 -0500 Subject: [PATCH 07/16] Fix CI failures --- src/env.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/env.rs b/src/env.rs index a1293bb..7d6184b 100644 --- a/src/env.rs +++ b/src/env.rs @@ -53,10 +53,11 @@ impl Config { if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.index = index; } else { - self.registries.insert( - k.to_owned(), - RegistriesConfigValue { index, token: None, protocol: None }, - ); + self.registries.insert(k.to_owned(), RegistriesConfigValue { + index, + token: None, + protocol: None, + }); } continue; } else if let Some(k) = k.strip_suffix("_TOKEN") { @@ -68,10 +69,11 @@ impl Config { if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.token = token; } else { - self.registries.insert( - k.to_owned(), - RegistriesConfigValue { index: None, token, protocol: None }, - ); + self.registries.insert(k.to_owned(), RegistriesConfigValue { + index: None, + token, + protocol: None, + }); } continue; } else if k == "CRATES_IO_PROTOCOL" { @@ -91,10 +93,11 @@ impl Config { if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.protocol = protocol; } else { - self.registries.insert( - k.to_owned(), - RegistriesConfigValue { index: None, token: None, protocol }, - ); + self.registries.insert(k.to_owned(), RegistriesConfigValue { + index: None, + token: None, + protocol, + }); } continue; } From 84391a6dc198f8f1951460ae49bc6808abb11245 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 18:16:58 -0500 Subject: [PATCH 08/16] Use full environment variable names in definitions and errors --- src/env.rs | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/env.rs b/src/env.rs index 7d6184b..0fa5d56 100644 --- a/src/env.rs +++ b/src/env.rs @@ -27,13 +27,16 @@ impl Config { #[doc(hidden)] // Not public API. pub fn apply_env(&mut self, cx: &ResolveContext) -> Result<()> { for (k, v) in &cx.env { + let definition = Definition::Environment(k.to_owned().into()); + let error_env_not_unicode = || Error::env_not_unicode(k, v.clone()); + // https://doc.rust-lang.org/nightly/cargo/reference/config.html#alias if let Some(k) = k.strip_prefix("CARGO_ALIAS_") { self.alias.insert( k.to_owned(), StringList::from_string( - v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?, - Some(&Definition::Environment(k.to_owned().into())), + v.to_str().ok_or_else(error_env_not_unicode)?, + Some(&definition), ), ); continue; @@ -41,14 +44,11 @@ impl Config { // https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries else if let Some(k) = k.strip_prefix("CARGO_REGISTRIES_") { if let Some(k) = k.strip_suffix("_INDEX") { - let v = v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?; + let v = v.to_str().ok_or_else(error_env_not_unicode)?; let index = Some( - Value { - val: v.to_owned(), - definition: Some(Definition::Environment(k.to_owned().into())), - } - .parse() - .with_context(|| format!("failed to parse URL `{v}`"))?, + Value { val: v.to_owned(), definition: Some(definition) } + .parse() + .with_context(|| format!("failed to parse URL `{v}`"))?, ); if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.index = index; @@ -61,11 +61,8 @@ impl Config { } continue; } else if let Some(k) = k.strip_suffix("_TOKEN") { - let v = v.to_str().ok_or_else(|| Error::env_not_unicode(k, v.clone()))?; - let token = Some(Value { - val: v.to_owned(), - definition: Some(Definition::Environment(k.to_owned().into())), - }); + let v = v.to_str().ok_or_else(error_env_not_unicode)?; + let token = Some(Value { val: v.to_owned(), definition: Some(definition) }); if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.token = token; } else { @@ -78,18 +75,9 @@ impl Config { continue; } else if k == "CRATES_IO_PROTOCOL" { let k = "crates-io"; - let v = v.to_str().ok_or_else(|| { - Error::env_not_unicode("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", v.clone()) - })?; - let protocol = Some( - Value { - val: v.to_owned(), - definition: Some(Definition::Environment( - "CARGO_REGISTRIES_CRATES_IO_PROTOCOL".into(), - )), - } - .parse()?, - ); + let v = v.to_str().ok_or_else(error_env_not_unicode)?; + let protocol = + Some(Value { val: v.to_owned(), definition: Some(definition) }.parse()?); if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.protocol = protocol; } else { From b75139347857313d0cfab34ba3d47c1c4cb61ba1 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 18:22:36 -0500 Subject: [PATCH 09/16] Fix CI failures --- src/env.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env.rs b/src/env.rs index 0fa5d56..0ce3522 100644 --- a/src/env.rs +++ b/src/env.rs @@ -27,7 +27,7 @@ impl Config { #[doc(hidden)] // Not public API. pub fn apply_env(&mut self, cx: &ResolveContext) -> Result<()> { for (k, v) in &cx.env { - let definition = Definition::Environment(k.to_owned().into()); + let definition = Definition::Environment(k.clone().into()); let error_env_not_unicode = || Error::env_not_unicode(k, v.clone()); // https://doc.rust-lang.org/nightly/cargo/reference/config.html#alias From cbcfa8cbb7a38ae4b19305d49739b16effd9432c Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sat, 4 Mar 2023 19:01:29 -0500 Subject: [PATCH 10/16] Add notices about the credentials file not being read to the docs --- src/de.rs | 8 ++++++++ src/easy.rs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/de.rs b/src/de.rs index a34e288..747a930 100644 --- a/src/de.rs +++ b/src/de.rs @@ -466,6 +466,10 @@ pub struct RegistriesConfigValue { pub index: Option>, /// Specifies the authentication token for the given registry. /// + /// Note: This library does not read any values in the + /// [credentials](https://doc.rust-lang.org/nightly/cargo/reference/config.html#credentials) + /// file. + /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnametoken) #[serde(skip_serializing_if = "Option::is_none")] pub token: Option>, @@ -521,6 +525,10 @@ pub struct RegistryConfig { pub default: Option>, /// Specifies the authentication token for [crates.io](https://crates.io/). /// + /// Note: This library does not read any values in the + /// [credentials](https://doc.rust-lang.org/nightly/cargo/reference/config.html#credentials) + /// file. + /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrytoken) #[serde(skip_serializing_if = "Option::is_none")] pub token: Option>, diff --git a/src/easy.rs b/src/easy.rs index 638b156..d36ac29 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -733,6 +733,10 @@ pub struct RegistriesConfigValue { pub index: Option, /// Specifies the authentication token for the given registry. /// + /// Note: This library does not read any values in the + /// [credentials](https://doc.rust-lang.org/nightly/cargo/reference/config.html#credentials) + /// file. + /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnametoken) #[serde(skip_serializing_if = "Option::is_none")] pub token: Option, @@ -788,6 +792,10 @@ pub struct RegistryConfig { pub default: Option, /// Specifies the authentication token for [crates.io](https://crates.io/). /// + /// Note: This library does not read any values in the + /// [credentials](https://doc.rust-lang.org/nightly/cargo/reference/config.html#credentials) + /// file. + /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registrytoken) #[serde(skip_serializing_if = "Option::is_none")] pub token: Option, From c2e93982a750d9dcb9bc5f5dd96bc827ac3448d5 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sun, 5 Mar 2023 10:25:35 -0500 Subject: [PATCH 11/16] Make definition a closure to clone lazily --- src/env.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/env.rs b/src/env.rs index 0ce3522..0d82a2b 100644 --- a/src/env.rs +++ b/src/env.rs @@ -27,7 +27,7 @@ impl Config { #[doc(hidden)] // Not public API. pub fn apply_env(&mut self, cx: &ResolveContext) -> Result<()> { for (k, v) in &cx.env { - let definition = Definition::Environment(k.clone().into()); + let definition = || Some(Definition::Environment(k.clone().into())); let error_env_not_unicode = || Error::env_not_unicode(k, v.clone()); // https://doc.rust-lang.org/nightly/cargo/reference/config.html#alias @@ -36,7 +36,7 @@ impl Config { k.to_owned(), StringList::from_string( v.to_str().ok_or_else(error_env_not_unicode)?, - Some(&definition), + definition().as_ref(), ), ); continue; @@ -46,7 +46,7 @@ impl Config { if let Some(k) = k.strip_suffix("_INDEX") { let v = v.to_str().ok_or_else(error_env_not_unicode)?; let index = Some( - Value { val: v.to_owned(), definition: Some(definition) } + Value { val: v.to_owned(), definition: definition() } .parse() .with_context(|| format!("failed to parse URL `{v}`"))?, ); @@ -62,7 +62,7 @@ impl Config { continue; } else if let Some(k) = k.strip_suffix("_TOKEN") { let v = v.to_str().ok_or_else(error_env_not_unicode)?; - let token = Some(Value { val: v.to_owned(), definition: Some(definition) }); + let token = Some(Value { val: v.to_owned(), definition: definition() }); if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.token = token; } else { @@ -77,7 +77,7 @@ impl Config { let k = "crates-io"; let v = v.to_str().ok_or_else(error_env_not_unicode)?; let protocol = - Some(Value { val: v.to_owned(), definition: Some(definition) }.parse()?); + Some(Value { val: v.to_owned(), definition: definition() }.parse()?); if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.protocol = protocol; } else { From a38865aa24364154588feff212bfd1c142f70775 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sun, 5 Mar 2023 10:50:02 -0500 Subject: [PATCH 12/16] Remove the url dependency --- .external-types.toml | 1 - Cargo.toml | 2 -- src/de.rs | 3 +-- src/easy.rs | 3 +-- src/env.rs | 6 +----- src/merge.rs | 3 --- 6 files changed, 3 insertions(+), 15 deletions(-) diff --git a/.external-types.toml b/.external-types.toml index 9b5a81e..2368e7c 100644 --- a/.external-types.toml +++ b/.external-types.toml @@ -4,5 +4,4 @@ # The following are external types that are allowed to be exposed in our public API. allowed_external_types = [ "serde::*", - "url::Url", ] diff --git a/Cargo.toml b/Cargo.toml index 8326ad9..fa13479 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ members = ["bench", "tests/helper/build-info", "tools/codegen"] doc-scrape-examples = false # Note: serde is public dependencies. -# Note: url is public dependencies. [dependencies] cfg-expr = "0.14" home = "0.5" @@ -31,7 +30,6 @@ once_cell = { version = "1", default-features = false } serde = { version = "1.0.103", features = ["derive"] } shell-escape = "0.1.5" toml = { version = "0.7", default-features = false, features = ["parse"] } -url = { version = "2", features = ["serde"] } [dev-dependencies] anyhow = "1" diff --git a/src/de.rs b/src/de.rs index 747a930..beb5488 100644 --- a/src/de.rs +++ b/src/de.rs @@ -15,7 +15,6 @@ use std::{ }; use serde::{Deserialize, Serialize}; -use url::Url; pub use crate::value::{Definition, Value}; use crate::{ @@ -463,7 +462,7 @@ pub struct RegistriesConfigValue { /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnameindex) #[serde(skip_serializing_if = "Option::is_none")] - pub index: Option>, + pub index: Option>, /// Specifies the authentication token for the given registry. /// /// Note: This library does not read any values in the diff --git a/src/easy.rs b/src/easy.rs index d36ac29..5447030 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -9,7 +9,6 @@ use std::{ }; use serde::Serialize; -use url::Url; use crate::{ de::{self, split_encoded, split_space_separated, Color, Frequency, When}, @@ -730,7 +729,7 @@ pub struct RegistriesConfigValue { /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriesnameindex) #[serde(skip_serializing_if = "Option::is_none")] - pub index: Option, + pub index: Option, /// Specifies the authentication token for the given registry. /// /// Note: This library does not read any values in the diff --git a/src/env.rs b/src/env.rs index 0d82a2b..a841435 100644 --- a/src/env.rs +++ b/src/env.rs @@ -45,11 +45,7 @@ impl Config { else if let Some(k) = k.strip_prefix("CARGO_REGISTRIES_") { if let Some(k) = k.strip_suffix("_INDEX") { let v = v.to_str().ok_or_else(error_env_not_unicode)?; - let index = Some( - Value { val: v.to_owned(), definition: definition() } - .parse() - .with_context(|| format!("failed to parse URL `{v}`"))?, - ); + let index = Some(Value { val: v.to_owned(), definition: definition() }); if let Some(registries_config_value) = self.registries.get_mut(k) { registries_config_value.index = index; } else { diff --git a/src/merge.rs b/src/merge.rs index af20d67..e9b797f 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -1,7 +1,5 @@ use std::collections::{btree_map, BTreeMap}; -use url::Url; - use crate::{ de::{self, RegistriesProtocol}, error::{Context as _, Result}, @@ -49,7 +47,6 @@ merge_non_container!(String); merge_non_container!(Color); merge_non_container!(Frequency); merge_non_container!(When); -merge_non_container!(Url); merge_non_container!(RegistriesProtocol); impl Merge for Option { From ecf0fb6a3b08b2c8937f3d28571273570c0b0565 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sun, 5 Mar 2023 11:00:29 -0500 Subject: [PATCH 13/16] Add CARGO_REGISTRIES_CRATES_IO_PROTOCOL to the env variable tests --- bench/bench.rs | 3 ++- src/resolve.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bench/bench.rs b/bench/bench.rs index 53c622b..7890d21 100644 --- a/bench/bench.rs +++ b/bench/bench.rs @@ -66,8 +66,9 @@ fn reference(c: &mut Criterion) { ("CARGO_NET_OFFLINE", "false"), ("CARGO_REGISTRIES_crates-io_INDEX", "https://github.com/rust-lang/crates.io-index"), ("CARGO_REGISTRIES_crates-io_TOKEN", "00000000000000000000000000000000000"), - ("CARGO_REGISTRY_DEFAULT", "crates.io"), + ("CARGO_REGISTRY_DEFAULT", "crates-io"), ("CARGO_REGISTRY_TOKEN", "00000000000000000000000000000000000"), + ("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", "git"), ("CARGO_TERM_QUIET", "false"), ("CARGO_TERM_VERBOSE", "false"), ("CARGO_TERM_COLOR", "auto"), diff --git a/src/resolve.rs b/src/resolve.rs index cca4cfa..2a057e3 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -671,8 +671,9 @@ mod tests { ("CARGO_NET_OFFLINE", "false"), ("CARGO_REGISTRIES_crates-io_INDEX", "https://github.com/rust-lang/crates.io-index"), ("CARGO_REGISTRIES_crates-io_TOKEN", "00000000000000000000000000000000000"), - ("CARGO_REGISTRY_DEFAULT", "crates.io"), + ("CARGO_REGISTRY_DEFAULT", "crates-io"), ("CARGO_REGISTRY_TOKEN", "00000000000000000000000000000000000"), + ("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", "git"), ("CARGO_TERM_QUIET", "false"), ("CARGO_TERM_VERBOSE", "false"), ("CARGO_TERM_COLOR", "auto"), From c6d6c3716d0363824f3fc199c44647594dd10011 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sun, 5 Mar 2023 11:01:09 -0500 Subject: [PATCH 14/16] Implement FromStr for RegistriesProtocol consistently with other types --- src/de.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/de.rs b/src/de.rs index beb5488..f1df5c3 100644 --- a/src/de.rs +++ b/src/de.rs @@ -498,11 +498,11 @@ pub enum RegistriesProtocol { impl FromStr for RegistriesProtocol { type Err = Error; - fn from_str(s: &str) -> Result { - match s { - "git" => Ok(RegistriesProtocol::Git), - "sparse" => Ok(RegistriesProtocol::Sparse), - _ => bail!("CARGO_REGISTRIES_CRATES_IO_PROTOCOL environment variable must be `git` or `sparse`"), + fn from_str(protocol: &str) -> Result { + match protocol { + "git" => Ok(Self::Git), + "sparse" => Ok(Self::Sparse), + other => bail!("must be git or sparse, but found `{other}`"), } } } From 5bb3df2f52cc6d3e57b0848de288f10727fa8035 Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sun, 5 Mar 2023 11:26:50 -0500 Subject: [PATCH 15/16] Don't display token values in Debug implementations --- src/de.rs | 36 ++++++++++++++++++++++++++++++++++-- src/easy.rs | 28 ++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/de.rs b/src/de.rs index f1df5c3..e7b5742 100644 --- a/src/de.rs +++ b/src/de.rs @@ -8,6 +8,7 @@ use std::{ borrow::Cow, collections::BTreeMap, ffi::OsStr, + fmt::{self, Formatter}, fs, path::{Path, PathBuf}, slice, @@ -454,7 +455,7 @@ pub struct NetConfig { /// A value of the `[registries]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries) -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] #[non_exhaustive] pub struct RegistriesConfigValue { @@ -480,6 +481,22 @@ pub struct RegistriesConfigValue { pub protocol: Option>, } +impl fmt::Debug for RegistriesConfigValue { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let Self { index, token, protocol } = self; + let redacted_token = if let Some(token) = token { + Some(Value { val: "[REDACTED]", definition: token.definition.to_owned() }) + } else { + None + }; + f.debug_struct("RegistriesConfigValue") + .field("index", &index) + .field("token", &redacted_token) + .field("protocol", &protocol) + .finish() + } +} + /// Specifies the protocol used to access crates.io. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriescrates-ioprotocol) @@ -510,7 +527,7 @@ impl FromStr for RegistriesProtocol { /// The `[registry]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] #[non_exhaustive] pub struct RegistryConfig { @@ -533,6 +550,21 @@ pub struct RegistryConfig { pub token: Option>, } +impl fmt::Debug for RegistryConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let Self { default, token } = self; + let redacted_token = if let Some(token) = token { + Some(Value { val: "[REDACTED]", definition: token.definition.to_owned() }) + } else { + None + }; + f.debug_struct("RegistryConfig") + .field("default", &default) + .field("token", &redacted_token) + .finish() + } +} + /// The `[term]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#term) diff --git a/src/easy.rs b/src/easy.rs index 5447030..7a3ce30 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -3,6 +3,7 @@ use std::{ cell::RefCell, collections::BTreeMap, ffi::{OsStr, OsString}, + fmt::{self, Formatter}, ops, path::{Path, PathBuf}, process::Command, @@ -721,7 +722,7 @@ impl NetConfig { /// A value of the `[registries]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registries) -#[derive(Debug, Clone, Default, Serialize)] +#[derive(Clone, Default, Serialize)] #[serde(rename_all = "kebab-case")] #[non_exhaustive] pub struct RegistriesConfigValue { @@ -759,6 +760,18 @@ impl RegistriesConfigValue { } } +impl fmt::Debug for RegistriesConfigValue { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let Self { index, token, protocol } = self; + let redacted_token = if token.is_some() { Some("[REDACTED]") } else { None }; + f.debug_struct("RegistriesConfigValue") + .field("index", &index) + .field("token", &redacted_token) + .field("protocol", &protocol) + .finish_non_exhaustive() + } +} + /// Specifies the protocol used to access crates.io. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registriescrates-ioprotocol) @@ -777,7 +790,7 @@ pub enum RegistriesProtocol { /// The `[registry]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#registry) -#[derive(Debug, Clone, Default, Serialize)] +#[derive(Clone, Default, Serialize)] #[serde(rename_all = "kebab-case")] #[non_exhaustive] pub struct RegistryConfig { @@ -808,6 +821,17 @@ impl RegistryConfig { } } +impl fmt::Debug for RegistryConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let Self { default, token } = self; + let redacted_token = if token.is_some() { Some("[REDACTED]") } else { None }; + f.debug_struct("RegistryConfig") + .field("default", &default) + .field("token", &redacted_token) + .finish() + } +} + /// The `[term]` table. /// /// [reference](https://doc.rust-lang.org/nightly/cargo/reference/config.html#term) From d97ce4ec203a26853b0a4bd0edb80e571072814c Mon Sep 17 00:00:00 2001 From: yottalogical Date: Sun, 5 Mar 2023 13:17:47 -0500 Subject: [PATCH 16/16] Fix CI failures --- src/de.rs | 16 ++++++---------- src/easy.rs | 4 ++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/de.rs b/src/de.rs index e7b5742..c91a0a7 100644 --- a/src/de.rs +++ b/src/de.rs @@ -484,11 +484,9 @@ pub struct RegistriesConfigValue { impl fmt::Debug for RegistriesConfigValue { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let Self { index, token, protocol } = self; - let redacted_token = if let Some(token) = token { - Some(Value { val: "[REDACTED]", definition: token.definition.to_owned() }) - } else { - None - }; + let redacted_token = token + .as_ref() + .map(|token| Value { val: "[REDACTED]", definition: token.definition.clone() }); f.debug_struct("RegistriesConfigValue") .field("index", &index) .field("token", &redacted_token) @@ -553,11 +551,9 @@ pub struct RegistryConfig { impl fmt::Debug for RegistryConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let Self { default, token } = self; - let redacted_token = if let Some(token) = token { - Some(Value { val: "[REDACTED]", definition: token.definition.to_owned() }) - } else { - None - }; + let redacted_token = token + .as_ref() + .map(|token| Value { val: "[REDACTED]", definition: token.definition.clone() }); f.debug_struct("RegistryConfig") .field("default", &default) .field("token", &redacted_token) diff --git a/src/easy.rs b/src/easy.rs index 7a3ce30..bcdea39 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -763,7 +763,7 @@ impl RegistriesConfigValue { impl fmt::Debug for RegistriesConfigValue { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let Self { index, token, protocol } = self; - let redacted_token = if token.is_some() { Some("[REDACTED]") } else { None }; + let redacted_token = token.as_ref().map(|_| "[REDACTED]"); f.debug_struct("RegistriesConfigValue") .field("index", &index) .field("token", &redacted_token) @@ -824,7 +824,7 @@ impl RegistryConfig { impl fmt::Debug for RegistryConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let Self { default, token } = self; - let redacted_token = if token.is_some() { Some("[REDACTED]") } else { None }; + let redacted_token = token.as_ref().map(|_| "[REDACTED]"); f.debug_struct("RegistryConfig") .field("default", &default) .field("token", &redacted_token)