Skip to content

feat(ruby): add Ruby on Rails command support#643

Closed
Maimer wants to merge 5 commits intortk-ai:developfrom
Maimer:pim_feat_ruby-rails-support
Closed

feat(ruby): add Ruby on Rails command support#643
Maimer wants to merge 5 commits intortk-ai:developfrom
Maimer:pim_feat_ruby-rails-support

Conversation

@Maimer
Copy link

@Maimer Maimer commented Mar 16, 2026

feat(ruby): add Ruby on Rails command support

Summary

Add comprehensive Ruby on Rails support to rtk with 3 new command modules, 1 TOML filter, shared utilities, and automatic discover/rewrite rules.

New Commands

Command Module Strategy Token Savings
rtk rake test rake_cmd.rs State machine text parser (Minitest) 85-90%
rtk rspec rspec_cmd.rs JSON parsing with text fallback 60%+
rtk rubocop rubocop_cmd.rs JSON parsing, group by cop/severity 60%+
rtk bundle install bundle-install.toml TOML filter (strip Using lines) 70%

Discover/Rewrite Rules

All common Ruby invocation patterns are automatically rewritten by the Claude Code hook:

rake test              → rtk rake test
bundle exec rake test  → rtk rake test
rails test             → rtk rake test
bin/rails test         → rtk rake test
bundle exec rspec      → rtk rspec
bundle exec rubocop    → rtk rubocop
bundle install         → rtk bundle install
bundle update          → rtk bundle update

ENV_PREFIX auto-strips RAILS_ENV, WITH_COVERAGE, BUNDLE_GEMFILE and re-prepends to the rewritten command (e.g. WITH_COVERAGE=true bundle exec rake testWITH_COVERAGE=true rtk rake test).

Shared Infrastructure

  • ruby_exec(tool) in utils.rs: Auto-detects bundle exec when Gemfile exists in working directory. Handles transitive dependencies correctly (e.g. rake pulled in via rails not listed directly in Gemfile).
  • fallback_tail(output, n): Returns last N lines on parse failure (graceful degradation).
  • exit_code_from_output(output): Unix signal handling for child process exit codes.
  • count_tokens(text): Test utility for token savings verification.

Minitest Parser Details (rake_cmd.rs)

