CrackedRuby CrackedRuby

Overview

Linting examines source code for programmatic and stylistic errors without executing the program. Formatters automatically restructure code to match style guidelines. These tools operate on the abstract syntax tree (AST) or token stream of source code, identifying patterns that violate defined rules and optionally modifying the code to fix violations.

The distinction matters: linters detect issues across multiple categories including logic errors, code smells, style violations, and potential bugs. Formatters focus exclusively on whitespace, indentation, line breaks, and other aesthetic concerns. A linter might flag an unused variable or warn about a method with too many parameters. A formatter ensures consistent spacing around operators and proper indentation depth.

Ruby's dynamic nature makes static analysis challenging yet valuable. The language permits runtime code modification, method definitions inside conditional blocks, and extensive metaprogramming. Linters compensate for the absence of compile-time checks that statically-typed languages provide, catching errors that would otherwise surface only during execution or testing.

The practice gained prominence as codebases grew and teams expanded. Manual code review could not scale to verify style consistency across thousands of files. Automated tools eliminated subjective style debates, reduced review cycle times, and caught mechanical errors before human reviewers saw the code. What began as simple style checkers evolved into sophisticated analysis engines examining security vulnerabilities, performance issues, and architectural violations.

# Before linting/formatting
def calculate(x,y)
  if x>0
      result=x*y
    return result
  end
end

# After linting/formatting
def calculate(x, y)
  return unless x.positive?

  x * y
end

Key Principles

Automated Enforcement

Manual style enforcement fails with team size and codebase growth. Humans miss inconsistencies during review, apply rules subjectively, and waste cognitive resources on formatting minutiae. Automated tools examine every line deterministically, applying identical standards across the entire codebase. The automation removes human judgment from style decisions, converting preferences into enforceable policies.

Separation of Concerns

Linting and formatting address distinct problems requiring different approaches. Linting rules carry semantic meaning: a method with excessive cyclomatic complexity indicates genuine design problems. A missing space after a comma carries no semantic weight. This distinction affects how teams adopt and configure tools. Formatting changes apply automatically without manual review. Linting violations require human judgment to address properly.

Configuration as Code

Linting configurations live in version-controlled files alongside source code. Teams track changes to rule sets, review modifications to style policies, and maintain different configurations for different projects or modules. The configuration defines the team's coding standards explicitly, eliminating ambiguity about style expectations. Developers clone a repository and inherit the project's linting rules automatically.

Progressive Adoption

Existing codebases cannot adopt strict linting rules instantly. A project with 100,000 lines of code might have 10,000 violations of a new rule set. Fixing all violations before enabling the linter blocks all other work. Progressive adoption allows teams to enable linting for new code, fix violations incrementally, and maintain momentum on feature development. Baseline files record existing violations, preventing new violations without requiring immediate fixes for legacy code.

Rule Categories

Linting rules group into categories by purpose and severity. Layout rules enforce visual consistency. Style rules promote idiomatic code. Metrics rules prevent complexity accumulation. Lint rules catch probable bugs. Security rules identify vulnerabilities. Each category requires different handling. Teams might auto-fix layout violations, review style violations during pull requests, and block merges on security violations.

Fast Feedback Loops

Effective linting provides immediate feedback during development. Developers see violations as they type, not hours later during CI checks. Editor integration shows squiggly underlines beneath violations. Save-on-format automatically corrects whitespace issues. Pre-commit hooks block commits containing violations. CI builds fail when violations reach the main branch. Each layer catches violations progressively earlier, reducing the cost of fixing them.

Tools & Ecosystem

RuboCop

RuboCop combines linting and formatting in a single extensible tool. The analyzer parses Ruby code into an AST, traverses nodes looking for pattern matches, and reports or corrects violations. The tool ships with hundreds of built-in cops (rule implementations) organized into departments: Layout, Style, Metrics, Lint, Performance, Security, and others.

Each cop examines specific patterns. The Style/StringLiterals cop verifies quote style consistency. The Metrics/CyclomaticComplexity cop calculates branching complexity. The Lint/UnusedMethodArgument cop identifies parameters that never appear in the method body. The Security/Eval cop flags dynamic code evaluation that might execute untrusted input.

