diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 0d09aca6cd..99d5a99a15 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,5 +1,37 @@ # Breaking Changes +## Unreleased + +### `select`, `extend-select`, `ignore`, and `extend-ignore` have new semantics ([#2312](https://github.com/charliermarsh/ruff/pull/2312)) + +Previously, the interplay between `select` and its related options could lead to unexpected +behavior. For example, `ruff --select E501 --ignore ALL` and `ruff --select E501 --extend-ignore +ALL` behaved differently. (See [#2312](https://github.com/charliermarsh/ruff/pull/2312) for more +examples.) + +When Ruff determines the enabled rule set, it has to reconcile `select` and `ignore` from a variety +of sources, including the current `pyproject.toml`, any inherited `pyproject.toml` files, and the +CLI. + +The new semantics are such that Ruff uses the "highest-priority" `select` as the basis for the rule +set, and then applies any `extend-select`, `ignore`, and `extend-ignore` adjustments. CLI options +are given higher priority than `pyproject.toml` options, and the current `pyproject.toml` file is +given higher priority than any inherited `pyproject.toml` files. + +`extend-select` and `extend-ignore` are no longer given "top priority"; instead, they merely append +to the `select` and `ignore` lists, as in Flake8. + +This change is largely backwards compatible -- most users should experience no change in behavior. +However, as an example of a breaking change, consider the following: + +```toml +[tool.ruff] +ignore = ["F401"] +``` + +Running `ruff --select F` would previously have enabled all `F` rules, apart from `F401`. Now, it +will enable all `F` rules, including `F401`, as the command line's `--select` resets the resolution. + ## 0.0.237 ### `--explain`, `--clean`, and `--generate-shell-completion` are now subcommands ([#2190](https://github.com/charliermarsh/ruff/pull/2190)) diff --git a/README.md b/README.md index 3208b10850..f82ed5e293 100644 --- a/README.md +++ b/README.md @@ -528,6 +528,33 @@ By default, Ruff will also skip any files that are omitted via `.ignore`, `.giti Files that are passed to `ruff` directly are always linted, regardless of the above criteria. For example, `ruff /path/to/excluded/file.py` will always lint `file.py`. +### Rule resolution + +The set of enabled rules is controlled via the [`select`](#select) and [`ignore`](#ignore) settings, +along with the [`extend-select`](#extend-select) and [`extend-ignore`](#extend-ignore) modifiers. + +To resolve the enabled rule set, Ruff may need to reconcile `select` and `ignore` from a variety +of sources, including the current `pyproject.toml`, any inherited `pyproject.toml` files, and the +CLI (e.g., `--select`). + +In those scenarios, Ruff uses the "highest-priority" `select` as the basis for the rule set, and +then applies any `extend-select`, `ignore`, and `extend-ignore` adjustments. CLI options are given +higher priority than `pyproject.toml` options, and the current `pyproject.toml` file is given higher +priority than any inherited `pyproject.toml` files. + +For example, given the following `pyproject.toml` file: + +```toml +[tool.ruff] +select = ["E", "F"] +ignore = ["F401"] +``` + +Running `ruff --select F401` would result in Ruff enforcing `F401`, and no other rules. + +Running `ruff --extend-select B` would result in Ruff enforcing the `E`, `F`, and `B` rules, with +the exception of `F401`. + ### Ignoring errors To omit a lint rule entirely, add it to the "ignore" list via [`ignore`](#ignore) or