Skip to content

Commit f955ddc

Browse files
committed
Auto merge of #10471 - Eh2406:credential_process, r=weihanglo
Use types to make clere (credential process || token) `RegistryConfig` represents what credentials we have read from disk. It was a ``` token: Option<String>, credential_process: Option<(PathBuf, Vec<String>)>, ``` with runtime checks that they were not both `Some`. This changes it to be an Enum `None|Token|Process`. There is somewhat more code, but I think this is clearer. This also changed some `Option<String>` arguments to `Option<&str>`.
2 parents 56ccd1f + 9588f83 commit f955ddc

File tree

2 files changed

+79
-52
lines changed

2 files changed

+79
-52
lines changed

src/cargo/ops/registry.rs

+71-45
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,41 @@ mod auth;
3636
///
3737
/// This is loaded based on the `--registry` flag and the config settings.
3838
#[derive(Debug)]
39-
pub struct RegistryConfig {
40-
/// The index URL. If `None`, use crates.io.
41-
pub index: Option<String>,
39+
pub enum RegistryConfig {
40+
None,
4241
/// The authentication token.
43-
pub token: Option<String>,
42+
Token(String),
4443
/// Process used for fetching a token.
45-
pub credential_process: Option<(PathBuf, Vec<String>)>,
44+
Process((PathBuf, Vec<String>)),
45+
}
46+
47+
impl RegistryConfig {
48+
/// Returns `true` if the credential is [`None`].
49+
///
50+
/// [`None`]: Credential::None
51+
pub fn is_none(&self) -> bool {
52+
matches!(self, Self::None)
53+
}
54+
/// Returns `true` if the credential is [`Token`].
55+
///
56+
/// [`Token`]: Credential::Token
57+
pub fn is_token(&self) -> bool {
58+
matches!(self, Self::Token(..))
59+
}
60+
pub fn as_token(&self) -> Option<&str> {
61+
if let Self::Token(v) = self {
62+
Some(&*v)
63+
} else {
64+
None
65+
}
66+
}
67+
pub fn as_process(&self) -> Option<&(PathBuf, Vec<String>)> {
68+
if let Self::Process(v) = self {
69+
Some(v)
70+
} else {
71+
None
72+
}
73+
}
4674
}
4775

4876
pub struct PublishOpts<'cfg> {
@@ -98,8 +126,8 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
98126
let (mut registry, _reg_cfg, reg_id) = registry(
99127
opts.config,
100128
opts.token.clone(),
101-
opts.index.clone(),
102-
publish_registry,
129+
opts.index.as_deref(),
130+
publish_registry.as_deref(),
103131
true,
104132
!opts.dry_run,
105133
)?;
@@ -336,21 +364,18 @@ pub fn registry_configuration(
336364
) -> CargoResult<RegistryConfig> {
337365
let err_both = |token_key: &str, proc_key: &str| {
338366
Err(format_err!(
339-
"both `{TOKEN_KEY}` and `{PROC_KEY}` \
367+
"both `{token_key}` and `{proc_key}` \
340368
were specified in the config\n\
341369
Only one of these values may be set, remove one or the other to proceed.",
342-
TOKEN_KEY = token_key,
343-
PROC_KEY = proc_key,
344370
))
345371
};
346372
// `registry.default` is handled in command-line parsing.
347-
let (index, token, process) = match registry {
373+
let (token, process) = match registry {
348374
Some(registry) => {
349-
let index = Some(config.get_registry_index(registry)?.to_string());
350-
let token_key = format!("registries.{}.token", registry);
375+
let token_key = format!("registries.{registry}.token");
351376
let token = config.get_string(&token_key)?.map(|p| p.val);
352377
let process = if config.cli_unstable().credential_process {
353-
let mut proc_key = format!("registries.{}.credential-process", registry);
378+
let mut proc_key = format!("registries.{registry}.credential-process");
354379
let mut process = config.get::<Option<config::PathAndArgs>>(&proc_key)?;
355380
if process.is_none() && token.is_none() {
356381
// This explicitly ignores the global credential-process if
@@ -364,7 +389,7 @@ pub fn registry_configuration(
364389
} else {
365390
None
366391
};
367-
(index, token, process)
392+
(token, process)
368393
}
369394
None => {
370395
// Use crates.io default.
@@ -380,17 +405,18 @@ pub fn registry_configuration(
380405
} else {
381406
None
382407
};
383-
(None, token, process)
408+
(token, process)
384409
}
385410
};
386411

387412
let credential_process =
388413
process.map(|process| (process.path.resolve_program(config), process.args));
389414

390-
Ok(RegistryConfig {
391-
index,
392-
token,
393-
credential_process,
415+
Ok(match (token, credential_process) {
416+
(None, None) => RegistryConfig::None,
417+
(None, Some(process)) => RegistryConfig::Process(process),
418+
(Some(x), None) => RegistryConfig::Token(x),
419+
(Some(_), Some(_)) => unreachable!("Only one of these values may be set."),
394420
})
395421
}
396422

@@ -408,8 +434,8 @@ pub fn registry_configuration(
408434
fn registry(
409435
config: &Config,
410436
token: Option<String>,
411-
index: Option<String>,
412-
registry: Option<String>,
437+
index: Option<&str>,
438+
registry: Option<&str>,
413439
force_update: bool,
414440
validate_token: bool,
415441
) -> CargoResult<(Registry, RegistryConfig, SourceId)> {
@@ -418,9 +444,12 @@ fn registry(
418444
bail!("both `--index` and `--registry` should not be set at the same time");
419445
}
420446
// Parse all configuration options
421-
let reg_cfg = registry_configuration(config, registry.as_deref())?;
422-
let opt_index = reg_cfg.index.as_deref().or_else(|| index.as_deref());
423-
let sid = get_source_id(config, opt_index, registry.as_deref())?;
447+
let reg_cfg = registry_configuration(config, registry)?;
448+
let opt_index = registry
449+
.map(|r| config.get_registry_index(r))
450+
.transpose()?
451+
.map(|u| u.to_string());
452+
let sid = get_source_id(config, opt_index.as_deref().or(index), registry)?;
424453
if !sid.is_remote_registry() {
425454
bail!(
426455
"{} does not support API commands.\n\
@@ -459,7 +488,7 @@ fn registry(
459488
// people. It will affect those using source replacement, but
460489
// hopefully that's a relatively small set of users.
461490
if token.is_none()
462-
&& reg_cfg.token.is_some()
491+
&& reg_cfg.is_token()
463492
&& registry.is_none()
464493
&& !sid.is_default_registry()
465494
&& !crates_io::is_url_crates_io(&api_host)
@@ -471,16 +500,10 @@ fn registry(
471500
see <https://github.com/rust-lang/cargo/issues/xxx>.\n\
472501
Use the --token command-line flag to remove this warning.",
473502
)?;
474-
reg_cfg.token.clone()
503+
reg_cfg.as_token().map(|t| t.to_owned())
475504
} else {
476-
let token = auth::auth_token(
477-
config,
478-
token.as_deref(),
479-
reg_cfg.token.as_deref(),
480-
reg_cfg.credential_process.as_ref(),
481-
registry.as_deref(),
482-
&api_host,
483-
)?;
505+
let token =
506+
auth::auth_token(config, token.as_deref(), &reg_cfg, registry, &api_host)?;
484507
Some(token)
485508
}
486509
}
@@ -692,7 +715,8 @@ pub fn registry_login(
692715
token: Option<String>,
693716
reg: Option<String>,
694717
) -> CargoResult<()> {
695-
let (registry, reg_cfg, _) = registry(config, token.clone(), None, reg.clone(), false, false)?;
718+
let (registry, reg_cfg, _) =
719+
registry(config, token.clone(), None, reg.as_deref(), false, false)?;
696720

697721
let token = match token {
698722
Some(token) => token,
@@ -714,7 +738,7 @@ pub fn registry_login(
714738
}
715739
};
716740

717-
if let Some(old_token) = &reg_cfg.token {
741+
if let RegistryConfig::Token(old_token) = &reg_cfg {
718742
if old_token == &token {
719743
config.shell().status("Login", "already logged in")?;
720744
return Ok(());
@@ -724,7 +748,7 @@ pub fn registry_login(
724748
auth::login(
725749
config,
726750
token,
727-
reg_cfg.credential_process.as_ref(),
751+
reg_cfg.as_process(),
728752
reg.as_deref(),
729753
registry.host(),
730754
)?;
@@ -740,9 +764,9 @@ pub fn registry_login(
740764
}
741765

742766
pub fn registry_logout(config: &Config, reg: Option<String>) -> CargoResult<()> {
743-
let (registry, reg_cfg, _) = registry(config, None, None, reg.clone(), false, false)?;
767+
let (registry, reg_cfg, _) = registry(config, None, None, reg.as_deref(), false, false)?;
744768
let reg_name = reg.as_deref().unwrap_or(CRATES_IO_DOMAIN);
745-
if reg_cfg.credential_process.is_none() && reg_cfg.token.is_none() {
769+
if reg_cfg.is_none() {
746770
config.shell().status(
747771
"Logout",
748772
format!("not currently logged in to `{}`", reg_name),
@@ -751,7 +775,7 @@ pub fn registry_logout(config: &Config, reg: Option<String>) -> CargoResult<()>
751775
}
752776
auth::logout(
753777
config,
754-
reg_cfg.credential_process.as_ref(),
778+
reg_cfg.as_process(),
755779
reg.as_deref(),
756780
registry.host(),
757781
)?;
@@ -788,8 +812,8 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
788812
let (mut registry, _, _) = registry(
789813
config,
790814
opts.token.clone(),
791-
opts.index.clone(),
792-
opts.registry.clone(),
815+
opts.index.as_deref(),
816+
opts.registry.as_deref(),
793817
true,
794818
true,
795819
)?;
@@ -864,7 +888,8 @@ pub fn yank(
864888
None => bail!("a version must be specified to yank"),
865889
};
866890

867-
let (mut registry, _, _) = registry(config, token, index, reg, true, true)?;
891+
let (mut registry, _, _) =
892+
registry(config, token, index.as_deref(), reg.as_deref(), true, true)?;
868893

869894
if undo {
870895
config
@@ -923,7 +948,8 @@ pub fn search(
923948
prefix
924949
}
925950

926-
let (mut registry, _, source_id) = registry(config, None, index, reg, false, false)?;
951+
let (mut registry, _, source_id) =
952+
registry(config, None, index.as_deref(), reg.as_deref(), false, false)?;
927953
let (crates, total_crates) = registry.search(query, limit).with_context(|| {
928954
format!(
929955
"failed to retrieve search results from the registry at {}",

src/cargo/ops/registry/auth.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use std::io::{Read, Write};
88
use std::path::PathBuf;
99
use std::process::{Command, Stdio};
1010

11+
use super::RegistryConfig;
12+
1113
enum Action {
1214
Get,
1315
Store(String),
@@ -18,18 +20,17 @@ enum Action {
1820
pub(super) fn auth_token(
1921
config: &Config,
2022
cli_token: Option<&str>,
21-
config_token: Option<&str>,
22-
credential_process: Option<&(PathBuf, Vec<String>)>,
23+
credential: &RegistryConfig,
2324
registry_name: Option<&str>,
2425
api_url: &str,
2526
) -> CargoResult<String> {
26-
let token = match (cli_token, config_token, credential_process) {
27-
(None, None, None) => {
27+
let token = match (cli_token, credential) {
28+
(None, RegistryConfig::None) => {
2829
bail!("no upload token found, please run `cargo login` or pass `--token`");
2930
}
30-
(Some(cli_token), _, _) => cli_token.to_string(),
31-
(None, Some(config_token), _) => config_token.to_string(),
32-
(None, None, Some(process)) => {
31+
(Some(cli_token), _) => cli_token.to_string(),
32+
(None, RegistryConfig::Token(config_token)) => config_token.to_string(),
33+
(None, RegistryConfig::Process(process)) => {
3334
let registry_name = registry_name.unwrap_or(CRATES_IO_REGISTRY);
3435
run_command(config, process, registry_name, api_url, Action::Get)?.unwrap()
3536
}

0 commit comments

Comments
 (0)