Skip to content

Commit

Permalink
config: propogate --when.command through cli
Browse files Browse the repository at this point in the history
  • Loading branch information
bryceberger committed Jan 22, 2025
1 parent 5464ba9 commit f50ef2c
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 5 deletions.
20 changes: 19 additions & 1 deletion cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3701,6 +3701,23 @@ impl CliRunner {
process_global_args_fn(ui, &matches)?;
}

let subcommand_combined =
if let Some((subcommand, mut subcommand_matches)) = matches.subcommand() {
let mut subcommand_combined = String::from(subcommand);
while let Some((subcommand, new_matches)) = subcommand_matches.subcommand() {
subcommand_combined.push(' ');
subcommand_combined.push_str(subcommand);
subcommand_matches = new_matches;
}
config = config_env
.resolve_config_with_command(&raw_config, Some(&subcommand_combined))?;
migrate_config(&mut config)?;
ui.reset(&config)?;
Some(subcommand_combined)
} else {
None
};

let maybe_workspace_loader = if let Some(path) = &args.global_args.repository {
// TODO: maybe path should be canonicalized by WorkspaceLoader?
let abs_path = cwd.join(path);
Expand All @@ -3712,7 +3729,8 @@ impl CliRunner {
.map_err(|err| map_workspace_load_error(err, Some(path)))?;
config_env.reset_repo_path(loader.repo_path());
config_env.reload_repo_config(&mut raw_config)?;
config = config_env.resolve_config(&raw_config)?;
config = config_env
.resolve_config_with_command(&raw_config, subcommand_combined.as_deref())?;
migrate_config(&mut config)?;
Ok(loader)
} else {
Expand Down
9 changes: 9 additions & 0 deletions cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,18 @@ impl ConfigEnv {
/// Resolves conditional scopes within the current environment. Returns new
/// resolved config.
pub fn resolve_config(&self, config: &RawConfig) -> Result<StackedConfig, ConfigGetError> {
self.resolve_config_with_command(config, None)
}

pub fn resolve_config_with_command(
&self,
config: &RawConfig,
command: Option<&str>,
) -> Result<StackedConfig, ConfigGetError> {
let context = ConfigResolutionContext {
home_dir: self.home_dir.as_deref(),
repo_path: self.repo_path.as_deref(),
command,
};
jj_lib::config::resolve(config.as_ref(), &context)
}
Expand Down
69 changes: 65 additions & 4 deletions cli/tests/test_config_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,12 +1078,25 @@ fn test_config_conditional() {
&user_config_path,
indoc! {"
foo = 'global'
baz = 'global'
qux = 'global'
[[--scope]]
--when.repositories = ['~/repo1']
foo = 'repo1'
[[--scope]]
--when.repositories = ['~/repo2']
foo = 'repo2'
[[--scope]]
--when.commands = ['config']
baz = 'config'
[[--scope]]
--when.commands = ['config get']
qux = 'get'
[[--scope]]
--when.commands = ['config list']
qux = 'list'
"},
)
.unwrap();
Expand All @@ -1093,16 +1106,38 @@ fn test_config_conditional() {
insta::assert_snapshot!(stdout, @"global");
let stdout = test_env.jj_cmd_success(&repo1_path, &["config", "get", "foo"]);
insta::assert_snapshot!(stdout, @"repo1");
// baz should be the same for `jj config get` and `jj config list`
// qux should be different
let stdout = test_env.jj_cmd_success(&repo1_path, &["config", "get", "baz"]);
insta::assert_snapshot!(stdout, @"config");
let stdout = test_env.jj_cmd_success(&repo1_path, &["config", "get", "qux"]);
insta::assert_snapshot!(stdout, @"get");
let stdout = test_env.jj_cmd_success(test_env.env_root(), &["config", "list", "--user"]);
insta::assert_snapshot!(stdout, @"foo = 'global'");
insta::assert_snapshot!(stdout, @r#"
foo = 'global'
baz = 'config'
qux = 'list'
"#);
let stdout = test_env.jj_cmd_success(&repo1_path, &["config", "list", "--user"]);
insta::assert_snapshot!(stdout, @"foo = 'repo1'");
insta::assert_snapshot!(stdout, @r#"
foo = 'repo1'
baz = 'config'
qux = 'list'
"#);
let stdout = test_env.jj_cmd_success(&repo2_path, &["config", "list", "--user"]);
insta::assert_snapshot!(stdout, @"foo = 'repo2'");
insta::assert_snapshot!(stdout, @r#"
foo = 'repo2'
baz = 'config'
qux = 'list'
"#);

// relative workspace path
let stdout = test_env.jj_cmd_success(&repo2_path, &["config", "list", "--user", "-R../repo1"]);
insta::assert_snapshot!(stdout, @"foo = 'repo1'");
insta::assert_snapshot!(stdout, @r#"
foo = 'repo1'
baz = 'config'
qux = 'list'
"#);

// set and unset should refer to the source config
// (there's no option to update scoped table right now.)
Expand All @@ -1113,24 +1148,50 @@ fn test_config_conditional() {
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(std::fs::read_to_string(&user_config_path).unwrap(), @r#"
foo = 'global'
baz = 'global'
qux = 'global'
bar = "new value"
[[--scope]]
--when.repositories = ['~/repo1']
foo = 'repo1'
[[--scope]]
--when.repositories = ['~/repo2']
foo = 'repo2'
[[--scope]]
--when.commands = ['config']
baz = 'config'
[[--scope]]
--when.commands = ['config get']
qux = 'get'
[[--scope]]
--when.commands = ['config list']
qux = 'list'
"#);
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo1_path, &["config", "unset", "--user", "foo"]);
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(std::fs::read_to_string(&user_config_path).unwrap(), @r#"
baz = 'global'
qux = 'global'
bar = "new value"
[[--scope]]
--when.repositories = ['~/repo1']
foo = 'repo1'
[[--scope]]
--when.repositories = ['~/repo2']
foo = 'repo2'
[[--scope]]
--when.commands = ['config']
baz = 'config'
[[--scope]]
--when.commands = ['config get']
qux = 'get'
[[--scope]]
--when.commands = ['config list']
qux = 'list'
"#);
}

Expand Down

0 comments on commit f50ef2c

Please sign in to comment.