From 2b9c19484fbd610c95447f194b019950019d8a74 Mon Sep 17 00:00:00 2001 From: Victorien Elvinger Date: Wed, 15 May 2024 17:48:38 +0200 Subject: [PATCH] refactor: allow group as rule filter --- CHANGELOG.md | 23 +- crates/biome_analyze/src/lib.rs | 9 +- crates/biome_cli/src/commands/lint.rs | 4 +- crates/biome_cli/src/commands/mod.rs | 13 +- .../migrate/eslint_any_rule_to_biome.rs | 4 + crates/biome_cli/src/execute/mod.rs | 6 +- crates/biome_cli/tests/commands/lint.rs | 92 ++++++++ .../main_commands_lint/lint_help.snap | 9 +- .../lint_rule_filter_group.snap | 67 ++++++ .../lint_rule_filter_group_disabled.snap | 67 ++++++ ..._rule_filter_group_with_disabled_rule.snap | 33 +++ .../lint_rule_missing_group.snap | 2 +- .../lint_rule_rule_doesnt_exist.snap | 2 +- crates/biome_configuration/src/linter/mod.rs | 52 +++-- .../biome_configuration/src/linter/rules.rs | 206 +++++++++++++----- .../src/file_handlers/javascript.rs | 32 ++- .../biome_service/src/file_handlers/json.rs | 28 ++- crates/biome_service/src/file_handlers/mod.rs | 4 +- crates/biome_service/src/workspace.rs | 6 +- xtask/codegen/src/generate_configuration.rs | 206 ++++++++++-------- 20 files changed, 661 insertions(+), 204 deletions(-) create mode 100644 crates/biome_cli/tests/snapshots/main_commands_lint/lint_rule_filter_group.snap create mode 100644 crates/biome_cli/tests/snapshots/main_commands_lint/lint_rule_filter_group_disabled.snap create mode 100644 crates/biome_cli/tests/snapshots/main_commands_lint/lint_rule_filter_group_with_disabled_rule.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index df3be927a7d8..c11523ff0127 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,24 +19,35 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b - Add a new option `--rule` to the command `biome lint` ([#58](https://github.com/biomejs/biome/issues/58)). - This new option allows you to execute a single rule. This option is convenient to test a rule or apply the code fixes of a single rule. + This new option allows you to execute a single rule or a rule group. + This option is convenient to test a rule or apply the code fixes of a single rule. - For example, you can execute the `style/useNamingConvention` rule on a set of files: + For example, you can execute the `style/useNamingConvention` rule on the working directory: ```shell - biome lint --rule=style/useNamingConvention src/index.js src/main.js + biome lint --rule=style/useNamingConvention ./ ``` - If the rule has code action (autofix), you can use `--apply` to apply the fix: + If the rule has a code action (autofix), you can use `--apply` to apply the fix: ```shell - biome lint --rule=style/useNamingConvention --apply index.js src/main.js + biome lint --rule=style/useNamingConvention --apply ./ ``` - The option takes the rule options set in the Biome configuration file into account. + The option takes the rule options in the Biome configuration file into account. Only, the severity level of the rule is overridden by its default value, i.e. `error` for a recommended rule or `warn` otherwise. + You can also run a group of rules: + + ```shell + biome lint --rule=suspicous src/main.js + ``` + + In this case, the severity level of a rule is not overridden. + Thus, disabled rules stay disabled. + To ensure that the group is run, the `recommended` field of the group is turned on. + The option is compatible with other options such as `--apply`, `--apply-unsafe` and `--reporter`. Contributed by @Conaclos diff --git a/crates/biome_analyze/src/lib.rs b/crates/biome_analyze/src/lib.rs index fd1cf9d60144..e00133aa2211 100644 --- a/crates/biome_analyze/src/lib.rs +++ b/crates/biome_analyze/src/lib.rs @@ -768,7 +768,14 @@ pub enum RuleFilter<'a> { Rule(&'a str, &'a str), } -impl RuleFilter<'_> { +impl<'a> RuleFilter<'a> { + // Returns the group name of thie filter. + pub fn group(self) -> &'a str { + match self { + RuleFilter::Group(group) => group, + RuleFilter::Rule(group, _) => group, + } + } /// Return `true` if the group `G` matches this filter fn match_group(self) -> bool { match self { diff --git a/crates/biome_cli/src/commands/lint.rs b/crates/biome_cli/src/commands/lint.rs index d37b5503e9ad..035eef8992a6 100644 --- a/crates/biome_cli/src/commands/lint.rs +++ b/crates/biome_cli/src/commands/lint.rs @@ -5,7 +5,7 @@ use crate::commands::{ use crate::{ execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, }; -use biome_configuration::linter::RuleCode; +use biome_configuration::linter::RuleSelector; use biome_configuration::vcs::PartialVcsConfiguration; use biome_configuration::{ PartialConfiguration, PartialFilesConfiguration, PartialLinterConfiguration, @@ -25,7 +25,7 @@ pub(crate) struct LintCommandPayload { pub(crate) vcs_configuration: Option, pub(crate) files_configuration: Option, pub(crate) paths: Vec, - pub(crate) rule: Option, + pub(crate) rule: Option, pub(crate) stdin_file_path: Option, pub(crate) staged: bool, pub(crate) changed: bool, diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index e83253dd9f82..df3bd4d93dec 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -4,7 +4,7 @@ use crate::diagnostics::DeprecatedConfigurationFile; use crate::execute::Stdin; use crate::logging::LoggingKind; use crate::{CliDiagnostic, CliSession, LoggingLevel, VERSION}; -use biome_configuration::linter::RuleCode; +use biome_configuration::linter::RuleSelector; use biome_configuration::{ css::partial_css_formatter, javascript::partial_javascript_formatter, json::partial_json_formatter, partial_configuration, partial_files_configuration, @@ -153,10 +153,13 @@ pub enum BiomeCommand { #[bpaf(external, hide_usage)] cli_options: CliOptions, - /// Run only the given rule taking into account the options set in the configurations files. - /// The severity level of the rule is set to its default. - #[bpaf(long("rule"), argument("NAME"))] - rule: Option, + /// Run only the given rule or rule group taking the configurations file into account. + /// + /// Example: `biome lint --rule=correctness/noUnusedVariables` + /// + /// Example: `biome lint --rule=suspicious` + #[bpaf(long("rule"), argument("GROUP|RULE"))] + rule: Option, /// Use this option when you want to format code piped from `stdin`, and print the output to `stdout`. /// diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index 31476e90e0fd..2655fa7951ec 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -1178,6 +1178,10 @@ pub(crate) fn migrate_eslint_any_rule( rule.set_level(rule_severity.into()); } "react/jsx-boolean-value" => { + if !options.include_inspired { + results.has_inspired_rules = true; + return false; + } let group = rules.style.get_or_insert_with(Default::default); let rule = group.no_implicit_boolean.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); diff --git a/crates/biome_cli/src/execute/mod.rs b/crates/biome_cli/src/execute/mod.rs index 7725c5513592..5b58bb8bf11a 100644 --- a/crates/biome_cli/src/execute/mod.rs +++ b/crates/biome_cli/src/execute/mod.rs @@ -12,7 +12,7 @@ use crate::execute::traverse::traverse; use crate::reporter::json::{JsonReporter, JsonReporterVisitor}; use crate::reporter::terminal::{ConsoleReporter, ConsoleReporterVisitor}; use crate::{CliDiagnostic, CliSession, DiagnosticsPayload, Reporter}; -use biome_configuration::linter::RuleCode; +use biome_configuration::linter::RuleSelector; use biome_console::{markup, ConsoleExt}; use biome_diagnostics::adapters::SerdeJsonError; use biome_diagnostics::{category, Category}; @@ -126,8 +126,8 @@ pub enum TraversalMode { /// 1. The virtual path to the file /// 2. The content of the file stdin: Option, - - rule: Option, + /// Run only the given rule or rule group taking the configurations file into account. + rule: Option, }, /// This mode is enabled when running the command `biome ci` CI { diff --git a/crates/biome_cli/tests/commands/lint.rs b/crates/biome_cli/tests/commands/lint.rs index b7474a456816..5c376e5722e5 100644 --- a/crates/biome_cli/tests/commands/lint.rs +++ b/crates/biome_cli/tests/commands/lint.rs @@ -3498,3 +3498,95 @@ fn lint_rule_filter_with_linter_disabled() { result, )); } + +#[test] +fn lint_rule_filter_group() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + let config = r#"{ + "linter": { + "rules": { + "suspicious": { + "recommended": false + } + } + } + }"#; + let content = r#" + export function CONSTANT_CASE(){ + debugger; + } + "#; + + let file_path = Path::new("check.js"); + fs.insert(file_path.into(), content.as_bytes()); + let config_path = Path::new("biome.json"); + fs.insert(config_path.into(), config.as_bytes()); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from( + [ + ("lint"), + "--rule=suspicious", + file_path.as_os_str().to_str().unwrap(), + ] + .as_slice(), + ), + ); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "lint_rule_filter_group", + fs, + console, + result, + )); +} + +#[test] +fn lint_rule_filter_group_with_disabled_rule() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + let config = r#"{ + "linter": { + "rules": { + "suspicious": { + "noDebugger": "off" + } + } + } + }"#; + let content = r#" + export function CONSTANT_CASE(){ + debugger; + } + "#; + + let file_path = Path::new("check.js"); + fs.insert(file_path.into(), content.as_bytes()); + let config_path = Path::new("biome.json"); + fs.insert(config_path.into(), config.as_bytes()); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from( + [ + ("lint"), + "--rule=suspicious", + file_path.as_os_str().to_str().unwrap(), + ] + .as_slice(), + ), + ); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "lint_rule_filter_group_with_disabled_rule", + fs, + console, + result, + )); +} diff --git a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap index 729e257fe5bf..a79859326b01 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap @@ -7,7 +7,8 @@ expression: content ```block Run various checks on a set of files. -Usage: lint [--apply] [--apply-unsafe] [--rule=NAME] [--staged] [--changed] [--since=REF] [PATH]... +Usage: lint [--apply] [--apply-unsafe] [--rule=] [--staged] [--changed] [--since=REF] [PATH +]... Set of properties to integrate Biome with a VCS software. --vcs-client-kind= The kind of client. @@ -60,8 +61,10 @@ Available positional items: Available options: --apply Apply safe fixes, formatting and import sorting --apply-unsafe Apply safe fixes and unsafe fixes, formatting and import sorting - --rule=NAME Run only the given rule taking into account the options set in the configurations - files. The severity level of the rule is set to its default. + --rule= Run only the given rule or rule group taking the configurations file into + account. + Example: `biome lint --rule=correctness/noUnusedVariables` + Example: `biome lint --rule=suspicious` --stdin-file-path=PATH Use this option when you want to format code piped from `stdin`, and print the output to `stdout`. The file doesn't need to exist on disk, what matters is the extension of diff --git a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_rule_filter_group.snap b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_rule_filter_group.snap new file mode 100644 index 000000000000..10e299f26579 --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_rule_filter_group.snap @@ -0,0 +1,67 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: content +--- +## `biome.json` + +```json +{ + "linter": { + "rules": { + "suspicious": { + "recommended": false + } + } + } +} +``` + +## `check.js` + +```js + + export function CONSTANT_CASE(){ + debugger; + } + +``` + +# Termination Message + +```block +lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Some errors were emitted while running checks. + + + +``` + +# Emitted Messages + +```block +check.js:3:9 lint/suspicious/noDebugger FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × This is an unexpected use of the debugger statement. + + 2 │ export function CONSTANT_CASE(){ + > 3 │ debugger; + │ ^^^^^^^^^ + 4 │ } + 5 │ + + i Unsafe fix: Remove debugger statement + + 1 1 │ + 2 2 │ export function CONSTANT_CASE(){ + 3 │ - ········debugger; + 4 3 │ } + 5 4 │ + + +``` + +```block +Checked 1 file in