Skip to content

Commit 7204d39

Browse files
committed
Auto merge of #9302 - ehuss:cargo-config, r=alexcrichton
Add `cargo config` subcommand. This adds an initial version of the `cargo config` command as discussed in #2362. Closes #2362
2 parents caddb21 + 23d4a68 commit 7204d39

File tree

16 files changed

+1225
-175
lines changed

16 files changed

+1225
-175
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ semver = { version = "0.10", features = ["serde"] }
5454
serde = { version = "1.0.123", features = ["derive"] }
5555
serde_ignored = "0.1.0"
5656
serde_json = { version = "1.0.30", features = ["raw_value"] }
57+
shell-escape = "0.1.4"
5758
strip-ansi-escapes = "0.1.0"
5859
tar = { version = "0.4.26", default-features = false }
5960
tempfile = "3.0"

crates/cargo-test-support/src/lib.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,8 +1144,6 @@ impl Execs {
11441144
}
11451145

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

1158-
find_json_mismatch(&expected, &actual)
1156+
let cwd = self.process_builder.as_ref().and_then(|p| p.get_cwd());
1157+
find_json_mismatch(&expected, &actual, cwd)
11591158
}
11601159

11611160
fn diff_lines<'a>(
@@ -1333,8 +1332,12 @@ fn lines_match_works() {
13331332
/// as paths). You can use a `"{...}"` string literal as a wildcard for
13341333
/// arbitrary nested JSON (useful for parts of object emitted by other programs
13351334
/// (e.g., rustc) rather than Cargo itself).
1336-
pub fn find_json_mismatch(expected: &Value, actual: &Value) -> Result<(), String> {
1337-
match find_json_mismatch_r(expected, actual) {
1335+
pub fn find_json_mismatch(
1336+
expected: &Value,
1337+
actual: &Value,
1338+
cwd: Option<&Path>,
1339+
) -> Result<(), String> {
1340+
match find_json_mismatch_r(expected, actual, cwd) {
13381341
Some((expected_part, actual_part)) => Err(format!(
13391342
"JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
13401343
serde_json::to_string_pretty(expected).unwrap(),
@@ -1349,20 +1352,29 @@ pub fn find_json_mismatch(expected: &Value, actual: &Value) -> Result<(), String
13491352
fn find_json_mismatch_r<'a>(
13501353
expected: &'a Value,
13511354
actual: &'a Value,
1355+
cwd: Option<&Path>,
13521356
) -> Option<(&'a Value, &'a Value)> {
13531357
use serde_json::Value::*;
13541358
match (expected, actual) {
13551359
(&Number(ref l), &Number(ref r)) if l == r => None,
13561360
(&Bool(l), &Bool(r)) if l == r => None,
1357-
(&String(ref l), &String(ref r)) if lines_match(l, r) => None,
1361+
(&String(ref l), _) if l == "{...}" => None,
1362+
(&String(ref l), &String(ref r)) => {
1363+
let normalized = normalize_matcher(r, cwd);
1364+
if lines_match(l, &normalized) {
1365+
None
1366+
} else {
1367+
Some((expected, actual))
1368+
}
1369+
}
13581370
(&Array(ref l), &Array(ref r)) => {
13591371
if l.len() != r.len() {
13601372
return Some((expected, actual));
13611373
}
13621374

13631375
l.iter()
13641376
.zip(r.iter())
1365-
.filter_map(|(l, r)| find_json_mismatch_r(l, r))
1377+
.filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd))
13661378
.next()
13671379
}
13681380
(&Object(ref l), &Object(ref r)) => {
@@ -1373,12 +1385,11 @@ fn find_json_mismatch_r<'a>(
13731385

13741386
l.values()
13751387
.zip(r.values())
1376-
.filter_map(|(l, r)| find_json_mismatch_r(l, r))
1388+
.filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd))
13771389
.next()
13781390
}
13791391
(&Null, &Null) => None,
13801392
// Magic string literal `"{...}"` acts as wildcard for any sub-JSON.
1381-
(&String(ref l), _) if l == "{...}" => None,
13821393
_ => Some((expected, actual)),
13831394
}
13841395
}

crates/cargo-test-support/src/publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn _validate_upload(
7676
let actual_json = serde_json::from_slice(&json_bytes).expect("uploaded JSON should be valid");
7777
let expected_json = serde_json::from_str(expected_json).expect("expected JSON does not parse");
7878

79-
if let Err(e) = find_json_mismatch(&expected_json, &actual_json) {
79+
if let Err(e) = find_json_mismatch(&expected_json, &actual_json, None) {
8080
panic!("{}", e);
8181
}
8282

src/bin/cargo/commands/config.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::command_prelude::*;
2+
use cargo::ops::cargo_config;
3+
4+
pub fn cli() -> App {
5+
subcommand("config")
6+
.about("Inspect configuration values")
7+
.after_help("Run `cargo help config` for more detailed information.\n")
8+
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
9+
.subcommand(
10+
subcommand("get")
11+
.arg(Arg::with_name("key").help("The config key to display"))
12+
.arg(
13+
opt("format", "Display format")
14+
.possible_values(cargo_config::ConfigFormat::POSSIBLE_VALUES)
15+
.default_value("toml"),
16+
)
17+
.arg(opt(
18+
"show-origin",
19+
"Display where the config value is defined",
20+
))
21+
.arg(
22+
opt("merged", "Whether or not to merge config values")
23+
.possible_values(&["yes", "no"])
24+
.default_value("yes"),
25+
),
26+
)
27+
}
28+
29+
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
30+
config
31+
.cli_unstable()
32+
.fail_if_stable_command(config, "config", 9301)?;
33+
match args.subcommand() {
34+
("get", Some(args)) => {
35+
let opts = cargo_config::GetOptions {
36+
key: args.value_of("key"),
37+
format: args.value_of("format").unwrap().parse()?,
38+
show_origin: args.is_present("show-origin"),
39+
merged: args.value_of("merged") == Some("yes"),
40+
};
41+
cargo_config::get(config, &opts)?;
42+
}
43+
(cmd, _) => {
44+
panic!("unexpected command `{}`", cmd)
45+
}
46+
}
47+
Ok(())
48+
}

src/bin/cargo/commands/logout.rs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use crate::command_prelude::*;
2-
use anyhow::format_err;
3-
use cargo::core::features;
42
use cargo::ops;
53

64
pub fn cli() -> App {
@@ -12,29 +10,10 @@ pub fn cli() -> App {
1210
}
1311

1412
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
15-
let unstable = config.cli_unstable();
16-
if !(unstable.credential_process || unstable.unstable_options) {
17-
const SEE: &str = "See https://github.com/rust-lang/cargo/issues/8933 for more \
18-
information about the `cargo logout` command.";
19-
if config.nightly_features_allowed {
20-
return Err(format_err!(
21-
"the `cargo logout` command is unstable, pass `-Z unstable-options` to enable it\n\
22-
{}",
23-
SEE
24-
)
25-
.into());
26-
} else {
27-
return Err(format_err!(
28-
"the `cargo logout` command is unstable, and only available on the \
29-
nightly channel of Cargo, but this is the `{}` channel\n\
30-
{}\n\
31-
{}",
32-
features::channel(),
33-
features::SEE_CHANNELS,
34-
SEE
35-
)
36-
.into());
37-
}
13+
if !config.cli_unstable().credential_process {
14+
config
15+
.cli_unstable()
16+
.fail_if_stable_command(config, "logout", 8933)?;
3817
}
3918
config.load_credentials()?;
4019
ops::registry_logout(config, args.value_of("registry").map(String::from))?;

src/bin/cargo/commands/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub fn builtin() -> Vec<App> {
66
build::cli(),
77
check::cli(),
88
clean::cli(),
9+
config::cli(),
910
describe_future_incompatibilities::cli(),
1011
doc::cli(),
1112
fetch::cli(),
@@ -45,6 +46,7 @@ pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches<'_>) -> Cli
4546
"build" => build::exec,
4647
"check" => check::exec,
4748
"clean" => clean::exec,
49+
"config" => config::exec,
4850
"describe-future-incompatibilities" => describe_future_incompatibilities::exec,
4951
"doc" => doc::exec,
5052
"fetch" => fetch::exec,
@@ -84,6 +86,7 @@ pub mod bench;
8486
pub mod build;
8587
pub mod check;
8688
pub mod clean;
89+
pub mod config;
8790
pub mod describe_future_incompatibilities;
8891
pub mod doc;
8992
pub mod fetch;

src/cargo/core/features.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,8 @@ impl CliUnstable {
765765
Ok(())
766766
}
767767

768-
/// Generates an error if `-Z unstable-options` was not used.
769-
/// Intended to be used when a user passes a command-line flag that
770-
/// requires `-Z unstable-options`.
768+
/// Generates an error if `-Z unstable-options` was not used for a new,
769+
/// unstable command-line flag.
771770
pub fn fail_if_stable_opt(&self, flag: &str, issue: u32) -> CargoResult<()> {
772771
if !self.unstable_options {
773772
let see = format!(
@@ -799,6 +798,43 @@ impl CliUnstable {
799798
}
800799
Ok(())
801800
}
801+
802+
/// Generates an error if `-Z unstable-options` was not used for a new,
803+
/// unstable subcommand.
804+
pub fn fail_if_stable_command(
805+
&self,
806+
config: &Config,
807+
command: &str,
808+
issue: u32,
809+
) -> CargoResult<()> {
810+
if self.unstable_options {
811+
return Ok(());
812+
}
813+
let see = format!(
814+
"See https://github.com/rust-lang/cargo/issues/{} for more \
815+
information about the `cargo {}` command.",
816+
issue, command
817+
);
818+
if config.nightly_features_allowed {
819+
bail!(
820+
"the `cargo {}` command is unstable, pass `-Z unstable-options` to enable it\n\
821+
{}",
822+
command,
823+
see
824+
);
825+
} else {
826+
bail!(
827+
"the `cargo {}` command is unstable, and only available on the \
828+
nightly channel of Cargo, but this is the `{}` channel\n\
829+
{}\n\
830+
{}",
831+
command,
832+
channel(),
833+
SEE_CHANNELS,
834+
see
835+
);
836+
}
837+
}
802838
}
803839

804840
/// Returns the current release channel ("stable", "beta", "nightly", "dev").

0 commit comments

Comments
 (0)