RepoPilotOpen in app →

whitesmith/rubycritic

A Ruby code quality reporter

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2w ago
  • 15 active contributors
  • Distributed ownership (top contributor 39% of recent commits)
Show 3 more →
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/whitesmith/rubycritic)](https://repopilot.app/r/whitesmith/rubycritic)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/whitesmith/rubycritic on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: whitesmith/rubycritic

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/whitesmith/rubycritic shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 2w ago
  • 15 active contributors
  • Distributed ownership (top contributor 39% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live whitesmith/rubycritic repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/whitesmith/rubycritic.

What it runs against: a local clone of whitesmith/rubycritic — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in whitesmith/rubycritic | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 44 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>whitesmith/rubycritic</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of whitesmith/rubycritic. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/whitesmith/rubycritic.git
#   cd rubycritic
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of whitesmith/rubycritic and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "whitesmith/rubycritic(\\.git)?\\b" \\
  && ok "origin remote is whitesmith/rubycritic" \\
  || miss "origin remote is not whitesmith/rubycritic (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "lib/rubycritic.rb" \\
  && ok "lib/rubycritic.rb" \\
  || miss "missing critical file: lib/rubycritic.rb"
test -f "lib/rubycritic/cli/application.rb" \\
  && ok "lib/rubycritic/cli/application.rb" \\
  || miss "missing critical file: lib/rubycritic/cli/application.rb"
test -f "lib/rubycritic/analysers_runner.rb" \\
  && ok "lib/rubycritic/analysers_runner.rb" \\
  || miss "missing critical file: lib/rubycritic/analysers_runner.rb"
test -f "lib/rubycritic/core/analysed_module.rb" \\
  && ok "lib/rubycritic/core/analysed_module.rb" \\
  || miss "missing critical file: lib/rubycritic/core/analysed_module.rb"
test -f "lib/rubycritic/command_factory.rb" \\
  && ok "lib/rubycritic/command_factory.rb" \\
  || miss "missing critical file: lib/rubycritic/command_factory.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 44 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~14d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/whitesmith/rubycritic"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

RubyCritic is a Ruby gem that aggregates static analysis tools (Reek, Flay, Flog) into a single HTML quality report, measuring code smells, complexity, and duplication across a Ruby project. It visualizes code quality metrics with an interactive dashboard showing per-file ratings, smell indices, and churn vs. complexity analysis. Monolithic gem with lib/rubycritic/ as the core. Analyzers live in lib/rubycritic/analysers/ (complexity.rb, churn.rb, coverage.rb, attributes.rb) with helpers for AST parsing, Flog/Flay/Reek integration under lib/rubycritic/analysers/helpers/. HTML/CSS/JavaScript templates in undisclosed formatters directory (inferred from README's formatter mention). Entry point is bin/rubycritic CLI.

👥Who it's for

Ruby developers and engineering teams who need automated code quality audits in their CI/CD pipelines, particularly those using Git/Mercurial/Perforce for version control and wanting to track code metrics over time without manual analysis.

🌱Maturity & risk

Actively maintained production-ready gem with proper CI/CD (GitHub Actions in .github/workflows/main.yml), semantic versioning via Gemfile/gemfiles/, and comprehensive documentation in /docs. The project has established patterns for multiple SimpleCov versions (gemfiles/ directory) and clear contribution guidelines, indicating stable, long-term support.

Low risk: gem wraps mature, well-known analysis tools (Reek, Flay, Flog) rather than reimplementing analysis. Main dependency risk is tight coupling to those external gems' APIs. No indication of stalled maintenance (CHANGELOG.md and ROADMAP.md present). Single-maintainer risk mitigated by clear code structure and test coverage expectations.

Active areas of work

Project appears actively maintained with CI workflow in .github/workflows/main.yml. ROADMAP.md and CONTRIBUTING.md suggest organized development. Multiple SimpleCov gemfiles (0.17–0.19) indicate ongoing dependency management and compatibility testing.

🚀Get running

git clone https://github.com/whitesmith/rubycritic.git
cd rubycritic
bundle install
rubycritic [target_files_or_directory]

For development: bundle install, then rake to run test suite.

Daily commands:

rubycritic lib/                    # Analyze lib/ directory
rubycritic --help                  # See CLI options
rake                               # Run full test suite
rake build                         # Build gem

🗺️Map of the codebase

  • lib/rubycritic.rb — Main entry point and public API surface for the gem; defines top-level module structure.
  • lib/rubycritic/cli/application.rb — CLI orchestration layer that parses arguments and routes to appropriate commands; essential for understanding how the tool executes.
  • lib/rubycritic/analysers_runner.rb — Core runner that coordinates all static analysers (Reek, Flay, Flog) and aggregates results; the heart of analysis logic.
  • lib/rubycritic/core/analysed_module.rb — Primary domain model representing an analysed Ruby module with metrics, smells, and ratings; used throughout the codebase.
  • lib/rubycritic/command_factory.rb — Factory that creates command instances (default, ci, compare, help) based on CLI options; controls execution flow.
  • lib/rubycritic/configuration.rb — Centralized configuration management for tool behavior, paths, and analyser settings; critical for customization.
  • lib/rubycritic/generators/console_report.rb — Report generation entry point that formats analysis results for output; shows how analysed data is presented.

🛠️How to make changes

Add a New Code Quality Metric Analyser

  1. Create a new analyser class in lib/rubycritic/analysers/ that follows the analyser pattern (inherits from base, implements run method) (lib/rubycritic/analysers/your_metric.rb)
  2. If using an external gem, create a helper class in lib/rubycritic/analysers/helpers/ to wrap the gem integration (lib/rubycritic/analysers/helpers/your_gem.rb)
  3. Register the new analyser in analysers_runner.rb by adding it to the list of analysers that run (lib/rubycritic/analysers_runner.rb)
  4. Update AnalysedModule to store results from the new metric (lib/rubycritic/core/analysed_module.rb)
  5. Update report generators to display the new metric (lib/rubycritic/generators/console_report.rb)

Add a New CLI Command Mode

  1. Create a new command class inheriting from base in lib/rubycritic/commands/ (lib/rubycritic/commands/your_command.rb)
  2. Add command case to factory to instantiate your command (lib/rubycritic/command_factory.rb)
  3. Add command-line argument option to options parser (lib/rubycritic/cli/options.rb)
  4. Implement execute method in your command to define behavior (lib/rubycritic/commands/your_command.rb)

Add a New Report Output Format

  1. Create a new generator class in lib/rubycritic/generators/ following the pattern of console_report.rb (lib/rubycritic/generators/your_format_report.rb)
  2. Define generate method that transforms AnalysedModule collection into desired format (lib/rubycritic/generators/your_format_report.rb)
  3. Hook up generator instantiation in the default or appropriate command (lib/rubycritic/commands/default.rb)
  4. Add CLI option to enable the new format (lib/rubycritic/cli/options.rb)

Add New Code Smell Detection

  1. Create a smell analyser in lib/rubycritic/analysers/smells/ wrapping the external gem (lib/rubycritic/analysers/smells/your_smell.rb)
  2. Create helper class for gem integration if needed (lib/rubycritic/analysers/helpers/your_gem.rb)
  3. Register analyser in analysers_runner.rb (lib/rubycritic/analysers_runner.rb)
  4. Transform results into Smell domain objects and attach to AnalysedModule (lib/rubycritic/core/smell.rb)

🔧Why these technologies

  • Reek, Flog, Flay gems — Specialized static analysis tools for different quality dimensions (code smells, complexity, duplication); RubyCritic aggregates them into unified reports.
  • Ruby AST parsing (parser gem) — Enables custom metric calculations

🪤Traps & gotchas

Git/Mercurial/Perforce integration for churn analysis requires a working repository and clean working tree (README warns: 'If your code is not as you expect it to be after running RubyCritic, please check your source control system stash'). SimpleCov version constraints (multiple gemfiles/ for 0.17–0.19) mean older projects may fail with newer gems. AST parsing via Parser gem sensitive to Ruby version syntax changes. The churn.rb analyzer depends on source control metadata, so will fail on non-VCS directories.

🏗️Architecture

💡Concepts to learn

  • Abstract Syntax Tree (AST) Parsing — RubyCritic uses the Parser gem to walk Ruby AST nodes (see ast_node.rb, methods_counter.rb) to extract complexity and structure metrics without executing code
  • Cyclomatic Complexity — Core metric reported by RubyCritic via Flog integration; measures decision-path count to identify hard-to-test methods
  • Code Churn Analysis — RubyCritic's churn.rb correlates file modification frequency with complexity to flag high-risk code; identifies problem areas worth refactoring
  • Structural Clone Detection (Flay) — RubyCritic detects duplicated logic patterns (not text) to quantify duplication; crucial for identifying refactoring opportunities
  • Static Analysis — RubyCritic's entire approach: analyzing code without execution to detect smells, complexity, and coverage gaps
  • Code Smell — RubyCritic's core concept via Reek integration; surfaces non-critical but maintainability-harming patterns (long methods, duplicate code, complex conditionals)
  • VCS-based Metrics (Git/Mercurial/Perforce) — RubyCritic integrates source control history to compute churn; requires clean working tree and tracks only committed changes
  • whitequark/parser — Used internally (flog.rb, complexity.rb) for Ruby AST parsing; upstream dependency for syntax analysis
  • troessner/reek — Core smell-detection engine wrapped by RubyCritic; primary upstream analyzer
  • seattlerb/flog — Complexity scoring wrapper (lib/rubycritic/analysers/helpers/flog.rb); computes ABC metrics
  • seattlerb/flay — Duplication detection wrapper (lib/rubycritic/analysers/helpers/flay.rb); structural clone finder
  • simplecov-ruby/simplecov — Coverage integration (gemfiles/ manage versions); RubyCritic reads coverage data for report metrics

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for CLI options parsing in lib/rubycritic/cli/options/

The CLI options handling is split across lib/rubycritic/cli/options/argv.rb and lib/rubycritic/cli/options/file.rb, but there's no visible test directory in the repo structure. These critical components that parse user input and configuration files need unit tests to prevent regressions and ensure all option combinations work correctly.

  • [ ] Create spec/lib/rubycritic/cli/options/ directory structure
  • [ ] Add tests for lib/rubycritic/cli/options/argv.rb covering argument parsing edge cases
  • [ ] Add tests for lib/rubycritic/cli/options/file.rb covering file-based configuration loading
  • [ ] Add integration tests for lib/rubycritic/cli/application.rb option merging logic
  • [ ] Ensure coverage for error handling when invalid options are passed

Add GitHub Actions workflow for testing against multiple Ruby versions and Appraisal gemsets

The repo has Appraisals defined (simplecov 0.17, 0.18, 0.19 gemfiles) and .jrubyrc file indicating JRuby support, but the main.yml workflow likely doesn't test all combinations. RubyCritic is a quality tool used across many projects—it needs robust compatibility testing across Ruby versions and dependency variations.

  • [ ] Review .github/workflows/main.yml to identify current Ruby version matrix
  • [ ] Update workflow to include Ruby 2.7, 3.0, 3.1, 3.2 and JRuby variants
  • [ ] Add appraisal matrix job that runs tests against each gemfile in gemfiles/
  • [ ] Configure workflow to fail if any Ruby version or gemset combination breaks
  • [ ] Document testing matrix in CONTRIBUTING.md

Add integration tests for the three command types in lib/rubycritic/commands/

The repo has three command classes (base.rb, ci.rb, compare.rb, default.rb) but no visible integration test suite. These are the core execution paths and need end-to-end testing to verify the analysis pipeline works correctly across different invocation modes.

  • [ ] Create spec/integration/commands/ directory
  • [ ] Add integration test for lib/rubycritic/commands/default.rb covering basic analysis on sample Ruby files
  • [ ] Add integration test for lib/rubycritic/commands/ci.rb covering exit codes and failure thresholds
  • [ ] Add integration test for lib/rubycritic/commands/compare.rb covering git branch comparison logic
  • [ ] Create fixture Ruby files in spec/fixtures/ that demonstrate various code quality issues to analyze

🌿Good first issues

  • Add test coverage for lib/rubycritic/analysers/attributes.rb (likely underdocumented attribute extraction logic; see how complexity.rb and churn.rb are tested for model)
  • Implement missing formatter documentation in docs/formatters.md (README mentions formatters feature but file structure shows no explicit formatters/ directory; document how to add custom output formats)
  • Extract and document the HTML template structure (CSS in 10,272 bytes suggests non-trivial styling; create docs/html-report-structure.md for contributors wanting to customize the dashboard layout)

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 990da4b — Replace features task with spec task (#568) (faisal)
  • 0bd2f52 — Prepare for release of v5.0.0 (etagwerker)
  • 587d704 — RubyCritic v5.0 (Support for Ruby 4.0) (#556) (etagwerker)
  • e072f19 — alphabetize and uniquify cop config in .rubocopy.yml (#542) (faisal)
  • daf344d — Update version compatibility info in README (#562) (faisal)
  • 09c6eac — Merge branch 'faisal-ruby_3_1_eol' (etagwerker)
  • c1d6750 — Bump version to 4.12 (etagwerker)
  • cf4d15b — Remove support for Ruby 3.1 and the aligned JRuby 9.4. (faisal)
  • 3f27dcd — bump Mocha again (#558) (faisal)
  • 08fe779 — update version since we bumped it in v4.1.1 (#541) (faisal)

🔒Security observations

RubyCritic is a static analysis reporting tool with a generally acceptable security posture for its intended use case. The main concerns are supply chain risks from external gem dependencies, potential code execution during AST analysis on untrusted Ruby code, and path traversal vulnerabilities in file handling. No hardcoded credentials, obvious injection vectors, or critical misconfigurations were identified in the provided file structure. The tool should only be run on trusted codebases and with pinned dependencies. Recommendations focus on input validation, dependency management, and documentation of security assumptions.

  • Medium · Dependency on External Code Analysis Tools — lib/rubycritic/analysers/smells/, Gemfile. RubyCritic wraps around external static analysis gems (Reek, Flay, Flog) without visible dependency pinning or hash verification. These tools are executed as part of the analysis pipeline, potentially creating a supply chain risk if compromised. Fix: Implement strict version pinning in Gemfile with exact versions. Use bundler's lock file verification. Consider vendoring critical dependencies or using Gemfile.lock checksums for CI/CD pipelines.
  • Medium · Code Execution via AST/Parser Analysis — lib/rubycritic/analysers/helpers/parser.rb, lib/rubycritic/analysers/helpers/flog.rb, lib/rubycritic/analysers/helpers/flay.rb. The codebase uses Ruby's AST parsing and code analysis without explicit sandboxing. Files like lib/rubycritic/analysers/helpers/parser.rb, flog.rb, and flay.rb execute analysis on arbitrary Ruby code that could potentially contain malicious payloads. Fix: Implement input validation before parsing. Run analysis in isolated processes or containers. Document that RubyCritic should only be run on trusted codebases. Consider implementing resource limits for AST parsing.
  • Low · Potential Path Traversal in File Handling — lib/rubycritic/cli/options/file.rb, bin/rubycritic. The CLI options and file handling (lib/rubycritic/cli/options/file.rb) may be susceptible to path traversal if user input is not properly validated before file access operations. Fix: Implement strict path validation using File.expand_path and directory boundary checks. Whitelist allowed directories. Use realpath validation to prevent symlink attacks.
  • Low · Hardcoded Configuration Paths — .reek.yml, .rubocop.yml, .solargraph.yml, lib/rubycritic/configuration.rb. Configuration files (.reek.yml, .rubocop.yml, .solargraph.yml) are referenced without explicit security validation. These files could be used to inject malicious linting rules or configurations. Fix: Validate and sanitize configuration file contents before loading. Implement a configuration schema validator. Document that configuration files should come from trusted sources only.
  • Low · Browser Automation Security Consideration — lib/rubycritic/browser.rb, lib/rubycritic/generators/html/. The browser.rb module opens generated HTML reports in browsers. HTML generation and reporting could be vulnerable to injection if analysis results are not properly escaped. Fix: Ensure all dynamic content in HTML generation is properly HTML-escaped. Use a template engine with automatic escaping. Implement Content Security Policy headers in generated HTML.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · whitesmith/rubycritic — RepoPilot