RuboCop
DevOps Tool
RuboCop
Overview
RuboCop is a Ruby code quality checking tool that enforces adherence to the Ruby Style Guide and maintains code style consistency. It provides auto-correction capabilities and is widely used as the standard quality checking tool for Ruby development. With built-in LSP server, gradual introduction system, and flexible configuration system, it supports everything from legacy projects to new projects. Through a rich ecosystem including Rails extensions, it powerfully supports quality improvement and coding convention unification in Ruby development.
Details
RuboCop is a Ruby-specific static code analysis tool (linter) and code formatter developed and maintained by the Ruby community. Since its release in 2013, it has been established as the de facto standard code quality checking tool in the Ruby ecosystem.
Key Features
- Ruby Style Guide Compliance: Automatic checking of community Ruby Style Guide
- Auto-correction: Automatic application of safe correction items (Correctable violations)
- Cops System: Departmental rule system including Style, Lint, Metrics, Rails, etc.
- Built-in LSP Server: Language Server Protocol support for editor integration
- Gradual Introduction: Safe introduction to existing projects through Pending Cops feature
- Advanced Configuration: Extremely flexible configuration system for customization
- Extensibility: Support for third-party extensions like Rails extensions
- Allowlist Generation: Automatic allowlist generation for existing violations
- Rich Output Formats: Various output formats including JSON, HTML, JUnit, etc.
Cops Department Details
- Style Cops: Code style unification (indentation, naming conventions, etc.)
- Lint Cops: Detection of potential bugs and issues
- Metrics Cops: Measurement of code complexity, method length, etc.
- Rails Cops: Rails-specific best practices (separate gem required)
Pros and Cons
Pros
- Standard tool for code style unification and quality improvement in Ruby development
- Significant reduction in manual correction work through auto-correction features
- Generation of readable and maintainable code through Ruby Style Guide compliance
- Systematic and comprehensive code quality checking through Cops system
- Real-time editor feedback through LSP server integration
- Safe application to legacy projects through gradual introduction system
- Specialized checking through rich ecosystem including Rails extensions
- Flexible response to project requirements through advanced configuration system
- Automated quality assurance and code review efficiency through CI/CD integration
- Practical introduction to large projects through allowlist functionality
Cons
- Complexity of initial setup and rule selection with learning costs
- Long execution times for large projects
- Risk of development speed reduction due to overly strict settings
- Operational burden from massive warnings when applying to legacy code
- Inability to use unified tools in multilingual projects due to Ruby-only focus
- Complexity of Cops dependency and version compatibility management
- Incompleteness of some auto-corrections (manual verification required)
- Need for discussion and consensus formation regarding coding conventions within teams
- Additional dependencies from external gems (Rails Cops, etc.)
- Maintenance burden from configuration file complexity
Reference Links
- RuboCop Official Site
- RuboCop Official Documentation
- RuboCop GitHub Repository
- Ruby Style Guide
- RuboCop Rails
- RuboCop RSpec
Code Examples
Installation and Basic Setup
# Basic installation
gem install rubocop
# Add to Gemfile (recommended)
echo 'gem "rubocop", "~> 1.68", require: false' >> Gemfile
bundle install
# Installation with Rails extensions
gem install rubocop rubocop-rails
# Installation in development group
# Gemfile
group :development do
gem 'rubocop', '~> 1.68', require: false
gem 'rubocop-rails', '~> 2.27', require: false
gem 'rubocop-rspec', '~> 3.2', require: false
gem 'rubocop-performance', '~> 1.23', require: false
end
# Installation via bundler
bundle add rubocop --group=development
bundle add rubocop-rails --group=development
# Version verification
rubocop --version
Basic Execution Methods
# Basic execution
rubocop
# Check specific file
rubocop app/models/user.rb
# Check specific directory
rubocop app/controllers/
# Execute auto-correction
rubocop -a app/
# Execute including unsafe corrections
rubocop -A app/
# Execute only specific Cop
rubocop --only Style/StringLiterals app/
# Exclude specific Cop
rubocop --except Style/Documentation app/
# Detailed output
rubocop --display-style-guide app/
# Progress display
rubocop --progress app/
# Parallel execution
rubocop --parallel app/
# Use cache
rubocop --cache true app/
Configuration File (.rubocop.yml)
# .rubocop.yml - Basic configuration
# Inheritance settings
inherit_from:
- .rubocop_todo.yml
# Exclusion patterns
AllCops:
# Target Ruby version
TargetRubyVersion: 3.2
# Automatically enable new Cops
NewCops: enable
# Exclusion patterns
Exclude:
- 'db/schema.rb'
- 'db/migrate/*'
- 'vendor/**/*'
- 'bin/*'
- 'node_modules/**/*'
- 'tmp/**/*'
- '.git/**/*'
# Include patterns
Include:
- '**/*.rb'
- '**/*.rake'
- '**/Rakefile'
- '**/Gemfile'
- '**/config.ru'
# Style Cops configuration
Style/Documentation:
Enabled: false
Style/StringLiterals:
EnforcedStyle: single_quotes
Style/StringLiteralsInInterpolation:
EnforcedStyle: single_quotes
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/FrozenStringLiteralComment:
Enabled: true
EnforcedStyle: always
# Lint Cops configuration
Lint/UnusedMethodArgument:
AllowUnusedKeywordArguments: true
# Metrics Cops configuration
Metrics/ClassLength:
Max: 150
Metrics/MethodLength:
Max: 20
CountAsOne:
- 'array'
- 'hash'
- 'heredoc'
Metrics/AbcSize:
Max: 20
Metrics/CyclomaticComplexity:
Max: 10
Metrics/PerceivedComplexity:
Max: 10
Metrics/BlockLength:
Exclude:
- 'spec/**/*'
- 'config/routes.rb'
- 'db/seeds.rb'
# Layout Cops configuration
Layout/LineLength:
Max: 120
AllowHeredoc: true
AllowURI: true
URISchemes:
- http
- https
Layout/MultilineMethodCallIndentation:
EnforcedStyle: aligned
Layout/HashAlignment:
EnforcedHashRocketStyle: key
EnforcedColonStyle: key
Rails-specific Configuration
# .rubocop.yml - Rails configuration
require:
- rubocop-rails
- rubocop-rspec
- rubocop-performance
inherit_from: .rubocop_todo.yml
AllCops:
TargetRubyVersion: 3.2
NewCops: enable
Exclude:
- 'db/schema.rb'
- 'db/migrate/*'
- 'vendor/**/*'
- 'bin/*'
- 'node_modules/**/*'
# Rails Cops configuration
Rails/Enabled: true
Rails/HasManyOrHasOneDependent:
Enabled: true
Rails/InversOf:
Enabled: true
Rails/Presence:
Enabled: true
Rails/UniqBeforePluck:
Enabled: true
Rails/BulkChangeTable:
Enabled: true
# RSpec Cops configuration
RSpec/ExampleLength:
Max: 10
RSpec/MultipleExpectations:
Max: 3
RSpec/NestedGroups:
Max: 3
RSpec/DescribeClass:
Enabled: true
# Performance Cops configuration
Performance/Caller:
Enabled: true
Performance/CaseWhenSplat:
Enabled: true
Performance/StringReplacement:
Enabled: true
CI/CD Integration Examples
GitHub Actions
# .github/workflows/rubocop.yml
name: RuboCop
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- name: Install dependencies
run: bundle install
- name: Run RuboCop
run: bundle exec rubocop --format github
- name: Run RuboCop with auto-correct (if main branch)
if: github.ref == 'refs/heads/main'
run: |
bundle exec rubocop -a
if [ -n "$(git status --porcelain)" ]; then
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add -A
git commit -m "Auto-fix RuboCop violations" -a
git push
fi
GitLab CI
# .gitlab-ci.yml
stages:
- quality
rubocop:
stage: quality
image: ruby:3.2-alpine
before_script:
- apk add --no-cache git
- bundle install --jobs $(nproc) --retry 3
script:
- bundle exec rubocop --format json --out rubocop-results.json
- bundle exec rubocop
artifacts:
reports:
codequality: rubocop-results.json
paths:
- rubocop-results.json
expire_in: 1 week
only:
- main
- develop
- merge_requests
Editor Integration Configuration
VS Code Configuration
// .vscode/settings.json
{
"ruby.rubocop.executePath": "bundle exec rubocop",
"ruby.rubocop.configFilePath": ".rubocop.yml",
"ruby.rubocop.onSave": true,
"ruby.format": "rubocop",
"ruby.lint": {
"rubocop": {
"useBundler": true,
"lint": true,
"rails": true
}
},
"[ruby]": {
"editor.defaultFormatter": "misogi.ruby-rubocop",
"editor.formatOnSave": true,
"editor.rulers": [120]
}
}
// RuboCop LSP usage configuration
{
"ruby.rubocop.useLsp": true,
"ruby.rubocop.lspConfigurationOptions": {
"safeAutocorrect": true
}
}
RubyMine/IntelliJ Configuration
# RubyMine configuration
# File → Settings → Editor → Inspections → Ruby
# Enable RuboCop
# External Tools configuration
# File → Settings → Tools → External Tools
Name: RuboCop
Description: Ruby static code analyzer
Program: bundle
Arguments: exec rubocop $FilePath$
Working Directory: $ProjectFileDir$
# File Watchers configuration
# File Type: Ruby
# Scope: Project Files
# Program: bundle
# Arguments: exec rubocop -a $FilePath$
Gradual Introduction Strategy
TODO File Generation
# Generate TODO file for existing projects
rubocop --auto-gen-config
# Example of generated .rubocop_todo.yml
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2025-01-01 12:00:00 UTC using RuboCop version 1.68.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
Style/Documentation:
Exclude:
- 'app/controllers/application_controller.rb'
- 'app/models/user.rb'
Metrics/MethodLength:
Max: 25 # Goal: 15
Gradual Improvement Script
# scripts/rubocop_gradual.rb
#!/usr/bin/env ruby
require 'yaml'
require 'json'
class RubocopGradualImprovement
def initialize
@todo_file = '.rubocop_todo.yml'
@config = load_todo_config
end
def improve_gradually
@config.each do |cop_name, settings|
next unless improvable?(cop_name, settings)
puts "Improving #{cop_name}..."
improve_cop(cop_name, settings)
end
save_config
end
private
def improvable?(cop_name, settings)
# Metrics Cops with numerical settings
cop_name.start_with?('Metrics/') &&
settings.is_a?(Hash) &&
settings['Max']
end
def improve_cop(cop_name, settings)
current_max = settings['Max']
target_max = target_value(cop_name)
if current_max > target_max
new_max = [current_max - 1, target_max].max
settings['Max'] = new_max
puts " #{cop_name}: #{current_max} → #{new_max}"
end
end
def target_value(cop_name)
targets = {
'Metrics/MethodLength' => 15,
'Metrics/ClassLength' => 100,
'Metrics/AbcSize' => 15,
'Metrics/CyclomaticComplexity' => 6
}
targets[cop_name] || 10
end
def load_todo_config
YAML.load_file(@todo_file) if File.exist?(@todo_file)
rescue
{}
end
def save_config
File.write(@todo_file, @config.to_yaml)
end
end
# Execute
RubocopGradualImprovement.new.improve_gradually if __FILE__ == $0
Advanced Configuration and Customization
Custom Cop Creation
# lib/custom_cops/no_binding_pry.rb
module CustomCops
class NoBindingPry < RuboCop::Cop::Base
MSG = 'Remove binding.pry from production code.'
def on_send(node)
return unless binding_pry?(node)
add_offense(node, message: MSG)
end
private
def binding_pry?(node)
node.receiver&.const_name == 'Kernel' &&
node.method_name == :binding &&
node.parent&.method_name == :pry
end
end
end
# Load custom Cop in .rubocop.yml
require:
- './lib/custom_cops/no_binding_pry'
CustomCops/NoBindingPry:
Enabled: true
Exclude:
- 'spec/**/*'
Multi-environment Configuration Management
# .rubocop.yml - Production configuration
production: &production
AllCops:
TargetRubyVersion: 3.2
Metrics/LineLength:
Max: 100
# .rubocop_development.yml - Development configuration
inherit_from: .rubocop.yml
AllCops:
NewCops: enable
Style/Documentation:
Enabled: false
Metrics/MethodLength:
Max: 25 # More lenient during development
# Environment-specific execution
rubocop --config .rubocop.yml # Production configuration
rubocop --config .rubocop_development.yml # Development configuration
Performance Optimization and Troubleshooting
# Performance diagnosis
rubocop --profile
# Parallel execution (speed up)
rubocop --parallel
# Use cache
rubocop --cache true
# Debug output
rubocop --debug app/models/user.rb
# Detailed information for specific Cop
rubocop --show-cops Style/StringLiterals
# Configuration file validation
rubocop --config .rubocop.yml --lint
# Memory usage check
time rubocop --parallel app/