Skip to content

Commit 4e56636

Browse files
committed
refactor(cli): Lazily do first-pass config loading
This will be a help for cases like #10952 which I would expect would assert that the config is not loaded before changing the current_dir.
1 parent 990eef2 commit 4e56636

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

src/bin/cargo/cli.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use anyhow::anyhow;
2+
use cargo::core::shell::Shell;
23
use cargo::core::{features, CliUnstable};
34
use cargo::{self, drop_print, drop_println, CliResult, Config};
45
use clap::{AppSettings, Arg, ArgMatches};
@@ -21,12 +22,13 @@ lazy_static::lazy_static! {
2122
]);
2223
}
2324

24-
pub fn main(config: &mut Config) -> CliResult {
25+
pub fn main(config: &mut LazyConfig) -> CliResult {
26+
let args = cli().try_get_matches()?;
27+
2528
// CAUTION: Be careful with using `config` until it is configured below.
2629
// In general, try to avoid loading config values unless necessary (like
2730
// the [alias] table).
28-
29-
let args = cli().try_get_matches()?;
31+
let config = config.get_mut();
3032

3133
// Global args need to be extracted before expanding aliases because the
3234
// clap code for extracting a subcommand discards global options
@@ -463,6 +465,34 @@ See 'cargo help <command>' for more information on a specific command.\n",
463465
.subcommands(commands::builtin())
464466
}
465467

468+
pub struct LazyConfig {
469+
config: Option<Config>,
470+
}
471+
472+
impl LazyConfig {
473+
pub fn new() -> Self {
474+
Self { config: None }
475+
}
476+
477+
pub fn is_init(&self) -> bool {
478+
self.config.is_some()
479+
}
480+
481+
pub fn get(&mut self) -> &Config {
482+
self.get_mut()
483+
}
484+
485+
pub fn get_mut(&mut self) -> &mut Config {
486+
self.config.get_or_insert_with(|| match Config::default() {
487+
Ok(cfg) => cfg,
488+
Err(e) => {
489+
let mut shell = Shell::new();
490+
cargo::exit_with_error(e.into(), &mut shell)
491+
}
492+
})
493+
}
494+
}
495+
466496
#[test]
467497
fn verify_cli() {
468498
cli().debug_assert();

src/bin/cargo/main.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![warn(rust_2018_idioms)] // while we're getting used to 2018
22
#![allow(clippy::all)]
33

4-
use cargo::core::shell::Shell;
54
use cargo::util::toml::StringOrVec;
65
use cargo::util::CliError;
76
use cargo::util::{self, closest_msg, command_prelude, CargoResult, CliResult, Config};
@@ -22,23 +21,17 @@ fn main() {
2221
#[cfg(not(feature = "pretty-env-logger"))]
2322
env_logger::init_from_env("CARGO_LOG");
2423

25-
let mut config = match Config::default() {
26-
Ok(cfg) => cfg,
27-
Err(e) => {
28-
let mut shell = Shell::new();
29-
cargo::exit_with_error(e.into(), &mut shell)
30-
}
31-
};
24+
let mut config = cli::LazyConfig::new();
3225

3326
let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
34-
cargo::ops::fix_exec_rustc(&config, &lock_addr).map_err(|e| CliError::from(e))
27+
cargo::ops::fix_exec_rustc(config.get(), &lock_addr).map_err(|e| CliError::from(e))
3528
} else {
3629
let _token = cargo::util::job::setup();
3730
cli::main(&mut config)
3831
};
3932

4033
match result {
41-
Err(e) => cargo::exit_with_error(e, &mut *config.shell()),
34+
Err(e) => cargo::exit_with_error(e, &mut config.get_mut().shell()),
4235
Ok(()) => {}
4336
}
4437
}

0 commit comments

Comments
 (0)