Skip to content

Commit

Permalink
Auto merge of #7901 - ehuss:config-cli-path, r=alexcrichton
Browse files Browse the repository at this point in the history
Support `--config path_to_config.toml` cli syntax.

Updates the `--config` flag so that if the argument appears to be a file, it will load the file.

cc #7722, #7723
  • Loading branch information
bors committed Feb 18, 2020
2 parents e029740 + 1d5d7a2 commit e0678fb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
43 changes: 29 additions & 14 deletions src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,20 +864,35 @@ impl Config {
};
let mut loaded_args = CV::Table(HashMap::new(), Definition::Cli);
for arg in cli_args {
// TODO: This should probably use a more narrow parser, reject
// comments, blank lines, [headers], etc.
let toml_v: toml::Value = toml::de::from_str(arg)
.chain_err(|| format!("failed to parse --config argument `{}`", arg))?;
let toml_table = toml_v.as_table().unwrap();
if toml_table.len() != 1 {
bail!(
"--config argument `{}` expected exactly one key=value pair, got {} keys",
arg,
toml_table.len()
);
}
let tmp_table = CV::from_toml(Definition::Cli, toml_v)
.chain_err(|| format!("failed to convert --config argument `{}`", arg))?;
let arg_as_path = self.cwd.join(arg);
let tmp_table = if !arg.is_empty() && arg_as_path.exists() {
// --config path_to_file
let str_path = arg_as_path
.to_str()
.ok_or_else(|| {
anyhow::format_err!("config path {:?} is not utf-8", arg_as_path)
})?
.to_string();
let mut map = HashMap::new();
let value = CV::String(str_path, Definition::Cli);
map.insert("include".to_string(), value);
CV::Table(map, Definition::Cli)
} else {
// TODO: This should probably use a more narrow parser, reject
// comments, blank lines, [headers], etc.
let toml_v: toml::Value = toml::de::from_str(arg)
.chain_err(|| format!("failed to parse --config argument `{}`", arg))?;
let toml_table = toml_v.as_table().unwrap();
if toml_table.len() != 1 {
bail!(
"--config argument `{}` expected exactly one key=value pair, got {} keys",
arg,
toml_table.len()
);
}
CV::from_toml(Definition::Cli, toml_v)
.chain_err(|| format!("failed to convert --config argument `{}`", arg))?
};
let mut seen = HashSet::new();
let tmp_table = self
.load_includes(tmp_table, &mut seen)
Expand Down
5 changes: 3 additions & 2 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,11 @@ The config values are first loaded from the include path, and then the config
file's own values are merged on top of it.

This can be paired with [config-cli](#config-cli) to specify a file to load
from the command-line:
from the command-line. Pass a path to a config file as the argument to
`--config`:

```console
cargo +nightly -Zunstable-options -Zconfig-include --config 'include="somefile.toml"' build
cargo +nightly -Zunstable-options -Zconfig-include --config somefile.toml build
```

CLI paths are relative to the current working directory.
28 changes: 27 additions & 1 deletion tests/testsuite/config_include.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
use super::config::{
assert_error, assert_match, read_output, write_config, write_config_at, ConfigBuilder,
};
use cargo_test_support::NO_SUCH_FILE_ERR_MSG;
use cargo_test_support::{paths, NO_SUCH_FILE_ERR_MSG};
use std::fs;

#[cargo_test]
fn gated() {
Expand Down Expand Up @@ -208,3 +209,28 @@ Caused by:
expected array, but found string",
);
}

#[cargo_test]
fn cli_path() {
// --config path_to_file
fs::write(paths::root().join("myconfig.toml"), "key = 123").unwrap();
let config = ConfigBuilder::new()
.cwd(paths::root())
.unstable_flag("config-include")
.config_arg("myconfig.toml")
.build();
assert_eq!(config.get::<u32>("key").unwrap(), 123);

let config = ConfigBuilder::new()
.unstable_flag("config-include")
.config_arg("missing.toml")
.build_err();
assert_error(
config.unwrap_err(),
"\
failed to parse --config argument `missing.toml`
Caused by:
expected an equals, found eof at line 1 column 13",
);
}

0 comments on commit e0678fb

Please sign in to comment.