Skip to content

Commit

Permalink
refactor(cli): Lazily do first-pass config loading
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
epage committed Aug 29, 2022
1 parent 990eef2 commit 4e56636
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
36 changes: 33 additions & 3 deletions src/bin/cargo/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::anyhow;
use cargo::core::shell::Shell;
use cargo::core::{features, CliUnstable};
use cargo::{self, drop_print, drop_println, CliResult, Config};
use clap::{AppSettings, Arg, ArgMatches};
Expand All @@ -21,12 +22,13 @@ lazy_static::lazy_static! {
]);
}

pub fn main(config: &mut Config) -> CliResult {
pub fn main(config: &mut LazyConfig) -> CliResult {
let args = cli().try_get_matches()?;

// CAUTION: Be careful with using `config` until it is configured below.
// In general, try to avoid loading config values unless necessary (like
// the [alias] table).

let args = cli().try_get_matches()?;
let config = config.get_mut();

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

pub struct LazyConfig {
config: Option<Config>,
}

impl LazyConfig {
pub fn new() -> Self {
Self { config: None }
}

pub fn is_init(&self) -> bool {
self.config.is_some()
}

pub fn get(&mut self) -> &Config {
self.get_mut()
}

pub fn get_mut(&mut self) -> &mut Config {
self.config.get_or_insert_with(|| match Config::default() {
Ok(cfg) => cfg,
Err(e) => {
let mut shell = Shell::new();
cargo::exit_with_error(e.into(), &mut shell)
}
})
}
}

#[test]
fn verify_cli() {
cli().debug_assert();
Expand Down
13 changes: 3 additions & 10 deletions src/bin/cargo/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![warn(rust_2018_idioms)] // while we're getting used to 2018
#![allow(clippy::all)]

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

let mut config = match Config::default() {
Ok(cfg) => cfg,
Err(e) => {
let mut shell = Shell::new();
cargo::exit_with_error(e.into(), &mut shell)
}
};
let mut config = cli::LazyConfig::new();

let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
cargo::ops::fix_exec_rustc(&config, &lock_addr).map_err(|e| CliError::from(e))
cargo::ops::fix_exec_rustc(config.get(), &lock_addr).map_err(|e| CliError::from(e))
} else {
let _token = cargo::util::job::setup();
cli::main(&mut config)
};

match result {
Err(e) => cargo::exit_with_error(e, &mut *config.shell()),
Err(e) => cargo::exit_with_error(e, &mut config.get_mut().shell()),
Ok(()) => {}
}
}
Expand Down

0 comments on commit 4e56636

Please sign in to comment.