Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add enabled config for fix tools #4401

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

* CommitId / ChangeId template types now support `.normal_hex()`.

* Fix tools have a new config `fix.tools.NAME.enabled` which can be
used to configure a disabled tool in user config and enable it in a
individual repo's config.

### Fixed bugs

* Fixed panic when parsing invalid conflict markers of a particular form.
Expand Down
15 changes: 13 additions & 2 deletions cli/src/commands/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ use crate::ui::Ui;
/// empty, no files will be affected by the tool. If there are multiple
/// patterns, the tool is applied only once to each file in the union of the
/// patterns.
/// - `enabled`: Enables or disables the tool. If omitted, the tool is enabled.
/// This is useful for defining disabled tools in user configuration that can
/// be enabled in individual repositories with one config setting.
///
/// For example, the following configuration defines how two code formatters
/// (`clang-format` and `black`) will apply to three different file extensions
Expand Down Expand Up @@ -432,6 +435,12 @@ struct ToolsConfig {
struct RawToolConfig {
command: CommandNameAndArgs,
patterns: Vec<String>,
#[serde(default = "default_tool_enabled")]
enabled: bool,
}

fn default_tool_enabled() -> bool {
true
}

/// Parses the `fix.tools` config table.
Expand Down Expand Up @@ -474,8 +483,10 @@ fn get_tools_config(ui: &mut Ui, config: &config::Config) -> Result<ToolsConfig,
let mut tools: Vec<ToolConfig> = tools_table
.into_iter()
.sorted_by(|a, b| a.0.cmp(&b.0))
.map(|(_name, value)| -> Result<ToolConfig, CommandError> {
let tool: RawToolConfig = value.try_deserialize()?;
.map(|(_name, value): (_, _)| value.try_deserialize::<RawToolConfig>())
.filter_ok(|tool| tool.enabled)
.map(|tool| -> Result<ToolConfig, CommandError> {
let tool = tool?;
Ok(ToolConfig {
command: tool.command,
matcher: FilesetExpression::union_all(
Expand Down
5 changes: 5 additions & 0 deletions cli/src/config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,11 @@
"type": "string"
},
"description": "Filesets that will be affected by this tool"
},
"enabled": {
"type": "boolean",
"description": "Disables this tool if set to false",
"default": true
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions cli/tests/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,9 @@ the values have the following properties:
empty, no files will be affected by the tool. If there are multiple
patterns, the tool is applied only once to each file in the union of the
patterns.
- `enabled`: Enables or disables the tool. If omitted, the tool is enabled.
This is useful for defining disabled tools in user configuration that can
be enabled in individual repositories with one config setting.

For example, the following configuration defines how two code formatters
(`clang-format` and `black`) will apply to three different file extensions
Expand Down
42 changes: 42 additions & 0 deletions cli/tests/test_fix_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,48 @@ fn test_config_multiple_tools_with_same_name() {
insta::assert_snapshot!(content, @"Bar\n");
}

#[test]
fn test_config_disabled_tools() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let repo_path = test_env.env_root().join("repo");
let formatter_path = assert_cmd::cargo::cargo_bin("fake-formatter");
assert!(formatter_path.is_file());
let escaped_formatter_path = formatter_path.to_str().unwrap().replace('\\', r"\\");
test_env.add_config(&format!(
r###"
[fix.tools.tool-1]
# default is enabled
command = ["{formatter}", "--uppercase"]
patterns = ["foo"]

[fix.tools.tool-2]
enabled = true
command = ["{formatter}", "--lowercase"]
patterns = ["bar"]

[fix.tools.tool-3]
enabled = false
command = ["{formatter}", "--lowercase"]
patterns = ["baz"]
"###,
formatter = escaped_formatter_path.as_str()
));

std::fs::write(repo_path.join("foo"), "Foo\n").unwrap();
std::fs::write(repo_path.join("bar"), "Bar\n").unwrap();
std::fs::write(repo_path.join("baz"), "Baz\n").unwrap();

let (_stdout, _stderr) = test_env.jj_cmd_ok(&repo_path, &["fix"]);

let content = test_env.jj_cmd_success(&repo_path, &["file", "show", "foo", "-r", "@"]);
insta::assert_snapshot!(content, @"FOO\n");
let content = test_env.jj_cmd_success(&repo_path, &["file", "show", "bar", "-r", "@"]);
insta::assert_snapshot!(content, @"bar\n");
let content = test_env.jj_cmd_success(&repo_path, &["file", "show", "baz", "-r", "@"]);
insta::assert_snapshot!(content, @"Baz\n");
}

#[test]
fn test_config_tables_overlapping_patterns() {
let test_env = TestEnvironment::default();
Expand Down
21 changes: 21 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,27 @@ command = ["head", "-n", "10"]
patterns = ["numbers.txt"]
```

### Disabling and enabling tools

Tools can be disabled and enabled with the optional `enabled` config. This
allows you to define tools globally but enable them only for specific
repositories.

In the user configuration, define a disabled tool for running rustfmt:

```toml
[fix.tools.rustfmt]
enabled = false
command = ["rustfmt", "--emit", "stdout"]
patterns = ["glob:'**/*.rs'"]
```
jennings marked this conversation as resolved.
Show resolved Hide resolved

Then to use the tool in a specific repository, set the `enabled` config:

```shell
$ jj config set --repo fix.tools.rustfmt.enabled true
```

## Commit Signing

`jj` can be configured to sign and verify the commits it creates using either
Expand Down