Skip to content

Commit

Permalink
Auto merge of #9302 - ehuss:cargo-config, r=alexcrichton
Browse files Browse the repository at this point in the history
Add `cargo config` subcommand.

This adds an initial version of the `cargo config` command as discussed in #2362.

Closes #2362
  • Loading branch information
bors committed Mar 30, 2021
2 parents caddb21 + 23d4a68 commit 7204d39
Show file tree
Hide file tree
Showing 16 changed files with 1,225 additions and 175 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ semver = { version = "0.10", features = ["serde"] }
serde = { version = "1.0.123", features = ["derive"] }
serde_ignored = "0.1.0"
serde_json = { version = "1.0.30", features = ["raw_value"] }
shell-escape = "0.1.4"
strip-ansi-escapes = "0.1.0"
tar = { version = "0.4.26", default-features = false }
tempfile = "3.0"
Expand Down
29 changes: 20 additions & 9 deletions crates/cargo-test-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1144,8 +1144,6 @@ impl Execs {
}

fn match_json(&self, expected: &str, line: &str) -> MatchResult {
let expected = self.normalize_matcher(expected);
let line = self.normalize_matcher(line);
let actual = match line.parse() {
Err(e) => return Err(format!("invalid json, {}:\n`{}`", e, line)),
Ok(actual) => actual,
Expand All @@ -1155,7 +1153,8 @@ impl Execs {
Ok(expected) => expected,
};

find_json_mismatch(&expected, &actual)
let cwd = self.process_builder.as_ref().and_then(|p| p.get_cwd());
find_json_mismatch(&expected, &actual, cwd)
}

fn diff_lines<'a>(
Expand Down Expand Up @@ -1333,8 +1332,12 @@ fn lines_match_works() {
/// as paths). You can use a `"{...}"` string literal as a wildcard for
/// arbitrary nested JSON (useful for parts of object emitted by other programs
/// (e.g., rustc) rather than Cargo itself).
pub fn find_json_mismatch(expected: &Value, actual: &Value) -> Result<(), String> {
match find_json_mismatch_r(expected, actual) {
pub fn find_json_mismatch(
expected: &Value,
actual: &Value,
cwd: Option<&Path>,
) -> Result<(), String> {
match find_json_mismatch_r(expected, actual, cwd) {
Some((expected_part, actual_part)) => Err(format!(
"JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
serde_json::to_string_pretty(expected).unwrap(),
Expand All @@ -1349,20 +1352,29 @@ pub fn find_json_mismatch(expected: &Value, actual: &Value) -> Result<(), String
fn find_json_mismatch_r<'a>(
expected: &'a Value,
actual: &'a Value,
cwd: Option<&Path>,
) -> Option<(&'a Value, &'a Value)> {
use serde_json::Value::*;
match (expected, actual) {
(&Number(ref l), &Number(ref r)) if l == r => None,
(&Bool(l), &Bool(r)) if l == r => None,
(&String(ref l), &String(ref r)) if lines_match(l, r) => None,
(&String(ref l), _) if l == "{...}" => None,
(&String(ref l), &String(ref r)) => {
let normalized = normalize_matcher(r, cwd);
if lines_match(l, &normalized) {
None
} else {
Some((expected, actual))
}
}
(&Array(ref l), &Array(ref r)) => {
if l.len() != r.len() {
return Some((expected, actual));
}

l.iter()
.zip(r.iter())
.filter_map(|(l, r)| find_json_mismatch_r(l, r))
.filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd))
.next()
}
(&Object(ref l), &Object(ref r)) => {
Expand All @@ -1373,12 +1385,11 @@ fn find_json_mismatch_r<'a>(

l.values()
.zip(r.values())
.filter_map(|(l, r)| find_json_mismatch_r(l, r))
.filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd))
.next()
}
(&Null, &Null) => None,
// Magic string literal `"{...}"` acts as wildcard for any sub-JSON.
(&String(ref l), _) if l == "{...}" => None,
_ => Some((expected, actual)),
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-test-support/src/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn _validate_upload(
let actual_json = serde_json::from_slice(&json_bytes).expect("uploaded JSON should be valid");
let expected_json = serde_json::from_str(expected_json).expect("expected JSON does not parse");

if let Err(e) = find_json_mismatch(&expected_json, &actual_json) {
if let Err(e) = find_json_mismatch(&expected_json, &actual_json, None) {
panic!("{}", e);
}

Expand Down
48 changes: 48 additions & 0 deletions src/bin/cargo/commands/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use crate::command_prelude::*;
use cargo::ops::cargo_config;

pub fn cli() -> App {
subcommand("config")
.about("Inspect configuration values")
.after_help("Run `cargo help config` for more detailed information.\n")
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
.subcommand(
subcommand("get")
.arg(Arg::with_name("key").help("The config key to display"))
.arg(
opt("format", "Display format")
.possible_values(cargo_config::ConfigFormat::POSSIBLE_VALUES)
.default_value("toml"),
)
.arg(opt(
"show-origin",
"Display where the config value is defined",
))
.arg(
opt("merged", "Whether or not to merge config values")
.possible_values(&["yes", "no"])
.default_value("yes"),
),
)
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
config
.cli_unstable()
.fail_if_stable_command(config, "config", 9301)?;
match args.subcommand() {
("get", Some(args)) => {
let opts = cargo_config::GetOptions {
key: args.value_of("key"),
format: args.value_of("format").unwrap().parse()?,
show_origin: args.is_present("show-origin"),
merged: args.value_of("merged") == Some("yes"),
};
cargo_config::get(config, &opts)?;
}
(cmd, _) => {
panic!("unexpected command `{}`", cmd)
}
}
Ok(())
}
29 changes: 4 additions & 25 deletions src/bin/cargo/commands/logout.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::command_prelude::*;
use anyhow::format_err;
use cargo::core::features;
use cargo::ops;

pub fn cli() -> App {
Expand All @@ -12,29 +10,10 @@ pub fn cli() -> App {
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let unstable = config.cli_unstable();
if !(unstable.credential_process || unstable.unstable_options) {
const SEE: &str = "See https://github.com/rust-lang/cargo/issues/8933 for more \
information about the `cargo logout` command.";
if config.nightly_features_allowed {
return Err(format_err!(
"the `cargo logout` command is unstable, pass `-Z unstable-options` to enable it\n\
{}",
SEE
)
.into());
} else {
return Err(format_err!(
"the `cargo logout` command is unstable, and only available on the \
nightly channel of Cargo, but this is the `{}` channel\n\
{}\n\
{}",
features::channel(),
features::SEE_CHANNELS,
SEE
)
.into());
}
if !config.cli_unstable().credential_process {
config
.cli_unstable()
.fail_if_stable_command(config, "logout", 8933)?;
}
config.load_credentials()?;
ops::registry_logout(config, args.value_of("registry").map(String::from))?;
Expand Down
3 changes: 3 additions & 0 deletions src/bin/cargo/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub fn builtin() -> Vec<App> {
build::cli(),
check::cli(),
clean::cli(),
config::cli(),
describe_future_incompatibilities::cli(),
doc::cli(),
fetch::cli(),
Expand Down Expand Up @@ -45,6 +46,7 @@ pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches<'_>) -> Cli
"build" => build::exec,
"check" => check::exec,
"clean" => clean::exec,
"config" => config::exec,
"describe-future-incompatibilities" => describe_future_incompatibilities::exec,
"doc" => doc::exec,
"fetch" => fetch::exec,
Expand Down Expand Up @@ -84,6 +86,7 @@ pub mod bench;
pub mod build;
pub mod check;
pub mod clean;
pub mod config;
pub mod describe_future_incompatibilities;
pub mod doc;
pub mod fetch;
Expand Down
42 changes: 39 additions & 3 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,9 +765,8 @@ impl CliUnstable {
Ok(())
}

/// Generates an error if `-Z unstable-options` was not used.
/// Intended to be used when a user passes a command-line flag that
/// requires `-Z unstable-options`.
/// Generates an error if `-Z unstable-options` was not used for a new,
/// unstable command-line flag.
pub fn fail_if_stable_opt(&self, flag: &str, issue: u32) -> CargoResult<()> {
if !self.unstable_options {
let see = format!(
Expand Down Expand Up @@ -799,6 +798,43 @@ impl CliUnstable {
}
Ok(())
}

/// Generates an error if `-Z unstable-options` was not used for a new,
/// unstable subcommand.
pub fn fail_if_stable_command(
&self,
config: &Config,
command: &str,
issue: u32,
) -> CargoResult<()> {
if self.unstable_options {
return Ok(());
}
let see = format!(
"See https://github.com/rust-lang/cargo/issues/{} for more \
information about the `cargo {}` command.",
issue, command
);
if config.nightly_features_allowed {
bail!(
"the `cargo {}` command is unstable, pass `-Z unstable-options` to enable it\n\
{}",
command,
see
);
} else {
bail!(
"the `cargo {}` command is unstable, and only available on the \
nightly channel of Cargo, but this is the `{}` channel\n\
{}\n\
{}",
command,
channel(),
SEE_CHANNELS,
see
);
}
}
}

/// Returns the current release channel ("stable", "beta", "nightly", "dev").
Expand Down
Loading

0 comments on commit 7204d39

Please sign in to comment.