mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00
Auto merge of #13479 - epage:cfg, r=weihanglo
fix(cli): Respect CARGO_TERM_COLOR in '--list' and '-Zhelp' ### What does this PR try to resolve? Similar to #9012, we aren't respecting `CARGO_TERM_COLOR` for `-Zhelp` and other places. This corrects that. ### How should we test and review this PR? #9012 was about initialization order to get the value. Here, the problem is that we don't update `Shell` with `CARGO_TERM_COLOR`. In doing this, I was concerned about keeping track of where it is safe to call `config_configure` without running it twice. To this end, I refactored `main` to make it clear that each call to `config_configure` is in a mutually exclusive path that exists immediately. ### Additional information Found this with the test for `-Zhelp` in #13461.
This commit is contained in:
commit
98079d9d19
@ -48,11 +48,55 @@ pub fn main(gctx: &mut GlobalContext) -> CliResult {
|
|||||||
|
|
||||||
let (expanded_args, global_args) = expand_aliases(gctx, args, vec![])?;
|
let (expanded_args, global_args) = expand_aliases(gctx, args, vec![])?;
|
||||||
|
|
||||||
|
let is_verbose = expanded_args.verbose() > 0;
|
||||||
|
|
||||||
if expanded_args
|
if expanded_args
|
||||||
.get_one::<String>("unstable-features")
|
.get_one::<String>("unstable-features")
|
||||||
.map(String::as_str)
|
.map(String::as_str)
|
||||||
== Some("help")
|
== Some("help")
|
||||||
{
|
{
|
||||||
|
// Don't let config errors get in the way of parsing arguments
|
||||||
|
let _ = config_configure(gctx, &expanded_args, None, global_args, None);
|
||||||
|
print_zhelp(gctx);
|
||||||
|
} else if expanded_args.flag("version") {
|
||||||
|
// Don't let config errors get in the way of parsing arguments
|
||||||
|
let _ = config_configure(gctx, &expanded_args, None, global_args, None);
|
||||||
|
let version = get_version_string(is_verbose);
|
||||||
|
drop_print!(gctx, "{}", version);
|
||||||
|
} else if let Some(code) = expanded_args.get_one::<String>("explain") {
|
||||||
|
// Don't let config errors get in the way of parsing arguments
|
||||||
|
let _ = config_configure(gctx, &expanded_args, None, global_args, None);
|
||||||
|
let mut procss = gctx.load_global_rustc(None)?.process();
|
||||||
|
procss.arg("--explain").arg(code).exec()?;
|
||||||
|
} else if expanded_args.flag("list") {
|
||||||
|
// Don't let config errors get in the way of parsing arguments
|
||||||
|
let _ = config_configure(gctx, &expanded_args, None, global_args, None);
|
||||||
|
print_list(gctx, is_verbose);
|
||||||
|
} else {
|
||||||
|
let (cmd, subcommand_args) = match expanded_args.subcommand() {
|
||||||
|
Some((cmd, args)) => (cmd, args),
|
||||||
|
_ => {
|
||||||
|
// No subcommand provided.
|
||||||
|
cli(gctx).print_help()?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let exec = Exec::infer(cmd)?;
|
||||||
|
config_configure(
|
||||||
|
gctx,
|
||||||
|
&expanded_args,
|
||||||
|
Some(subcommand_args),
|
||||||
|
global_args,
|
||||||
|
Some(&exec),
|
||||||
|
)?;
|
||||||
|
super::init_git(gctx);
|
||||||
|
|
||||||
|
exec.exec(gctx, subcommand_args)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_zhelp(gctx: &GlobalContext) {
|
||||||
let header = style::HEADER;
|
let header = style::HEADER;
|
||||||
let literal = style::LITERAL;
|
let literal = style::LITERAL;
|
||||||
let placeholder = style::PLACEHOLDER;
|
let placeholder = style::PLACEHOLDER;
|
||||||
@ -97,23 +141,9 @@ Run with `{literal}cargo -Z{literal:#} {placeholder}[FLAG] [COMMAND]{placeholder
|
|||||||
"\nSee https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \
|
"\nSee https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \
|
||||||
for more information about these flags."
|
for more information about these flags."
|
||||||
);
|
);
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_verbose = expanded_args.verbose() > 0;
|
fn print_list(gctx: &GlobalContext, is_verbose: bool) {
|
||||||
if expanded_args.flag("version") {
|
|
||||||
let version = get_version_string(is_verbose);
|
|
||||||
drop_print!(gctx, "{}", version);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(code) = expanded_args.get_one::<String>("explain") {
|
|
||||||
let mut procss = gctx.load_global_rustc(None)?.process();
|
|
||||||
procss.arg("--explain").arg(code).exec()?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if expanded_args.flag("list") {
|
|
||||||
// Maps from commonly known external commands (not builtin to cargo)
|
// Maps from commonly known external commands (not builtin to cargo)
|
||||||
// to their description, for the help page. Reserved for external
|
// to their description, for the help page. Reserved for external
|
||||||
// subcommands that are core within the rust ecosystem (esp ones that
|
// subcommands that are core within the rust ecosystem (esp ones that
|
||||||
@ -167,22 +197,6 @@ Run with `{literal}cargo -Z{literal:#} {placeholder}[FLAG] [COMMAND]{placeholder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let (cmd, subcommand_args) = match expanded_args.subcommand() {
|
|
||||||
Some((cmd, args)) => (cmd, args),
|
|
||||||
_ => {
|
|
||||||
// No subcommand provided.
|
|
||||||
cli(gctx).print_help()?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let exec = Exec::infer(cmd)?;
|
|
||||||
config_configure(gctx, &expanded_args, subcommand_args, global_args, &exec)?;
|
|
||||||
super::init_git(gctx);
|
|
||||||
|
|
||||||
exec.exec(gctx, subcommand_args)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_version_string(is_verbose: bool) -> String {
|
pub fn get_version_string(is_verbose: bool) -> String {
|
||||||
@ -365,16 +379,18 @@ For more information, see issue #12207 <https://github.com/rust-lang/cargo/issue
|
|||||||
fn config_configure(
|
fn config_configure(
|
||||||
gctx: &mut GlobalContext,
|
gctx: &mut GlobalContext,
|
||||||
args: &ArgMatches,
|
args: &ArgMatches,
|
||||||
subcommand_args: &ArgMatches,
|
subcommand_args: Option<&ArgMatches>,
|
||||||
global_args: GlobalArgs,
|
global_args: GlobalArgs,
|
||||||
exec: &Exec,
|
exec: Option<&Exec>,
|
||||||
) -> CliResult {
|
) -> CliResult {
|
||||||
let arg_target_dir = &subcommand_args.value_of_path("target-dir", gctx);
|
let arg_target_dir = &subcommand_args.and_then(|a| a.value_of_path("target-dir", gctx));
|
||||||
let mut verbose = global_args.verbose + args.verbose();
|
let mut verbose = global_args.verbose + args.verbose();
|
||||||
// quiet is unusual because it is redefined in some subcommands in order
|
// quiet is unusual because it is redefined in some subcommands in order
|
||||||
// to provide custom help text.
|
// to provide custom help text.
|
||||||
let mut quiet = args.flag("quiet") || subcommand_args.flag("quiet") || global_args.quiet;
|
let mut quiet = args.flag("quiet")
|
||||||
if matches!(exec, Exec::Manifest(_)) && !quiet {
|
|| subcommand_args.map(|a| a.flag("quiet")).unwrap_or_default()
|
||||||
|
|| global_args.quiet;
|
||||||
|
if matches!(exec, Some(Exec::Manifest(_))) && !quiet {
|
||||||
// Verbosity is shifted quieter for `Exec::Manifest` as it is can be used as if you ran
|
// Verbosity is shifted quieter for `Exec::Manifest` as it is can be used as if you ran
|
||||||
// `cargo install` and we especially shouldn't pollute programmatic output.
|
// `cargo install` and we especially shouldn't pollute programmatic output.
|
||||||
//
|
//
|
||||||
|
@ -1018,6 +1018,49 @@ impl GlobalContext {
|
|||||||
unstable_flags: &[String],
|
unstable_flags: &[String],
|
||||||
cli_config: &[String],
|
cli_config: &[String],
|
||||||
) -> CargoResult<()> {
|
) -> CargoResult<()> {
|
||||||
|
// Ignore errors in the configuration files. We don't want basic
|
||||||
|
// commands like `cargo version` to error out due to config file
|
||||||
|
// problems.
|
||||||
|
let term = self.get::<TermConfig>("term").unwrap_or_default();
|
||||||
|
|
||||||
|
// The command line takes precedence over configuration.
|
||||||
|
let extra_verbose = verbose >= 2;
|
||||||
|
let verbose = verbose != 0;
|
||||||
|
let verbosity = match (verbose, quiet) {
|
||||||
|
(true, true) => bail!("cannot set both --verbose and --quiet"),
|
||||||
|
(true, false) => Verbosity::Verbose,
|
||||||
|
(false, true) => Verbosity::Quiet,
|
||||||
|
(false, false) => match (term.verbose, term.quiet) {
|
||||||
|
(Some(true), Some(true)) => {
|
||||||
|
bail!("cannot set both `term.verbose` and `term.quiet`")
|
||||||
|
}
|
||||||
|
(Some(true), _) => Verbosity::Verbose,
|
||||||
|
(_, Some(true)) => Verbosity::Quiet,
|
||||||
|
_ => Verbosity::Normal,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
self.shell().set_verbosity(verbosity);
|
||||||
|
self.extra_verbose = extra_verbose;
|
||||||
|
|
||||||
|
let color = color.or_else(|| term.color.as_deref());
|
||||||
|
self.shell().set_color_choice(color)?;
|
||||||
|
if let Some(hyperlinks) = term.hyperlinks {
|
||||||
|
self.shell().set_hyperlinks(hyperlinks)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.progress_config = term.progress.unwrap_or_default();
|
||||||
|
|
||||||
|
self.frozen = frozen;
|
||||||
|
self.locked = locked;
|
||||||
|
self.offline = offline
|
||||||
|
|| self
|
||||||
|
.net_config()
|
||||||
|
.ok()
|
||||||
|
.and_then(|n| n.offline)
|
||||||
|
.unwrap_or(false);
|
||||||
|
let cli_target_dir = target_dir.as_ref().map(|dir| Filesystem::new(dir.clone()));
|
||||||
|
self.target_dir = cli_target_dir;
|
||||||
|
|
||||||
for warning in self
|
for warning in self
|
||||||
.unstable_flags
|
.unstable_flags
|
||||||
.parse(unstable_flags, self.nightly_features_allowed)?
|
.parse(unstable_flags, self.nightly_features_allowed)?
|
||||||
@ -1042,49 +1085,6 @@ impl GlobalContext {
|
|||||||
// before configure). This can be removed when stabilized.
|
// before configure). This can be removed when stabilized.
|
||||||
self.reload_rooted_at(self.cwd.clone())?;
|
self.reload_rooted_at(self.cwd.clone())?;
|
||||||
}
|
}
|
||||||
let extra_verbose = verbose >= 2;
|
|
||||||
let verbose = verbose != 0;
|
|
||||||
|
|
||||||
// Ignore errors in the configuration files. We don't want basic
|
|
||||||
// commands like `cargo version` to error out due to config file
|
|
||||||
// problems.
|
|
||||||
let term = self.get::<TermConfig>("term").unwrap_or_default();
|
|
||||||
|
|
||||||
let color = color.or_else(|| term.color.as_deref());
|
|
||||||
|
|
||||||
// The command line takes precedence over configuration.
|
|
||||||
let verbosity = match (verbose, quiet) {
|
|
||||||
(true, true) => bail!("cannot set both --verbose and --quiet"),
|
|
||||||
(true, false) => Verbosity::Verbose,
|
|
||||||
(false, true) => Verbosity::Quiet,
|
|
||||||
(false, false) => match (term.verbose, term.quiet) {
|
|
||||||
(Some(true), Some(true)) => {
|
|
||||||
bail!("cannot set both `term.verbose` and `term.quiet`")
|
|
||||||
}
|
|
||||||
(Some(true), _) => Verbosity::Verbose,
|
|
||||||
(_, Some(true)) => Verbosity::Quiet,
|
|
||||||
_ => Verbosity::Normal,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let cli_target_dir = target_dir.as_ref().map(|dir| Filesystem::new(dir.clone()));
|
|
||||||
|
|
||||||
self.shell().set_verbosity(verbosity);
|
|
||||||
self.shell().set_color_choice(color)?;
|
|
||||||
if let Some(hyperlinks) = term.hyperlinks {
|
|
||||||
self.shell().set_hyperlinks(hyperlinks)?;
|
|
||||||
}
|
|
||||||
self.progress_config = term.progress.unwrap_or_default();
|
|
||||||
self.extra_verbose = extra_verbose;
|
|
||||||
self.frozen = frozen;
|
|
||||||
self.locked = locked;
|
|
||||||
self.offline = offline
|
|
||||||
|| self
|
|
||||||
.net_config()
|
|
||||||
.ok()
|
|
||||||
.and_then(|n| n.offline)
|
|
||||||
.unwrap_or(false);
|
|
||||||
self.target_dir = cli_target_dir;
|
|
||||||
|
|
||||||
self.load_unstable_flags_from_config()?;
|
self.load_unstable_flags_from_config()?;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user