State machine with 4 states: Header → Running → Failures → Summary

  • Handles both standard Minitest format (# Running:, N runs) and minitest-reporters format (Started with run options, N tests)
  • All pass → one-line summary: "ok rake test: 8 runs, 0 failures"
  • Failures → summary line + numbered failure blocks with test name, file:line, assertion message
  • Graceful fallback to raw output on parse failure

Testing

  • 108 new tests across rake_cmd (11), rspec_cmd (97+), rubocop_cmd tests
  • 4 inline TOML tests for bundle-install filter
  • Token savings verified ≥60% for all filters
  • All 989 tests passing (cargo test)

Documentation

  • README.md: Added Ruby commands to savings table, usage examples, and hook rewrite table
  • CHANGELOG.md: Added Unreleased section with all Ruby features
  • ARCHITECTURE.md: Added Ruby module table entry and full Ruby Module Architecture section
  • CLAUDE.md: Updated module responsibilities and fork-specific features

Commits

  1. feat(ruby): add RSpec and RuboCop filters with shared Ruby utilities — rspec_cmd.rs, rubocop_cmd.rs, utils.rs additions, test-ruby.sh
  2. feat(ruby): add minitest filter for rake/rails test — rake_cmd.rs with state machine parser
  3. feat(ruby): register rake/rspec/rubocop commands and rewrite rules — main.rs routing, discover/rules.rs patterns
  4. feat(ruby): add TOML filter for bundle install/update — bundle-install.toml, filter count update
  5. docs(ruby): update documentation — README, CHANGELOG, ARCHITECTURE, CLAUDE.md

Test Plan

  • cargo fmt --all --check passes (our files)
  • cargo clippy --all-targets passes (no new warnings)
  • cargo test — 989 tests pass, 3 ignored
  • Token savings ≥60% verified for all new filters
  • Manual testing with real Ruby/Rails projects (rake test, rspec, rubocop, bundle install)
  • Minitest parser handles both standard and minitest-reporters formats
  • Discover/rewrite rules correctly handle all invocation patterns including bin/rails and env var prefixes
  • DCO sign-off on all commits

🤖 Generated with Claude Code

@navidemad
Copy link

There is 3 PR on rails 🤣

@Maimer Maimer force-pushed the pim_feat_ruby-rails-support branch from 0991f09 to d78401b Compare March 18, 2026 14:40
@Maimer
Copy link
Author

Maimer commented Mar 18, 2026

There is 3 PR on rails 🤣

I had looked at the others but it seemed they had stalled. The changes from #292 where ported in commit 639b06d in this PR. I believe that this PR is the most extensive of the 3 and includes everything those other 2 and more, but can wait until the other PRs get merged before opening mine if that is preferred. We want to use this tool more widely at my org, but we are mostly using Ruby / Rails, so this is important to us. Just let me know what works best for you. Thanks for making the tool!

Maimer and others added 5 commits March 18, 2026 13:46
Port upstream PR rtk-ai#292 (rtk-ai/rtk feat/ruby-rails-support):
- rspec_cmd.rs: RSpec JSON filter with text fallback (~1000 lines, 97 tests)
- rubocop_cmd.rs: RuboCop JSON filter grouped by cop/severity (~660 lines)
- utils.rs: ruby_exec(), fallback_tail(), exit_code_from_output(), count_tokens()
  ruby_exec() uses bundle exec whenever Gemfile exists (transitive deps
  like rake aren't declared in Gemfile but still need bundler)
- E2E smoke test script (scripts/test-ruby.sh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Nicholas Lee <nicholas.lee@appfolio.com>
State machine parser for Minitest output (rake test / rails test):
- Parses both standard Minitest and minitest-reporters formats
- Handles "# Running:" and "Started with run options" headers
- Summary matches both "N runs" and "N tests" keywords
- All-pass: "ok rake test: N runs, 0 failures"
- Failures: summary + numbered failure details (limit 10, truncated)
- Handles ANSI codes, skipped tests, errors
- 80%+ token savings on typical test runs (11 tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Nicholas Lee <nicholas.lee@appfolio.com>
src/main.rs:
- Add mod rake_cmd, rspec_cmd, rubocop_cmd
- Add Commands::Rake, Rspec, Rubocop variants with trailing_var_arg
- Route to respective run() functions
- Add to is_operational_command list

src/discover/rules.rs:
- bundle install/update pattern + rule (TOML, 70% savings)
- rake/rails test pattern + rule (85% savings, handles bin/rails)
- rspec pattern + rule (65% savings, handles bundle exec)
- rubocop pattern + rule (65% savings, handles bundle exec)

Rewrite examples:
  rake test -> rtk rake test
  bundle exec rake test -> rtk rake test
  WITH_COVERAGE=true bundle exec rake test -> WITH_COVERAGE=true rtk rake test
  bundle exec rspec -> rtk rspec
  bundle exec rubocop -> rtk rubocop
  bundle install -> rtk bundle install

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Nicholas Lee <nicholas.lee@appfolio.com>
- bundle-install.toml: strips 'Using' lines, gem metadata, blank lines
- Short-circuits to "ok bundle: complete/updated" on success
- 4 inline tests: all-cached, mixed install, update, empty
- Update builtin filter count (47 -> 48)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Nicholas Lee <nicholas.lee@appfolio.com>
- Add rake_cmd.rs, rspec_cmd.rs, rubocop_cmd.rs to module responsibilities
- Add ruby_exec to utils.rs description
- Add Ruby on Rails Support section to fork-specific features

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Nicholas Lee <nicholas.lee@appfolio.com>
@Maimer Maimer force-pushed the pim_feat_ruby-rails-support branch from d78401b to a22df4f Compare March 18, 2026 20:55
@Maimer
Copy link
Author

Maimer commented Mar 18, 2026

@navidemad do you feel your PRs cover everything here? Is there a way we can combine everything together?

navidemad added a commit to navidemad/rtk that referenced this pull request Mar 19, 2026
Unifies 5 competing PRs (rtk-ai#198, rtk-ai#292, rtk-ai#379, rtk-ai#534, rtk-ai#643) into a single
coherent implementation.

New commands:
- rtk rspec: JSON parsing with text fallback (60%+ savings)
- rtk rubocop: JSON parsing, group by cop/severity (60%+ savings)
- rtk rake test: Minitest state machine parser (85-90% savings)
- rtk bundle install: TOML filter, strip Using lines (90%+ savings)

Shared infrastructure: ruby_exec(), fallback_tail(),
exit_code_from_output(), count_tokens() in utils.rs.

Discover/rewrite rules for rspec, rubocop, rake, rails, bundle
including bundle exec and bin/ variants.

56 new unit tests + 4 inline TOML tests. All 1035 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
navidemad added a commit to navidemad/rtk that referenced this pull request Mar 19, 2026
Unifies 5 competing PRs (rtk-ai#198, rtk-ai#292, rtk-ai#379, rtk-ai#534, rtk-ai#643) into a single
coherent implementation.

New commands:
- rtk rspec: JSON parsing with text fallback (60%+ savings)
- rtk rubocop: JSON parsing, group by cop/severity (60%+ savings)
- rtk rake test: Minitest state machine parser (85-90% savings)
- rtk bundle install: TOML filter, strip Using lines (90%+ savings)

Shared infrastructure: ruby_exec(), fallback_tail(),
exit_code_from_output(), count_tokens() in utils.rs.

Discover/rewrite rules for rspec, rubocop, rake, rails, bundle
including bundle exec and bin/ variants.

E2E smoke tests (scripts/test-ruby.sh) covering all 4 commands.
56 new unit tests + 4 inline TOML tests. All 1035 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Navid EMAD <navid.emad@yespark.fr>
@navidemad
Copy link

@Maimer — to answer your question: yes, I combined everything! See the unified PR at #724 which merges all 5 Ruby PRs (#198, #292, #379, #534, #643).

Your PR was the preferred base when approaches conflicted, and contributed several unique pieces: rake_cmd.rs (only Minitest implementation), the most comprehensive discover rules, and bundle-install.toml.

The full attribution table is in the PR description.

navidemad added a commit to navidemad/rtk that referenced this pull request Mar 19, 2026
Integrate ARCHITECTURE.md Ruby Module Architecture section and CLAUDE.md
module table/fork-features from PR rtk-ai#643. Update PR description attribution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Navid EMAD <navid.emad@yespark.fr>
pszymkowiak pushed a commit that referenced this pull request Mar 19, 2026
…724)

* feat(ruby): add Ruby on Rails support (rspec, rubocop, rake, bundle)

Unifies 5 competing PRs (#198, #292, #379, #534, #643) into a single
coherent implementation.

New commands:
- rtk rspec: JSON parsing with text fallback (60%+ savings)
- rtk rubocop: JSON parsing, group by cop/severity (60%+ savings)
- rtk rake test: Minitest state machine parser (85-90% savings)
- rtk bundle install: TOML filter, strip Using lines (90%+ savings)

Shared infrastructure: ruby_exec(), fallback_tail(),
exit_code_from_output(), count_tokens() in utils.rs.

Discover/rewrite rules for rspec, rubocop, rake, rails, bundle
including bundle exec and bin/ variants.

E2E smoke tests (scripts/test-ruby.sh) covering all 4 commands.
56 new unit tests + 4 inline TOML tests. All 1035 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Navid EMAD <navid.emad@yespark.fr>

* fix(ruby): use TEST= env var for rake single-file test in smoke tests

Rails' `rake test` ignores positional file args; use `TEST=path` syntax.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Navid EMAD <navid.emad@yespark.fr>

* docs(ruby): add Ruby module architecture and update attribution

Integrate ARCHITECTURE.md Ruby Module Architecture section and CLAUDE.md
module table/fork-features from PR #643. Update PR description attribution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Navid EMAD <navid.emad@yespark.fr>

* chore: remove PULL_REQUEST_DESCRIPTION.md from repo

PR description lives on GitHub, no need to track in the codebase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Navid EMAD <navid.emad@yespark.fr>

---------

Signed-off-by: Navid EMAD <navid.emad@yespark.fr>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Maimer
Copy link
Author

Maimer commented Mar 19, 2026

Thanks @navidemad @pszymkowiak. Closing due to changes being merged in PR: #724

@Maimer Maimer closed this Mar 19, 2026
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.

2 participants