cli --config global option: allow spaces around =

This is especially useful for complicated options like

```
--config 'revsets."immutable_heads()" = "none()"'
```
This commit is contained in:
Ilya Grigoriev 2025-03-28 19:44:22 -07:00
parent 6327cc1da2
commit fa88527f77
4 changed files with 35 additions and 6 deletions

View File

@ -89,6 +89,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
reversing colors rather than underlining, you can set
`colors."diff token"={ underline = false, reverse = true }` in your config.
* The `--config` global option now allows whitespace around the equals sign, e.g.
`--config 'revsets."immutable_heads()" = "none()"'` is now legal.
### Fixed bugs
* `jj log -p --stat` now shows diff stats as well as the default color-words/git

View File

@ -579,7 +579,9 @@ fn parse_config_arg_item(item_str: &str) -> Result<(ConfigNamePathBuf, ConfigVal
let split_candidates = item_str.as_bytes().iter().positions(|&b| b == b'=');
let Some((name, value_str)) = split_candidates
.map(|p| (&item_str[..p], &item_str[p + 1..]))
.map(|(name, value)| name.parse().map(|name| (name, value)))
// Trim spaces, similarly to TOML syntax; names or values with spaces would have to be
// specified with quotes.
.map(|(name, value)| name.trim().parse().map(|name| (name, value.trim())))
.find_or_last(Result::is_ok)
.transpose()
.map_err(|err| config_error_with_message("--config name cannot be parsed", err))?
@ -827,21 +829,38 @@ mod tests {
assert!(parse_config_arg_item("").is_err());
assert!(parse_config_arg_item("a").is_err());
assert!(parse_config_arg_item("=").is_err());
// The value parser is sensitive to leading whitespaces, which seems
// good because the parsing falls back to a bare string.
assert!(parse_config_arg_item("a = 'b'").is_err());
let (name, value) = parse_config_arg_item("a=b").unwrap();
assert_eq!(name, ConfigNamePathBuf::from_iter(["a"]));
assert_eq!(value.as_str(), Some("b"));
let (name, value) = parse_config_arg_item("a = b").unwrap();
assert_eq!(name, ConfigNamePathBuf::from_iter(["a"]));
assert_eq!(value.as_str(), Some("b"));
let (name, value) = parse_config_arg_item("a = 'b'").unwrap();
assert_eq!(name, ConfigNamePathBuf::from_iter(["a"]));
assert_eq!(value.as_str(), Some("b"));
let (name, value) = parse_config_arg_item("a = ' '").unwrap();
assert_eq!(name, ConfigNamePathBuf::from_iter(["a"]));
assert_eq!(value.as_str(), Some(" "));
let (name, value) =
parse_config_arg_item(r#"revsets."immutable_heads()" = "none()""#).unwrap();
assert_eq!(
name,
ConfigNamePathBuf::from_iter(["revsets", "immutable_heads()"])
);
assert_eq!(value.as_str(), Some("none()"));
let (name, value) = parse_config_arg_item("a=").unwrap();
assert_eq!(name, ConfigNamePathBuf::from_iter(["a"]));
assert_eq!(value.as_str(), Some(""));
let (name, value) = parse_config_arg_item("a= ").unwrap();
assert_eq!(name, ConfigNamePathBuf::from_iter(["a"]));
assert_eq!(value.as_str(), Some(" "));
assert_eq!(value.as_str(), Some(""));
// This one is a bit cryptic, but b=c can be a bare string.
let (name, value) = parse_config_arg_item("a=b=c").unwrap();

View File

@ -462,6 +462,14 @@ fn test_color_config() {
[EOF]
");
// Spaces around the = signs or dots are OK, by analogy with TOML
let output = work_dir.run_jj(["--config= ui . color = never", "log", "-T", "commit_id"]);
insta::assert_snapshot!(output, @r"
@ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
0000000000000000000000000000000000000000
[EOF]
");
// --color overrides --config 'ui.color=...'.
let output = work_dir.run_jj([
"--color",

View File

@ -1573,7 +1573,6 @@ to specify additional configuration settings. This overrides settings defined in
config files or environment variables. For example,
```shell
# Must not have spaces around the `=`
jj --config ui.color=always --config ui.diff-editor=meld split
```