Skip to content

Commit

Permalink
Fix exclusive rules selection for only arg (#310)
Browse files Browse the repository at this point in the history
## Summary

Earlier, if a user had define a rule selection or exclusion using the
`lint.args` setting, it would collide with the `only` parameter. The
purpose of the `only` parameter is to only run Ruff for the given rule
excluding everything else. The "excluding everything else" part was done
with `--extend-ignore=ALL`. The problem, as highlighted in the linked
issue, was that if there's a user defined `--ignore` / `--select` (or
their `--extend-*` version), then the `ALL` directive won't work
because:

> When breaking ties between enabled and disabled rules (via select and
ignore, respectively), more specific prefixes override less specific
prefixes.
>
> _Reference: https://docs.astral.sh/ruff/settings/#ignore_

This means that between `--select=E,F` and `--ignore=ALL`, the former
wins.

This PR fixes this issue by checking for the following argument pattern
in user defined settings, skipping them if the `only` parameter is
given:

* `["--select", "A,B,C"]` / `["--select=A,B,C"]`
* `["--ignore", "A,B,C"]` / `["--ignore=A,B,C"]`

And their `--extend-*` version.

## Test Plan

Manual testing locally :)

fixes: astral-sh/ruff-vscode#328
  • Loading branch information
dhruvmanila authored Nov 7, 2023
1 parent 4dd4c0b commit 3dc7888
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions ruff_lsp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1157,11 +1157,30 @@ async def _run_check_on_document(
executable = _find_ruff_binary(settings, VERSION_REQUIREMENT_LINTER)
argv: list[str] = CHECK_ARGS + list(extra_args)

skip_next_arg = False
for arg in lint_args(settings):
if skip_next_arg:
skip_next_arg = False
continue
if arg in UNSUPPORTED_CHECK_ARGS:
log_to_output(f"Ignoring unsupported argument: {arg}")
else:
argv.append(arg)
continue
# If we're trying to run a single rule, we need to make sure to skip any of the
# arguments that would override it.
if only:
# Case 1: Option and it's argument as separate items
# (e.g. `["--select", "F821"]`).
if arg in ("--select", "--extend-select", "--ignore", "--extend-ignore"):
# Skip the following argument assuming it's a list of rules.
skip_next_arg = True
continue
# Case 2: Option and it's argument as a single item
# (e.g. `["--select=F821"]`).
elif arg.startswith(
("--select=", "--extend-select=", "--ignore=", "--extend-ignore=")
):
continue
argv.append(arg)

# If the Ruff version is not sufficiently recent, use the deprecated `--format`
# argument instead of `--output-format`.
Expand All @@ -1172,14 +1191,9 @@ async def _run_check_on_document(
argv.pop(index)
argv.insert(index, "--format")

# If we're trying to run a single rule, add it to the command line, and disable
# all other rules (if the Ruff version is sufficiently recent).
# If we're trying to run a single rule, add it to the command line.
if only:
if VERSION_REQUIREMENT_ALL_SELECTOR.contains(
executable.version, prereleases=True
):
argv += ["--extend-ignore", "ALL"]
argv += ["--extend-select", only]
argv += ["--select", only]

# Provide the document filename.
argv += ["--stdin-filename", document.path]
Expand Down

0 comments on commit 3dc7888

Please sign in to comment.