Skip to content

fix(ruff): summarize format --check output for ruff >= 0.16 wording (#3930) - #3965

Open
anujsingh-cse wants to merge 2 commits into
rtk-ai:developfrom
anujsingh-cse:fix/ruff-format-check-unused
Open

anujsingh-cse wants to merge 2 commits into
rtk-ai:developfrom
anujsingh-cse:fix/ruff-format-check-unused

Conversation

@anujsingh-cse

Copy link
Copy Markdown

Closes #3930

Problem

filter_ruff_format keys only off pre-0.12 ruff strings: "would reformat:" and "left unchanged". On ruff 0.16.6 format --check prints unformatted: File would be reformatted per file (with the path on a following --> path:row:col pointer line) and N files already formatted as the summary. Neither branch matched, so the filter fell through to an identity passthrough — 0% savings on a path meant to hit the 20% floor.

Repro (ruff 0.16.6):

ruff format --check . | wc -c     # 886
rtk ruff format --check . | wc -c # 886  -> 0.0% savings

Fix

Extend filter_ruff_format to recognise the current wording while keeping the old spellings:

  • per-file: match unformatted: and extract the path from the following --> path:row:col line, alongside the existing Would reformat: path
  • summary: match already formatted alongside the existing left unchanged
  • check-mode detection is now driven by !files_to_format.is_empty() (both old and new per-file issuers populate it) plus the existing would reformat fallback

Tests

Added two unit tests using the new wording (captured from a current ruff):

  • test_filter_ruff_format_all_formatted_ruff_016_wording — "5 files already formatted"
  • test_filter_ruff_format_needs_formatting_ruff_016_wording — the unformatted: + --> path:row:col two-line form

Existing old-wording tests unchanged and still pass; cargo fmt --check and cargo clippy --all-targets clean; 19 ruff tests pass. Verified end-to-end that ruff 0.16.6 format --check output (156 raw bytes) now flattens to a compact summary instead of passing through.

@rtk-wshm-sync-bot rtk-wshm-sync-bot Bot added bug Something isn't working ruff rust labels Sep 9, 2026
@rtk-wshm-sync-bot

Copy link
Copy Markdown

wshm · Automated triage by AI

📊 Automated PR Analysis

🐛 Type bug-fix
🟢 Risk low

Summary

Fixes filter_ruff_format to recognize ruff >= 0.16's new format --check output wording (unformatted: / already formatted / --> path:row:col pointer lines) while retaining support for the old pre-0.12 wording, restoring the intended output-summarization savings. Adds two unit tests covering the new wording.

Review Checklist

  • Tests present
  • Breaking change
  • Docs updated

Linked issues: #3930


Analyzed automatically by wshm · This is an automated analysis, not a human review.

@anujsingh-cse
anujsingh-cse force-pushed the fix/ruff-format-check-unused branch from cc5d361 to 6a000cf Compare September 13, 2026 04:15
@anujsingh-cse

Copy link
Copy Markdown
Author

Rebased onto latest \develop\ so it's up to date and mergeable. Happy to adjust anything reviewers would like.

@anujsingh-cse
anujsingh-cse force-pushed the fix/ruff-format-check-unused branch from 6a000cf to 02c286c Compare October 10, 2026 08:46
@anujsingh-cse

Copy link
Copy Markdown
Author

Rebased onto current develop and fixed the CI failure.

The branch was 300+ commits behind a develop that has since repaired broken rustdoc intra-doc links (the rustdoc gate failed on the stale base), and current stable clippy now flags the nested if in the unformatted-marker handling as collapsible_if. The two conditions are joined into a single if let ... && chain, and rustfmt rewrapped the affected literals.

All local gates pass against current develop: cargo fmt --all --check, cargo clippy --all-targets, cargo doc --no-deps, the test-isolation guard, and all 12 ruff_cmd tests. The fresh workflow run will need approval to start.

@Protocol-zero-0 Protocol-zero-0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this rebased head with real Ruff 0.17.0 on Linux. The default full-format mixed-file check now reports the dirty file correctly, and the 12 Ruff unit tests pass.

There is one blocking correctness issue in the supported --output-format concise path: a mixed clean/dirty set is summarized as all files formatted correctly. This is newly introduced relative to current develop (a4cddfc), which preserves the actual concise diagnostics. The process still exits 1, but every unformatted-file diagnostic disappears.

I compared seven real CLI cases (28 raw/develop/#3964/#3965 commands): full mixed, concise mixed, concise 40-dirty/1-clean, concise dirty-only, concise clean-only, JSON output and invalid syntax. Child exit statuses remain 0/1/2 as appropriate. This is targeted review evidence; I did not run the full quality pipeline or other operating systems.

// Check if all files are formatted
if files_to_format.is_empty() && output_lower.contains("left unchanged") {
if files_to_format.is_empty()
&& (output_lower.contains("left unchanged") || output_lower.contains("already formatted"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve concise-format failures before returning the all-formatted summary

Ruff supports ruff format --check --output-format concise bad.py clean.py. With bad.py containing x= [1,2,3] and clean.py containing x = [1, 2, 3], Ruff 0.17.0 emits:

bad.py:1:2: unformatted: File would be reformatted
1 file would be reformatted, 1 file already formatted

The concise diagnostic has no following --> line, so the new parser leaves files_to_format empty. The new already formatted condition then returns Ruff format: All files formatted correctly, discarding the dirty file. The same happens with 40 dirty files and one clean file. Both raw Ruff and RTK still exit 1; the bug is the misleading filtered body, not the exit status.

Please parse the concise location form or conservatively preserve the raw failure output when a reformat marker/count is present. An empty collected-path list must not establish that all files are clean. A mixed concise-output regression test would cover this branch.

Real `ruff format --check --output-format concise` (0.17.0) on a mixed
clean/dirty set ends with a summary that also names already-formatted
files:

    dirty.py:1:6: unformatted: File would be reformatted
    1 file would be reformatted, 1 file already formatted

The concise per-file lines never reach the `-->` pairing, so
`files_to_format` stays empty, and the all-formatted guard fired on the
"already formatted" half of the summary alone — reporting every
unformatted-file diagnostic as gone while the process still exited 1.

The clean conclusion is now only drawn when the output contains no
reformatted indication at all: no "unformatted" and no "would be
reformat". Mixed concise runs fall through and pass the raw
diagnostics through, matching develop.
@anujsingh-cse

Copy link
Copy Markdown
Author

Fixed in c9dc768. Root cause confirmed on real Ruff 0.17.0: the mixed concise run ends with 1 file would be reformatted, 1 file already formatted. The concise per-file lines (dirty.py:1:6: unformatted: File would be reformatted) never reach the --> pairing, so files_to_format stays empty, and the all-formatted guard fired on the "already formatted" half of the summary alone. Develop was safe only because its guard matched "left unchanged" and not the new wording.

The clean conclusion now also requires that the output contains no reformatted indication at all — no unformatted and no would be reformat — so mixed concise runs fall through and pass the raw diagnostics through unchanged.

Re-verified against real Ruff 0.17.0 through the built rtk binary, matching your seven-case shape:

  • concise mixed (1 dirty + 1 clean): both concise lines pass through verbatim, exit 1
  • concise dirty-only: diagnostics pass through, exit 1
  • concise clean-only: raw 2 files already formatted (the runner's never_worse guard keeps the shorter raw line over the summary), exit 0
  • full-format mixed: still summarized — Ruff format: 1 files need formatting + file list + 1 files already formatted + hint, exit 1
  • two regression tests added with the captured 0.17.0 concise shapes (mixed preserves diagnostics; clean-only summarizes)

All 14 ruff_cmd unit tests pass; cargo fmt --all --check, cargo clippy --all-targets, cargo doc --no-deps, and the test-isolation guard are green.

@Protocol-zero-0 Protocol-zero-0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independently rechecked c9dc768 with real Ruff 0.17.0 against its exact parent (02c286c).

Seven cases / 21 raw-parent-head executions cover full-format mixed, concise mixed/many/dirty/clean, explicit JSON, and a syntax error. The prior false-clean conclusion reproduces for concise mixed/many; this head preserves those diagnostics verbatim instead. Dirty-only stays correct, full-format mixed remains summarized, the clean control exits 0, JSON remains parseable with the same payload, and the syntax-error diagnostic survives. Every head exit code matches raw Ruff (including 1 for formatting failures and 2 for invalid syntax).

All 14 focused Ruff tests pass, and cargo fmt --all --check passes. This clears my earlier concise-output blocker. Approval covers this narrow wording/guard fix and the local Linux checks above; it does not select between this PR and the overlapping #3964, or replace the maintainer's integration decision. I did not rerun the full repository suite or other platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ruff rust

Projects

None yet

Development

Successfully merging this pull request may close these issues.

filter_ruff_format matches pre-0.12 ruff wording, so rtk ruff format --check compresses nothing

2 participants