RuboCop's extensibility allows custom cops for project-specific rules. Teams write cops to enforce architectural boundaries, naming conventions, or framework usage patterns. The plugin architecture supports third-party extensions that add domain-specific cops.

StandardRB

StandardRB wraps RuboCop with an opinionated, zero-configuration rule set. The tool eliminates configuration decisions by providing a single, unchangeable style guide. Teams install StandardRB and accept its style choices without debate. The approach trades flexibility for simplicity, removing the cognitive load of choosing and maintaining configurations.

The tool configures RuboCop with specific cop settings, disables configurable options, and provides simplified commands. Developers run a single command that both checks and fixes violations. The reduced surface area makes adoption easier for teams overwhelmed by RuboCop's configuration options.

RuboCop Extensions

The RuboCop ecosystem includes extensions for frameworks and libraries:

  • rubocop-rails adds cops for Rails-specific patterns, checking for proper use of associations, validations, and framework conventions
  • rubocop-rspec provides cops for RSpec test organization, expectation syntax, and spec file structure
  • rubocop-performance identifies performance anti-patterns like inefficient enumeration or excessive object allocation
  • rubocop-thread_safety detects thread-safety violations in concurrent code

Extensions follow RuboCop's plugin architecture. Each extension registers additional cops that activate when the relevant framework or library appears in the project.

Language Servers and Editor Integration

Editor integration transforms linting from batch checking into continuous feedback. The Ruby LSP (Language Server Protocol) implementation includes linting capabilities, providing real-time diagnostics as developers type. Editors display violations with inline messages, severity indicators, and quick-fix actions.

Different integration approaches offer various trade-offs. Direct RuboCop integration in editor plugins runs the full linter on save or on demand. Language server integration runs linting continuously in the background. File watchers trigger linting when files change. Each approach balances responsiveness against computational cost.

Formatters

While RuboCop handles both linting and formatting, specialized formatters focus exclusively on code layout. These tools make opinionated decisions about whitespace, line breaks, and indentation without configurable style options. The formatter reads code, parses it into an AST, and regenerates source code following strict formatting rules.

The single-purpose focus allows formatters to operate faster than full linters. A formatter completes in milliseconds, enabling format-on-save workflows that reformat files automatically. The deterministic output ensures every developer sees identically formatted code regardless of their editing habits.

Ruby Implementation

Installation and Basic Usage

RuboCop installs as a Ruby gem. The typical installation adds RuboCop to the development dependency group:

# Gemfile
group :development do
  gem 'rubocop', require: false
  gem 'rubocop-rails', require: false
  gem 'rubocop-rspec', require: false
end

The command-line interface provides inspection and correction modes:

# Check files for violations
rubocop

# Check specific files or directories
rubocop app/models lib/services

# Auto-correct violations
rubocop -A

# Auto-correct safe violations only
rubocop -a

RuboCop distinguishes between safe and unsafe corrections. Safe corrections never change code semantics: adding spaces, breaking lines, or reordering independent statements. Unsafe corrections might alter behavior: changing string literals from double to single quotes affects interpolation, converting a conditional to a guard clause changes variable scope.

Configuration Files

The .rubocop.yml file controls RuboCop behavior. The YAML structure defines enabled cops, severity levels, and cop-specific parameters:

# .rubocop.yml
AllCops:
  TargetRubyVersion: 3.2
  NewCops: enable
  Exclude:
    - 'vendor/**/*'
    - 'db/schema.rb'
    - 'node_modules/**/*'

Style/StringLiterals:
  Enabled: true
  EnforcedStyle: single_quotes

Metrics/MethodLength:
  Max: 15
  CountComments: false

Layout/LineLength:
  Max: 120
  AllowedPatterns:
    - '^\s*#'  # Ignore comment lines

Configuration inheritance allows sharing standards across projects:

# .rubocop.yml
inherit_from:
  - .rubocop_todo.yml
  - config/rubocop_shared.yml

inherit_gem:
  rubocop-rails: config/rails.yml
  rubocop-rspec: config/rspec.yml

The inherit_from directive loads local configuration files. The inherit_gem directive loads configurations from installed gems. Both mechanisms support multiple inheritance, merging configurations in order.

Inline Configuration

Comments inside Ruby files modify RuboCop behavior for specific lines or blocks:

# Disable a cop for the next line
# rubocop:disable Style/NumericLiterals
API_KEY = 1234567890
# rubocop:enable Style/NumericLiterals

# Disable multiple cops for a block
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
def complex_legacy_method
  # ... hundreds of lines ...
end
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity

# Disable a cop for the current line (inline)
def process(data) # rubocop:disable Metrics/AbcSize
  # method implementation
end

Inline disabling requires justification in code review. Teams establish policies about when disabling is acceptable: legacy code under refactor, generated code, temporary workarounds with follow-up issues.

Custom Cops

Teams create custom cops for project-specific rules. A cop inherits from RuboCop::Cop::Base and implements node pattern matching:

# lib/custom_cops/no_direct_model_access.rb
module CustomCops
  class NoDirectModelAccess < RuboCop::Cop::Base
    MSG = 'Avoid direct model access in controllers. Use a service object.'

    def_node_matcher :model_constant?, <<~PATTERN
      (const nil? {:User :Post :Comment})
    PATTERN

    def on_send(node)
      return unless in_controller?
      return unless model_constant?(node.receiver)

      add_offense(node)
    end

    private

    def in_controller?
      processed_source.file_path.include?('app/controllers')
    end
  end
end

The cop registers with RuboCop through configuration:

# .rubocop.yml
require:
  - ./lib/custom_cops/no_direct_model_access

CustomCops/NoDirectModelAccess:
  Enabled: true

Custom cops access the AST through node matchers, examining code structure rather than text patterns. This approach catches violations regardless of formatting variations.

RuboCop Todo Files

Large codebases with existing violations use todo files to defer fixes:

# Generate a todo file
rubocop --auto-gen-config

# Creates .rubocop_todo.yml
Style/StringLiterals:
  Exclude:
    - 'app/models/user.rb'
    - 'app/models/post.rb'
    # ... hundreds of files ...

Metrics/MethodLength:
  Exclude:
    - 'app/services/complex_calculation.rb'

The todo file becomes part of the main configuration through inheritance. New code follows the rules strictly. Legacy code violations appear in the todo file. Teams chip away at the todo file, removing entries as they fix violations incrementally.

Implementation Approaches

Big Bang Adoption

Big bang adoption enables all desired cops simultaneously, requiring immediate fixes for all violations. This approach works for small codebases, greenfield projects, or teams willing to pause feature development temporarily. The benefit lies in reaching the desired state immediately without carrying technical debt forward.

The strategy requires dedicated time for fixing violations. A team might allocate a sprint to linting adoption, fixing violations in focused work sessions. Alternatively, the team might freeze feature development while addressing violations. The approach fails when violation counts exceed available fixing capacity or when urgent feature work cannot pause.

Gradual Enablement

Gradual enablement activates cops incrementally, allowing teams to maintain feature velocity while improving code quality. The process begins with non-controversial cops: formatting rules that auto-correct safely. Each iteration adds more cops, fixes existing violations, and monitors adoption success.

# Week 1: Layout cops only
AllCops:
  DisabledByDefault: true

Layout:
  Enabled: true

# Week 2: Add safe Style cops
Style/StringLiterals:
  Enabled: true
Style/HashSyntax:
  Enabled: true

# Week 3: Add Lint cops
Lint:
  Enabled: true

The incremental approach reduces cognitive load. Developers learn rules gradually, internalize patterns, and build muscle memory. The small violation counts per iteration make fixing manageable. Teams maintain momentum on business features while improving code quality steadily.

Default Disabled Configuration

Some teams start with all cops disabled, enabling specific cops deliberately:

# .rubocop.yml
AllCops:
  DisabledByDefault: true

# Explicitly enable desired cops
Layout/IndentationWidth:
  Enabled: true
Style/StringLiterals:
  Enabled: true
Lint/UnusedMethodArgument:
  Enabled: true

This inverted approach forces conscious decisions about every rule. Teams evaluate each cop's value, discuss its implications, and enable only cops with broad support. The configuration grows organically as teams encounter patterns they want to enforce.

The downside appears when new RuboCop versions add valuable cops that remain disabled by default. Teams miss improvements unless they actively review new cop additions.

Strict vs Advisory

Teams choose between strict enforcement (build failures) and advisory reporting (warnings without blocking). Strict enforcement prevents violations from entering the codebase. Advisory reporting highlights issues without blocking progress.

