Skip to content

Use the report destination to color ruff check diagnostics - #29899

Merged
AlexWaygood merged 1 commit into
mainfrom
alex/ruff-check-output-color
Nov 2, 2026
Merged

AlexWaygood merged 1 commit into
mainfrom
alex/ruff-check-output-color

Conversation

@AlexWaygood

@AlexWaygood AlexWaygood commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

On main, ruff check --color=always example.py >report.txt saves colored diagnostics, but replacing >report.txt with --output-file report.txt strips the color. This PR makes both ways of saving the report honor --color=always.

Automatic color also goes wrong with ruff check --fix -. Ruff writes the fixed source to stdout and diagnostics to stderr, yet it checks whether stdout is a terminal to decide whether to color the diagnostics. Redirecting only stderr can put ANSI escapes in the saved report, while redirecting only stdout can leave the diagnostics plain on the terminal.

Ruff now applies the color policy from #29898 to the destination that receives the diagnostics. When the flags and environment leave color up to terminal detection, Ruff checks that destination. With --diff -, for example, a patch printed to the terminal on stdout can keep its color while the fix summary redirected from stderr stays plain.

Test plan

This video compares the base of this PR (#29898 at baa3088701) with the fix (779a511358). Each command uses the same one-line input, print(unknown).

ruff-report-color.mp4
Manual split-stream reproduction and results

Run these commands from a terminal in a scratch directory, first with ruff from the base commit (baa3088701) on PATH, then with the build from this PR. The tr pipelines count escape bytes in the redirected files.

unset NO_COLOR FORCE_COLOR CLICOLOR CLICOLOR_FORCE
export TERM=xterm-256color FORCE_HYPERLINK=0

check_stdin() {
    ruff check --isolated --no-cache --color=auto --output-format=concise "$@" -
}

printf 'print(unknown)\n' | check_stdin --fix --select F821 2>err
LC_ALL=C tr -cd '\033' <err | wc -c
printf 'print(unknown)\n' | check_stdin --fix --select F821 >out
cat out

On the base commit, err contained 11 escape bytes. With this change it contains zero. Reversing the redirection (>out) changed the F821 diagnostic on the terminal from plain to colored. On both revisions, out contained the unchanged source, print(unknown).

With --diff, stdout carries the patch and stderr carries the fix summary.

printf 'import os\nprint(unknown)\n' | check_stdin --diff --config 'show-fixes = true' 2>summary
LC_ALL=C tr -cd '\033' <summary | wc -c
printf 'import os\nprint(unknown)\n' | check_stdin --diff --config 'show-fixes = true' >patch
LC_ALL=C tr -cd '\033' <patch | wc -c

The removed import was red on the terminal on both revisions, while the escape count in summary dropped from 10 to zero. With >patch, the patch contained zero escapes on both revisions, and the fix summary on the terminal changed from plain to colored.

@AlexWaygood AlexWaygood added bug An issue describing something that isn't working, or a PR that fixes a bug cli Related to the command-line interface of Ruff or ty labels Nov 2, 2026
@astral-automations-bot

astral-automations-bot Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

ruff-ecosystem results

Linter (stable)

βœ… ecosystem check detected no linter changes.

Linter (preview)

βœ… ecosystem check detected no linter changes.

Linter (stable) Β· Linter (preview)


Results for 28be99e Β· Workflow run

@AlexWaygood
AlexWaygood added this pull request to stack #29901 November 2, 2026 10:54
@AlexWaygood
AlexWaygood marked this pull request as ready for review November 2, 2026 13:29
Base automatically changed from alex/cli-color-environment to main November 2, 2026 14:30
@AlexWaygood
AlexWaygood requested review from a team as code owners November 2, 2026 14:30
@AlexWaygood
AlexWaygood force-pushed the alex/ruff-check-output-color branch from 779a511 to 28be99e Compare November 2, 2026 14:30
@AlexWaygood
AlexWaygood merged commit 399c34b into main Nov 2, 2026
54 of 55 checks passed
@AlexWaygood
AlexWaygood deleted the alex/ruff-check-output-color branch November 2, 2026 14:38
@MichaReiser

MichaReiser commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

I'm not sure I agree with this change. What's the motivation to force color in --output-file? Color is only supposed to control color when writing to the terminal output, which is true for > but not when using --output-file

This also makes ruff and ty inconsistent with uv

@AlexWaygood

Copy link
Copy Markdown
Member Author

I assumed --color=always was intended to always enable color. But this is a theoretical issue that I don't actually have a use case for; I'm happy to revert this.

@MichaReiser

Copy link
Copy Markdown
Member

I think I'd prefer that. The motivation here isn't clear to me.

@AlexWaygood AlexWaygood added the internal An internal refactor or improvement (not for changelogs) label Nov 2, 2026
@AlexWaygood

Copy link
Copy Markdown
Member Author

Reverting in #29908

This branch was previously deployed

1 inactive deployment
automations β€” 28be99e7 Deployed Nov 2, 2026 by AlexWaygood via security-review / security review #96570
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug An issue describing something that isn't working, or a PR that fixes a bug cli Related to the command-line interface of Ruff or ty internal An internal refactor or improvement (not for changelogs)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants