This guide will get you up and running with RuboCop in a few minutes. RuboCop serves three primary roles:
-
Code style checker (a.k.a. linter) — enforces style conventions from the Ruby Style Guide
-
Lint tool — catches bugs and suspicious code, like a smarter <code>ruby -w</code>
-
Code formatter — automatically fixes layout and formatting
First Run
After installing RuboCop, just run it from your project’s root directory:
$ rubocop
RuboCop will recursively check all Ruby files and report any offenses it finds:
Inspecting 5 files
{.W}.C.
Offenses:
lib/foo.rb:2:3: C: Style/IfUnlessModifier: Favor modifier if usage when having a single-line body.
if something
^^
lib/.rb:5:5: W: Lint/UselessAssignment: Useless assignment to variable - x.
x = 42
^
5 files inspected, 2 offenses detected
Each offense shows the file, line, column, severity (C for convention, W for warning, E for error), the cop name, and a description. The letter on the progress line (. = clean, C/W/E = offense found) gives you a quick overview.
Setting Up Your Project
For an existing project with many offenses, the easiest way to get started is to generate a TODO file:
$ rubocop --auto-gen-config
This creates two files:
-
<code>.rubocop_todo.yml</code> — temporarily disables all current offenses
-
<code>.rubocop.yml</code> — your configuration file (with <code>inherit_from:
.rubocop_todo.yml</code> added)
Now rubocop will pass cleanly, and you can work through the TODO entries at your own pace. See Auto-generating Configuration for details.
For a new project, you can generate a starter config file instead:
$ rubocop --init
Customizing RuboCop
All configuration lives in <code>.rubocop.yml</code>. Here are a few common adjustments:
# Increase the maximum line length
Layout/LineLength:
Max: 120
# Disable a cop entirely
Style/Documentation:
Enabled: false
# Restrict a cop to specific files
Rails/HasAndBelongsToMany:
Include:
- app/models/**/*.rb
See Configuration for the full reference.
Fixing Offenses Automatically
Many cops can autocorrect the problems they find. Use <code>-a</code> for safe corrections only, or <code>-A</code> to include unsafe ones:
# Safe autocorrections only
$ rubocop -a
# All autocorrections (safe and unsafe)
$ rubocop -A
# Fix only formatting (layout) offenses
$ rubocop -x
|
Tip
|
Review the diff after running autocorrect, especially with <code>-A</code>. See Autocorrect for more details on safe vs. unsafe corrections. |
Inspecting Only What Changed
On a large project you often care only about the code you just touched. <code>--changed</code> asks git which files differ and inspects those:
# Files you have modified since the last commit, including untracked ones
$ rubocop --changed
# Files your branch changed since it forked from main
$ rubocop --changed=main...
The revision goes straight to <code>git diff</code>, so it means what it means there.
<code>--changed=main</code> compares the working tree against the tip of main, which
also picks up every file main changed after your branch forked from it. The
three-dot form <code>main…</code> compares against the merge base instead, but it stops
at your last commit: uncommitted edits to tracked files are left out, though
untracked files still count. That makes it the one to use on CI, where the
checkout is clean anyway.
Deleted files are skipped, and Include/Exclude still apply, so the result is
the intersection of "what git says changed" and "what RuboCop would inspect
anyway". Paths given on the command line narrow it further, so
<code>rubocop --changed lib</code> inspects the changed files under lib.
Two things it is good for. On a large codebase that is mid-adoption, it keeps a local run fast and focused on the code you are actually touching:
$ rubocop --changed --diff
And on CI, it holds new code to a standard the whole repository does not meet yet, without a todo file:
$ git fetch origin main
$ rubocop --changed=origin/main...
Finding the merge base takes history from both branches, so a shallow clone (the default for many CI checkouts) has to be deepened first, or git fails with <code>no merge base</code>.
|
Note
|
The whole file is inspected, not just the lines that changed, so a file you touched can still report an offense from a part you did not write. Tools like Pronto exist for line-level filtering. |
In a repository without any commits every file counts as changed, and outside a git repository <code>--changed</code> reports the error rather than guessing.
Editor Integration
For the best experience, set up RuboCop in your editor so you get real-time feedback as you type. RuboCop has a built-in LSP server that works with any editor that supports the Language Server Protocol.
The recommended setup for popular editors:
See Integration with Other Tools for more editors and alternative approaches.
Next Steps
-
CLI Reference — full command-line reference with all flags
-
Configuration — everything about <code>.rubocop.yml</code>
-
Source Code Directives — disable/enable cops inline with comments
-
Cops — browse all available cops by department
-
Plugins — add cops for Rails, RSpec, Performance, and more