Skip to content

ruff subcommand misrouting: rule, config, linter, etc. get check --output-format=json injected #2669

Description

@guyoron1

Bug

ruff_cmd.rs uses a blocklist to detect check invocations (lines 35-37):

let is_check = args.is_empty()
    || args[0] == "check"
    || (!args[0].starts_with('-') && args[0] != "format" && args[0] != "version");

Only format and version are excluded. All other ruff subcommands — rule, config, linter, clean, server, analyze, generate-shell-completion — are treated as check invocations and get check --output-format=json prepended.

Reproduction

rtk ruff rule E501
# Actual:  ruff check --output-format=json rule E501  (invalid command, errors out)
# Expected: ruff rule E501

rtk ruff config
# Actual:  ruff check --output-format=json config  (invalid)
# Expected: ruff config

rtk ruff linter
# Actual:  ruff check --output-format=json linter  (invalid)
# Expected: ruff linter

Root Cause

The is_check detection uses a blocklist (only "format" and "version" excluded) instead of an allowlist. Any first argument that doesn't start with - and isn't "format" or "version" is assumed to be a check target path.

Suggested Fix

Add a RUFF_SUBCOMMANDS constant (similar to NPM_SUBCOMMANDS in npm_cmd.rs) listing known ruff subcommands, and exclude them from is_check detection:

const RUFF_SUBCOMMANDS: &[&str] = &[
    "check", "format", "rule", "config", "linter",
    "clean", "server", "analyze", "version",
    "generate-shell-completion",
];

Then is_check becomes: args is empty, OR first arg is "check", OR first arg is not a known subcommand and not a flag (i.e., it's a path).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions