fix(ruff): stop ruff check from mutating the tree - #4
Merged
Merged
Conversation
`fix = true` under `[tool.ruff]` applies to every `ruff check` invocation in the repo, including CI. The lint job (`uv run ruff check --output-format=github packages/`) was therefore rewriting its own checkout and exiting 0: it inserted the `required-imports` entry missing from `packages/ensure_uv/__init__.py`, reported success, and threw the fix away. The committed source was never lint-clean, and the file ruff-check produced would itself have failed `ruff format --check` (no blank line after the module docstring) had the two jobs shared a checkout. - Add the missing `from __future__ import annotations` so the committed tree is genuinely clean under both `ruff check` and `ruff format --check`. - Drop `fix = true`. Autofix is now requested at the call site, which is already this repo's convention: the pre-commit ruff hook passes `args: [--fix]` explicitly, and a developer wanting autofix runs `ruff check --fix`. - Pass `--no-fix` in the CI lint job so the "must never mutate" requirement is stated where it is required, not only inherited from shared config. `unsafe-fixes = true` is kept: it only widens which fixes apply once fixing has been explicitly requested, so it is no longer reachable from a plain `ruff check`. Verified: with the violation reintroduced, the CI lint command exits 1 and leaves the file untouched.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect
pyproject.tomlsetfix = trueunder[tool.ruff]. That is a global default: everyruff checkin this repo autofixes, including CI's lint job.Reproduced on
origin/main(b801d7b), clean checkout,uv sync, ruff 0.14.8 fromuv.lock:The lint job inserted the
from __future__ import annotationsthatlint.isort.required-importsdemands, reported success, and discarded the fix when the runner was torn down. The committed source was never lint-clean.It is worse than a no-op: the file
ruff checkwrites is not whatruff formatwants — the inserted import gets no blank line after the module docstring, soruff format --checkexits 1 on it. CI only stayed green because theformatandlintjobs run in separate checkouts.The change
packages/ensure_uv/__init__.py— add the missing import and format it, so the committed tree is genuinely clean under bothruff checkandruff format --check. Applied with the repo's own pinned ruff (0.14.8, peruv.lock), not floating latest.Drop
fix = truerather than only patching the CI call site.fix = truein shared config makes every consumer of that config a writer — CI, hooks, editors, ad-hoc invocations — so patching one caller leaves the rest broken. Removing it costs the local developer nothing: autofix is still one flag away (ruff check --fix), and requesting it at the call site is already this repo's convention —.pre-commit-config.yamlpassesargs: [--fix]to the ruff hook explicitly rather than relying on the config default.Pass
--no-fixin the CI lint job as well. "This job must never mutate its checkout and report success" is a hard requirement of that job specifically, and stating it where it is required makes the job correct on its own terms instead of dependent on a config line a future edit could put back.unsafe-fixes = truekept. It is not part of this defect. It only widens which fixes apply once fixing has been requested, and withfix = truegone, fixing is always an explicit opt-in. Removing it would change what the existing pre-commit ruff hook fixes — a behaviour change unrelated to the problem here.Proof that CI now fails on unclean input
Violation reintroduced (import deleted again), exact CI command run:
The config change alone is sufficient — the old command (no
--no-fix) also now exits 1 and leaves the file untouched under the new config. The flag is the belt to that pair of braces.Gate
All
test.ymljob commands pass on this branch:ruff format --check,ruff check --no-fix,ty check,ensure-uv, the import smoke test.prek run --all-fileswith noSKIP.Pre-existing failure, not introduced here
prek run --all-filesfails onorigin/mainand still fails on this branch, inpackages/ensure_uv/version.pyonly:origin/main)ruffhookruff-formathookCause: version skew.
.pre-commit-config.yamlpinsruff-pre-commitat v0.16.5 whileuv.lockresolves ruff to 0.14.8, so the hook and CI run different linters. 0.16.5 rewrites# noqa: PLC0415into the new# ruff: ignore[...]spelling and then still reportsimport-outside-top-levelthree times inversion.py. Fixing that means bumping the locked ruff (uv remove/uv add) and migrating those suppressions — a separate change with its own behaviour implications, deliberately not folded into this PR.This PR strictly reduces that baseline failure: the
ruff-formathook goes Failed → Passed and one lint error is gone.