Skip to content

fix(cmds/ruby): accept version-only JSON from rubocop/rspec --version#1982

Open
YOMXXX wants to merge 1 commit into
rtk-ai:developfrom
YOMXXX:fix/rubocop-rspec-version-parse
Open

fix(cmds/ruby): accept version-only JSON from rubocop/rspec --version#1982
YOMXXX wants to merge 1 commit into
rtk-ai:developfrom
YOMXXX:fix/rubocop-rspec-version-parse

Conversation

@YOMXXX
Copy link
Copy Markdown
Contributor

@YOMXXX YOMXXX commented May 20, 2026

Summary

Fixes #1946. rtk rubocop --version and rtk rspec --version were polluting
stdout with two redundant warnings:

[rtk] rubocop: JSON parse failed (missing field `files` at line 1 column 20)
[rtk] rubocop (JSON parse error): output format not recognized, showing last 5 lines
{"version":"1.86.2"}

This PR detects the minimal {"version":"..."} JSON shape emitted by
--version queries before attempting the full lint/test report parse and
surfaces it as a clean rubocop 1.86.2 / rspec 3.13.2 line.

Root cause

Both modules inject --format json to get structured output. When the user
runs --version, the tool emits {"version":"..."} instead of a full report.
The strongly-typed struct (RubocopOutput { files, summary } /
RspecOutput { examples, summary }) rejects it, the JSON parse error is
logged, and fallback_tail adds a second "output format not recognized"
warning before printing the raw line.

Fix

In filter_rubocop_json and filter_rspec_output, run a lightweight
detector first:

  • Parse as serde_json::Value.
  • Verify it's an object with a string version key.
  • Bail out if any report-specific key is present (files/summary/metadata
    for rubocop, examples/summary/summary_line for rspec) — that means
    it's a real report, not a --version query.
  • Otherwise return <tool> <version> cleanly with no warnings.

Real reports that happen to carry a version field (which RSpec's JSON
formatter does) still flow through the existing report parser; covered by
regression tests.

Test plan

  • cargo fmt --all
  • cargo clippy --all-targets (zero warnings)
  • cargo test --bin rtk — 1909 passed, 0 failed
  • New tests (8 total, 4 per module):
    • test_filter_rubocop_version_only_json_clean
    • test_filter_rubocop_version_only_json_with_whitespace
    • test_filter_rubocop_version_only_does_not_swallow_real_report
    • test_try_version_only_json_rejects_non_object
    • test_filter_rspec_version_only_json_clean
    • test_filter_rspec_version_only_json_with_whitespace
    • test_filter_rspec_version_only_does_not_swallow_real_report
    • test_try_version_only_json_rspec_rejects_non_object

Files changed

  • src/cmds/ruby/rubocop_cmd.rs — add try_version_only_json(), call it before report parse, add 4 tests
  • src/cmds/ruby/rspec_cmd.rs — same shape, 4 tests

Fixes #1946

Root cause: `rubocop --version` and `rspec --version` emit minimal JSON
like `{"version":"1.86.2"}` which doesn't match the lint/test report
struct (missing `files` / `examples`). The full-struct parser fails,
triggers `[rtk] ...: JSON parse failed (...)` plus a second "output
format not recognized, showing last 5 lines" warning, polluting stdout
with noise for what is otherwise a clean version query.

Fix: detect version-only JSON shape (`{"version":"..."}` with no
report-specific keys) before attempting the full-struct parse. When
matched, emit a clean `rubocop X.Y.Z` / `rspec X.Y.Z` line, suppress
the warnings, and exit 0. Real reports that happen to include a
`version` field still go through the report parser (regression-guarded).

Tests:
- version-only JSON returns clean line, no warning markers
- whitespace-tolerant detection
- regression: real report with `version` still parses normally
- non-object / malformed JSON rejected by detector (falls through)

Fixes rtk-ai#1946
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rubocop/rspec --version parser rejects pure version JSON

1 participant