Strict enforcement works for formatting rules with auto-correction. Developers run the auto-corrector before committing, and violations never reach the repository. Advisory enforcement suits complex rules requiring human judgment: refactoring large methods or reducing cyclomatic complexity.

Mixed enforcement allows different severity levels per cop:

# .rubocop.yml
Layout/IndentationWidth:
  Severity: error  # Block CI builds

Metrics/MethodLength:
  Severity: warning  # Report but don't block

Metrics/CyclomaticComplexity:
  Severity: info  # Track but don't highlight

Team Configuration Management

Organizations with multiple repositories maintain shared configurations. A central configuration repository provides base settings that project-specific configurations extend:

# shared-configs/.rubocop.yml (in its own repository)
AllCops:
  TargetRubyVersion: 3.2
  NewCops: enable

Style/StringLiterals:
  EnforcedStyle: single_quotes

Metrics/MethodLength:
  Max: 15

# project/.rubocop.yml
inherit_gem:
  shared-configs: .rubocop.yml

# Project-specific overrides
Metrics/MethodLength:
  Max: 20  # Looser for this legacy project

Shared configurations evolve over time. Updates to the central configuration propagate to all projects when they update the shared-configs gem. Projects opt into updates explicitly through dependency management, allowing gradual adoption of stricter rules.

Practical Examples

Rails Application Setup

A typical Rails application configuration balances framework conventions with team preferences:

# .rubocop.yml
require:
  - rubocop-rails
  - rubocop-rspec

AllCops:
  TargetRubyVersion: 3.2
  NewCops: enable
  Exclude:
    - 'bin/**/*'
    - 'db/schema.rb'
    - 'db/migrate/*.rb'
    - 'vendor/**/*'
    - 'node_modules/**/*'

Rails:
  Enabled: true

Style/Documentation:
  Enabled: false  # Many Rails projects skip class documentation

Style/StringLiterals:
  EnforcedStyle: single_quotes
  ConsistentQuotesInMultiline: true

Style/FrozenStringLiteralComment:
  Enabled: true
  EnforcedStyle: always

Metrics/BlockLength:
  Exclude:
    - 'spec/**/*'  # RSpec specs often have long blocks
    - 'config/routes.rb'
    - 'config/environments/*.rb'

Rails/HasManyOrHasOneDependent:
  Enabled: true  # Enforce dependent: option on associations

Rails/UniqueValidationWithoutIndex:
  Enabled: true  # Catch uniqueness validations without database indexes

Monorepo Configuration

Monorepos containing multiple Ruby projects require hierarchical configuration:

# Root .rubocop.yml (applies to entire repo)
AllCops:
  TargetRubyVersion: 3.2
  NewCops: enable

Style/StringLiterals:
  EnforcedStyle: single_quotes

# services/api/.rubocop.yml (inherits from root)
inherit_from:
  - ../../.rubocop.yml

AllCops:
  Exclude:
    - 'tmp/**/*'

Rails:
  Enabled: true

# services/workers/.rubocop.yml (different rules for background jobs)
inherit_from:
  - ../../.rubocop.yml

Metrics/MethodLength:
  Max: 20  # Workers often have longer methods

Metrics/CyclomaticComplexity:
  Max: 8  # More complex logic acceptable in workers

Each subdirectory inherits from the root configuration and overrides specific rules for its context. API services enforce Rails conventions. Worker services allow longer methods for complex background processing logic.

Pre-commit Hook Integration

Git hooks enforce linting before code reaches the repository:

# .git/hooks/pre-commit
#!/usr/bin/env ruby

changed_files = `git diff --cached --name-only --diff-filter=ACM`.
  split("\n").
  select { |file| file.end_with?('.rb') }

exit 0 if changed_files.empty?

system("rubocop #{changed_files.join(' ')}")
exit_status = $?.exitstatus

if exit_status != 0
  puts "\nRuboCop found violations. Fix them or commit with --no-verify to skip."
  exit 1
end

More sophisticated setups use tools like Lefthook or Husky to manage Git hooks across teams:

# lefthook.yml
pre-commit:
  parallel: true
  commands:
    rubocop:
      glob: "*.rb"
      run: bundle exec rubocop {staged_files}
    
    rubocop-auto-fix:
      glob: "*.rb"
      run: bundle exec rubocop -A {staged_files}
      stage_fixed: true

