Skip to content

Commit

Permalink
feat(cli): add --only and --skip options
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed May 22, 2024
1 parent e64ab12 commit c4a40f8
Show file tree
Hide file tree
Showing 42 changed files with 1,778 additions and 449 deletions.
37 changes: 17 additions & 20 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,36 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

#### New features

- Add a new option `--rule` to the command `biome lint` ([#58](https://github.com/biomejs/biome/issues/58)).
- Add two new options `--only` and `--skip` to the command `biome lint` ([#58](https://github.com/biomejs/biome/issues/58)).

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 the working directory:
The `--only` option allows you to run a given rule or rule group,
For example, the following command runs only the `style/useNamingConvention` and `style/noInferrableTypes` rules.
If the rule is disabled in the configuration, then its severity level is set to `error` for a recommended rule or `warn` otherwise.

```shell
biome lint --rule=style/useNamingConvention ./
biome lint --only=style/useNamingConvention --only=style/noInferrableTypes
```

If the rule has a code action (autofix), you can use `--apply` to apply the fix:
Passing a group does not change the severity level of the rules in the group.
All the disabled rules in the group will remain disabled.
To ensure that the group is run, the `recommended` field of the group is enabled.
The `nursery` group cannot be passed, as no rules are enabled by default in the nursery group.

The `--skip` option allows you to skip the execution of a given group or a given rule.
For example, the following command skips the `style` group and the `suspicious/noExplicitAny` rule.

```shell
biome lint --rule=style/useNamingConvention --apply ./
biome lint --skip=style --skip=suspicious/noExplicitAny
```

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:
You can also use `--only` and `--skip` together.
The following command executes only the rules from the `style` group, but the `style/useNamingConvention` rule.

```shell
biome lint --rule=suspicious src/main.js
biome lint --only=style --skip=style/useNamingConvention
```

In this case, the severity level of a rule is not overridden.
Thus, the disabled rules stay disabled.
To ensure that the group is run, the `recommended` field of the group is turned on.
The `nursery` group cannot be passed because no rules are enabled in the nursery group by default.

The option is compatible with other options such as `--apply`, `--apply-unsafe` and `--reporter`.
These options are compatible with other options such as `--write` (previously `--apply`), and `--reporter`.

Contributed by @Conaclos

Expand Down
12 changes: 12 additions & 0 deletions crates/biome_analyze/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,18 @@ impl<'a> RuleFilter<'a> {
}
}
}

pub fn contains(self, other: Self) -> bool {
match self {
RuleFilter::Group(group) => group == other.group(),
RuleFilter::Rule(group, rule) => match other {
RuleFilter::Group(_) => false,
RuleFilter::Rule(other_group, other_rule) => {
group == other_group && rule == other_rule
}
},
}
}
}

impl<'a> Debug for RuleFilter<'a> {
Expand Down
18 changes: 15 additions & 3 deletions crates/biome_cli/src/commands/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pub(crate) struct LintCommandPayload {
pub(crate) vcs_configuration: Option<PartialVcsConfiguration>,
pub(crate) files_configuration: Option<PartialFilesConfiguration>,
pub(crate) paths: Vec<OsString>,
pub(crate) rule: Option<RuleSelector>,
pub(crate) only: Vec<RuleSelector>,
pub(crate) skip: Vec<RuleSelector>,
pub(crate) stdin_file_path: Option<String>,
pub(crate) staged: bool,
pub(crate) changed: bool,
Expand All @@ -54,7 +55,8 @@ pub(crate) fn lint(session: CliSession, payload: LintCommandPayload) -> Result<(
cli_options,
mut linter_configuration,
mut paths,
rule,
only,
skip,
stdin_file_path,
vcs_configuration,
files_configuration,
Expand All @@ -67,6 +69,15 @@ pub(crate) fn lint(session: CliSession, payload: LintCommandPayload) -> Result<(
} = payload;
setup_cli_subscriber(cli_options.log_level, cli_options.log_kind);

if !skip.is_empty() {
if let Some(selector) = only.iter().find(|selector| skip.contains(selector)) {
return Err(CliDiagnostic::incompatible_arguments(
format!("--only={selector}"),
format!("--skip={selector}"),
));
}
}

let fix_file_mode = determine_fix_file_mode(
FixFileModeOptions {
apply,
Expand Down Expand Up @@ -161,7 +172,8 @@ pub(crate) fn lint(session: CliSession, payload: LintCommandPayload) -> Result<(
Execution::new(TraversalMode::Lint {
fix_file_mode,
stdin,
rule,
only,
skip,
})
.set_report(&cli_options),
session,
Expand Down
18 changes: 14 additions & 4 deletions crates/biome_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,21 @@ pub enum BiomeCommand {
///
/// - When a rule group is passed, the `recommended` flag is enabled, but if the `all` flag is enabled.
///
/// Example: `biome lint --rule=correctness/noUnusedVariables`
/// Example: `biome lint --only=correctness/noUnusedVariables --only=suspicious`
#[bpaf(long("only"), argument("GROUP|RULE"))]
only: Vec<RuleSelector>,

/// Skip the given rule or rule group.
///
/// The option overrides the Biome configuration file as follows:
///
/// - When a rule is passed, its severity level is set to `off'.
///
/// - When a rule group is passed, all rules of the group are skipped.
///
/// Example: `biome lint --rule=suspicious`
#[bpaf(long("rule"), argument("GROUP|RULE"))]
rule: Option<RuleSelector>,
/// Example: `biome lint --skip=correctness/noUnusedVariables --skip=suspicious`
#[bpaf(long("skip"), argument("GROUP|RULE"))]
skip: Vec<RuleSelector>,

/// Use this option when you want to format code piped from `stdin`, and print the output to `stdout`.
///
Expand Down
7 changes: 6 additions & 1 deletion crates/biome_cli/src/execute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@ pub enum TraversalMode {
/// The option overrides the Biome configuration file as follows:
/// - When a rule is passed, its severity level is set to `error' if it is a recommended rule, or `warn' otherwise.
/// - When a rule group is passed, the `recommended` flag is enabled, but if the `all` flag is enabled.
rule: Option<RuleSelector>,
only: Vec<RuleSelector>,
/// Skip the given rule or rule group.
/// The option overrides the Biome configuration file as follows:
/// - When a rule is passed, its severity level is set to `off'.
/// - When a rule group is passed, all rules of the group are skipped.
skip: Vec<RuleSelector>,
},
/// This mode is enabled when running the command `biome ci`
CI {
Expand Down
7 changes: 6 additions & 1 deletion crates/biome_cli/src/execute/process_file/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ pub(crate) fn format_with_guard<'ctx>(
debug!("Pulling diagnostics from parsed file");
let diagnostics_result = workspace_file
.guard()
.pull_diagnostics(RuleCategories::SYNTAX, max_diagnostics.into(), None)
.pull_diagnostics(
RuleCategories::SYNTAX,
max_diagnostics.into(),
Vec::new(),
Vec::new(),
)
.with_file_path_and_code(
workspace_file.path.display().to_string(),
category!("format"),
Expand Down
14 changes: 8 additions & 6 deletions crates/biome_cli/src/execute/process_file/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,19 @@ pub(crate) fn lint_with_guard<'ctx>(
}

let max_diagnostics = ctx.remaining_diagnostics.load(Ordering::Relaxed);
let rule = if let TraversalMode::Lint { rule, .. } = ctx.execution.traversal_mode() {
*rule
} else {
None
};
let (only, skip) =
if let TraversalMode::Lint { only, skip, .. } = ctx.execution.traversal_mode() {
(only.clone(), skip.clone())
} else {
(Vec::new(), Vec::new())
};
let pull_diagnostics_result = workspace_file
.guard()
.pull_diagnostics(
RuleCategories::LINT | RuleCategories::SYNTAX,
max_diagnostics.into(),
rule,
only,
skip,
)
.with_file_path_and_code(
workspace_file.path.display().to_string(),
Expand Down
9 changes: 5 additions & 4 deletions crates/biome_cli/src/execute/std_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,18 @@ pub(crate) fn run<'a>(
}
}

let rule = if let TraversalMode::Lint { rule, .. } = mode.traversal_mode() {
*rule
let (only, skip) = if let TraversalMode::Lint { only, skip, .. } = mode.traversal_mode() {
(only.clone(), skip.clone())
} else {
None
(Vec::new(), Vec::new())
};
if !mode.is_check_apply_unsafe() {
let result = workspace.pull_diagnostics(PullDiagnosticsParams {
categories: RuleCategories::LINT | RuleCategories::SYNTAX,
path: biome_path.clone(),
max_diagnostics: mode.max_diagnostics.into(),
rule,
only,
skip,
})?;
diagnostics.extend(result.diagnostics);
}
Expand Down
6 changes: 4 additions & 2 deletions crates/biome_cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ impl<'app> CliSession<'app> {
cli_options,
linter_configuration,
paths,
rule,
only,
skip,
stdin_file_path,
vcs_configuration,
files_configuration,
Expand All @@ -145,7 +146,8 @@ impl<'app> CliSession<'app> {
cli_options,
linter_configuration,
paths,
rule,
only,
skip,
stdin_file_path,
vcs_configuration,
files_configuration,
Expand Down
Loading

0 comments on commit c4a40f8

Please sign in to comment.