diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 35a12732dee..a615bda59c3 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -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); @@ -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 { diff --git a/cli/src/config.rs b/cli/src/config.rs index 0f8dd3b9d70..0fe53f1cdc2 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -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 { + self.resolve_config_with_command(config, None) + } + + pub fn resolve_config_with_command( + &self, + config: &RawConfig, + command: Option<&str>, + ) -> Result { 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) } diff --git a/cli/tests/test_config_command.rs b/cli/tests/test_config_command.rs index 65ace23d86c..d3713898dc4 100644 --- a/cli/tests/test_config_command.rs +++ b/cli/tests/test_config_command.rs @@ -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(); @@ -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.) @@ -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' "#); }