CI/CD Integration

Continuous integration enforces linting on all pull requests:

# .github/workflows/rubocop.yml
name: RuboCop

on: [push, pull_request]

jobs:
  rubocop:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2
          bundler-cache: true
      - name: Run RuboCop
        run: bundle exec rubocop --format github

The github format outputs annotations that appear inline in pull request diffs. Alternative formats include JSON for parsing by other tools, junit for test reporting dashboards, and html for visual reports.

Custom Cop for Architecture Enforcement

Teams enforce architectural boundaries through custom cops:

# lib/custom_cops/no_cross_boundary_calls.rb
module CustomCops
  class NoCrossBoundaryRequires < RuboCop::Cop::Base
    MSG = 'Core domain should not require from infrastructure layer'

    INFRASTRUCTURE_PATHS = %w[
      app/repositories
      app/adapters
      app/controllers
    ].freeze

    def on_send(node)
      return unless node.method_name == :require_relative
      return unless in_core_domain?

      required_path = node.first_argument.str_content
      return unless requires_infrastructure?(required_path)

      add_offense(node)
    end

    private

    def in_core_domain?
      processed_source.file_path.include?('app/domain')
    end

    def requires_infrastructure?(path)
      INFRASTRUCTURE_PATHS.any? { |infra| path.include?(infra) }
    end
  end
end

This cop enforces clean architecture by preventing domain logic from depending on infrastructure concerns. The violation appears when domain models require repository or controller code.

Integration & Interoperability

Editor Integration

Modern editors integrate RuboCop through multiple mechanisms. Language Server Protocol implementations provide real-time linting as developers type. Direct editor plugins run RuboCop in response to file events. Each approach offers different characteristics for feedback speed and resource usage.

VS Code integration through the Ruby LSP extension displays violations inline with diagnostic messages. The extension highlights violations with colored underlines, shows detailed messages on hover, and provides quick-fix actions for auto-correctable violations. Configuration happens through workspace settings:

// .vscode/settings.json
{
  "ruby.lint": {
    "rubocop": true
  },
  "ruby.format": "rubocop",
  "editor.formatOnSave": true,
  "ruby.rubocop.useBundler": true
}

RubyMine integrates RuboCop natively through its inspections system. The IDE runs RuboCop analysis continuously, applying violations as inspection warnings. The integration respects RuboCop configuration files and provides IDE-based quick fixes:

# Settings > Editor > Inspections > Ruby > Gems and gem management > RuboCop
Enable RuboCop inspections: true
Run RuboCop inspections on the fly: true
RuboCop executable path: Use bundler

Vim integration typically uses ALE (Asynchronous Lint Engine) or similar plugins. ALE runs linters asynchronously, displaying results without blocking editing:

" .vimrc
let g:ale_linters = {
\   'ruby': ['rubocop'],
\}
let g:ale_fixers = {
\   'ruby': ['rubocop'],
\}
let g:ale_fix_on_save = 1
let g:ale_ruby_rubocop_executable = 'bundle'

CI Pipeline Integration

Linting in CI pipelines catches violations that escape local checks. The pipeline configuration determines when linting runs, how violations surface, and whether they block deployment.

GitHub Actions provides native RuboCop integration with pull request annotations:

# .github/workflows/lint.yml
name: Lint

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  rubocop:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2
          bundler-cache: true
      
      - name: RuboCop
        run: |
          bundle exec rubocop \
            --format json \
            --out rubocop-results.json \
            --format github
      
      - name: Annotate PR
        if: failure()
        uses: reviewdog/action-rubocop@v2
        with:
          rubocop_version: gemfile
          reporter: github-pr-review

GitLab CI integrates through Code Quality reports:

# .gitlab-ci.yml
rubocop:
  stage: test
  script:
    - bundle exec rubocop --format json --out rubocop.json
  artifacts:
    reports:
      codequality: rubocop.json
    when: always

The Code Quality report shows violations in merge request diffs as inline comments. GitLab tracks quality trends across commits, showing whether code quality improves or degrades over time.

Pull Request Automation

Automated pull request checks enforce linting before human review. Review bots examine changed files, run linting, and comment on violations:

# .pronto.yml
github:
  slug: organization/repository
  access_token: <%= ENV['GITHUB_ACCESS_TOKEN'] %>

runners:
  - rubocop

rubocop:
  config_file: .rubocop.yml

Pronto runs linting on changed files only, reducing noise from pre-existing violations. The bot posts comments on specific lines containing violations, allowing developers to fix issues before reviewers examine the code.

Danger provides more flexible automation through Ruby scripts:

# Dangerfile
rubocop.lint(inline_comment: true)

if rubocop.violations.any?
  warn "Please fix RuboCop violations before merging"
end

# Require documentation for public APIs
changed_files = git.modified_files + git.added_files
public_methods = changed_files.grep(/app\/(models|services)/).any? do |file|
  File.read(file).include?('def self.')
end

if public_methods && rubocop.violations.any? { |v| v[:cop_name] == 'Style/Documentation' }
  fail "Public API methods require documentation"
end

Git Hooks

Git hooks enforce linting at different points in the development workflow. Pre-commit hooks catch violations before they enter version control. Pre-push hooks run heavier analysis before code reaches remote repositories.

Lefthook provides cross-platform hook management:

# lefthook.yml
pre-commit:
  parallel: true
  commands:
    rubocop-changed:
      glob: "*.rb"
      run: bundle exec rubocop --force-exclusion {staged_files}
    
    rubocop-auto-fix:
      glob: "*.rb"
      run: bundle exec rubocop -A --force-exclusion {staged_files}
      stage_fixed: true

pre-push:
  commands:
    rubocop-full:
      run: bundle exec rubocop

The configuration runs fast checks on staged files during commit, reserving full repository analysis for the pre-push hook. Auto-fixing stages corrections automatically, ensuring consistent formatting without manual intervention.

Overcommit offers similar functionality with Ruby-based configuration:

# .overcommit.yml
PreCommit:
  RuboCop:
    enabled: true
    on_warn: fail
    command: ['bundle', 'exec', 'rubocop']
    flags: ['--force-exclusion']
    
PrePush:
  RuboCop:
    enabled: true
    required: true
    command: ['bundle', 'exec', 'rubocop']

Development Workflow Integration

Linting integrates into development workflows at multiple points. Format-on-save provides immediate correction. Commit hooks prevent violations from entering version control. CI checks block merges containing violations. Each layer provides defense in depth.

Developers configure their environment to run auto-correction on save:

# .vscode/settings.json
{
  "editor.formatOnSave": true,
  "ruby.format": "rubocop"
}

The editor runs RuboCop with auto-correction flags whenever the developer saves a file. Formatting violations disappear immediately, maintaining consistency without conscious effort.

Watch mode enables continuous linting during development:

# Use guard to watch files
# Guardfile
guard :rubocop, all_on_start: false, cli: ['--auto-correct'] do
  watch(%r{^.+\.rb$})
  watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
end

Guard monitors file changes and runs RuboCop automatically. Developers see violations moments after creating them, reducing the feedback loop from minutes to seconds.

Reference

Common RuboCop Cops

Cop Name Department Description Auto-correctable
Layout/IndentationWidth Layout Checks for correct indentation width Yes
Layout/TrailingWhitespace Layout Detects trailing whitespace at end of lines Yes
Layout/EmptyLineAfterGuardClause Layout Requires empty line after guard clause Yes
Style/StringLiterals Style Enforces single or double quote consistency Yes
Style/HashSyntax Style Enforces modern hash syntax where possible Yes
Style/FrozenStringLiteralComment Style Requires frozen string literal comment Yes
Style/Documentation Style Requires class and module documentation No
Style/SymbolArray Style Enforces symbol array literal syntax Yes
Metrics/MethodLength Metrics Flags methods exceeding line count threshold No
Metrics/CyclomaticComplexity Metrics Calculates cyclomatic complexity of methods No
Metrics/AbcSize Metrics Measures assignment, branch, condition complexity No
Lint/UnusedMethodArgument Lint Detects method arguments never used Yes
Lint/ShadowingOuterLocalVariable Lint Flags variables shadowing outer scope No
Lint/Debugger Lint Detects leftover debugging statements Yes
Lint/UnreachableCode Lint Identifies code after unconditional exit No
Performance/StringReplacement Performance Suggests faster string replacement methods Yes
Performance/FlatMap Performance Recommends flat_map over map.flatten Yes
Rails/HasManyOrHasOneDependent Rails Enforces dependent option on associations No
Rails/UniqueValidationWithoutIndex Rails Requires database index for uniqueness validation No
Security/Eval Security Detects dangerous dynamic code evaluation No
Security/JSONLoad Security Flags unsafe JSON parsing methods Yes

Configuration Options

Option Location Purpose Example
TargetRubyVersion AllCops Sets minimum Ruby version for syntax 3.2
NewCops AllCops Controls automatic enabling of new cops enable, disable, pending
Exclude AllCops or per-cop Files/patterns to skip db/schema.rb, vendor/**
DisabledByDefault AllCops Inverts default enabled state true, false
EnforcedStyle Style cops Selects enforcement variant single_quotes, double_quotes
Enabled Any cop Activates or deactivates cop true, false
Severity Any cop Sets violation severity level error, warning, info
Max Metrics cops Threshold for metric violations 15, 20, 25
AutoCorrect Any cop Enables auto-correction true, false
inherit_from Root level Loads additional config files .rubocop_todo.yml
inherit_gem Root level Loads gem-provided configs rubocop-rails: config/rails.yml

Command Line Options

Flag Purpose Usage
-a, --auto-correct Auto-correct safe violations rubocop -a
-A, --auto-correct-all Auto-correct all violations including unsafe rubocop -A
--format Output format selection rubocop --format json
--out Redirect output to file rubocop --out report.html
--force-exclusion Apply exclusions even with explicit paths rubocop --force-exclusion app/models
--only Run specific cops only rubocop --only Layout/IndentationWidth
--except Skip specific cops rubocop --except Style/Documentation
--fail-level Set minimum severity for exit code rubocop --fail-level warning
--display-cop-names Show cop names in output rubocop --display-cop-names
--config Use specific config file rubocop --config config/strict.yml
--auto-gen-config Generate todo file rubocop --auto-gen-config
--regenerate-todo Update existing todo file rubocop --regenerate-todo

Inline Configuration Syntax

Pattern Purpose Example
rubocop:disable CopName Disable cop until re-enabled # rubocop:disable Metrics/MethodLength
rubocop:enable CopName Re-enable previously disabled cop # rubocop:enable Metrics/MethodLength
rubocop:disable all Disable all cops until re-enabled # rubocop:disable all
rubocop:todo CopName Mark as intentional technical debt # rubocop:todo Metrics/CyclomaticComplexity
Inline disable Disable cop for single line def method # rubocop:disable Metrics/AbcSize
Multiple cops Disable multiple cops simultaneously # rubocop:disable Style/Documentation, Metrics/MethodLength

Output Formats

Format Purpose Use Case
progress Default progress indicator Interactive terminal use
simple Human-readable list Command line review
json Machine-parseable output CI integration, tool consumption
html Visual report with styling Documentation, stakeholder reports
junit JUnit XML format Test reporting dashboards
github GitHub Actions annotations Pull request inline comments
offense_count Count by cop type Tracking improvement over time
worst_offenders Most violated files Prioritizing refactoring
tap Test Anything Protocol Test harness integration

Severity Levels

Level Meaning CI Behavior Editor Display
error Critical violation requiring fix Fails build Red underline
warning Violation should be addressed Passes build with warnings Yellow underline
info Informational only Ignored Blue underline
convention Style preference Configurable Gray underline
refactor Code smell requiring refactor Configurable Orange underline

Department Categories

Department Focus Example Cops
Layout Code formatting and whitespace IndentationWidth, TrailingWhitespace
Style Idiomatic Ruby conventions StringLiterals, HashSyntax, SymbolArray
Metrics Complexity and size measurements MethodLength, CyclomaticComplexity, AbcSize
Lint Bug detection and suspicious patterns UnusedMethodArgument, ShadowingOuterLocalVariable
Performance Performance improvements StringReplacement, FlatMap, ReverseEach
Security Security vulnerabilities Eval, JSONLoad, Open
Rails Rails framework conventions HasManyOrHasOneDependent, OutputSafety
RSpec RSpec test organization MultipleExpectations, NestedGroups
Migration Rails migration best practices ChangeColumn, RemoveColumn
Naming Naming conventions MethodName, VariableName, ConstantName