/rubocop

An experimental Ruby code analyzer, based on the community Ruby style guide.

Primary LanguageRubyMIT LicenseMIT

Gem Version Build Status Coverage Status

RuboCop

Role models are important.
-- Officer Alex J. Murphy / RoboCop

RuboCop is a Ruby static code analyzer. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide.

Most aspects of its behavior can be tweaked via various configuration options.

Apart from reporting problems in your code, RuboCop can also automatically fix some of the problems for you.

Installation

RuboCop's installation is pretty standard:

$ gem install rubocop

Basic Usage

Running rubocop with no arguments will check all Ruby source files in the current folder:

$ rubocop

Alternatively you can pass rubocop a list of files and folders to check:

$ rubocop app spec lib/something.rb

Here's RuboCop in action. Consider the following Ruby source code:

def badName
  if something
    test
    end
end

Running RuboCop on it (assuming it's in a file named test.rb) would produce the following report:

Offences:

test.rb:1:5: C: Use snake_case for methods and variables.
def badName
    ^^^^^^^
test.rb:2:3: C: Favor modifier if/unless usage when you have a single-line body. Another good alternative is the usage of control flow &&/||.
  if something
  ^^
test.rb:4:5: W: end at 4, 4 is not aligned with if at 2, 2
    end
    ^^^

1 file inspected, 3 offences detected

For more details check the available command-line options:

$ rubocop -h
Command flag Description
-v/--version Displays the current version and exits
-V/--verbose-version Displays the current version plus the version of Parser and Ruby
-d/--debug Displays some extra debug output
-c/--config Run with specified config file
-f/--format Choose a formatter
-o/--out Write output to a file instead of STDOUT
-r/--require Require Ruby file
-R/--rails Run extra Rails cops
-l/--lint Run only lint cops
-a/--auto-correct Auto-correct certain offences Note: Experimental - use with caution
--only Run only the specified cop
--auto-gen-config Generate a configuration file acting as a TODO list
--show-cops Shows available cops and their configuration

Cops

In RuboCop lingo the various checks performed on the code are called cops. There are several cop departments.

Style

Most of the cops in RuboCop are so called style cops that check for stylistics problems in your code. Almost all of the them are based on the Ruby Style Guide. Many of the style cops have configurations options allowing them to support different popular coding conventions.

Lint

Lint cops check for possible errors and very bad practices in your code. RuboCop implements in a portable way all built-in MRI lint checks (ruby -wc) and adds a lot of extra lint checks of its own. You can run only the lint cops like this:

$ rubocop -l

Disabling any of the lint cops in generally a bad idea.

Rails

Rails cops are specific to the Ruby on Rails framework. Unlike style and lint cops they are not used by default and you have to request them specifically:

$ rubocop -R

Configuration

The behavior of RuboCop can be controlled via the .rubocop.yml configuration file. The file can be placed either in your home folder or in some project folder.

RuboCop will start looking for the configuration file in the directory where the inspected file is and continue its way up to the root folder.

The file has the following format:

inherit_from: ../.rubocop.yml

Encoding:
  Enabled: true

LineLength:
  Enabled: true
  Max: 79

It allows to enable/disable certain cops (checks) and to alter their behavior if they accept any parameters.

The optional inherit_from directive is used to include configuration from one or more files. This makes it possible to have the common project settings in the .rubocop.yml file at the project root, and then only the deviations from those rules in the subdirectories. The included files can be given with absolute paths or paths relative to the file where they are referenced. The settings after an inherit_from directive override any settings in the included file(s). When multiple files are included, the first file in the list has the lowest precedence and the last one has the highest. The format for multiple inclusion is:

inherit_from:
  - ../.rubocop.yml
  - ../conf/.rubocop.yml

Defaults

The file config/default.yml under the RuboCop home directory contains the default settings that all configurations inherit from. Project and personal .rubocop.yml files need only make settings that are different from the default ones. If there is no .rubocop.yml file in the project or home directory, config/default.yml will be used.

Disabling Cops within Source Code

One or more individual cops can be disabled locally in a section of a file by adding a comment such as

# rubocop:disable LineLength, StringLiterals
[...]
# rubocop:enable LineLength, StringLiterals

You can also disable all cops with

# rubocop:disable all
[...]
# rubocop:enable all

One or more cops can be disabled on a single line with an end-of-line comment.

for x in (0..19) # rubocop:disable AvoidFor

Including/Excluding files

RuboCop checks all files recursively within the directory it is run on. However, it does not recognize some files as Ruby(only files ending with .rb or extensionless files with a #!.*ruby declaration are automatically detected) files, and if you'd like it to check these you'll need to manually pass them in. Files and directories can also be ignored through .rubocop.yml.

Here is an example that might be used for a Rails project:

AllCops:
  Includes:
    - Rakefile
    - config.ru
  Excludes:
    - db/**
    - config/**
    - script/**

# other configuration
# ...

Note: Files and directories are specified relative to the .rubocop.yml file. The Excludes parameter is special. It is valid for the directory tree starting where it is defined. It is not shadowed by the setting of Excludes in other .rubocop.yml files in subdirectories.

Automatically Generated Configuration

If you have a code base with an overwhelming amount of offences, it can be a good idea to use rubocop --auto-gen-config and add an inherit_from: rubocop-todo.yml in your .rubocop.yml. The generated file rubocop-todo.yml contains configuration to disable all cops that currently detect an offence in the code. Then you can start removing the entries in the generated file one by one as you work through all the offences in the code.

Formatters

Clang Formatter (default)

The Clang formatter displays the offences in a manner similar to clang:

rubocop test.rb

Inspecting 1 file
W

Offences:

test.rb:1:1: C: Use snake_case for methods and variables.
def badName
^^^
test.rb:2:3: C: Favor modifier if/unless usage when you have a single-line body. Another good alternative is the usage of control flow &&/||.
  if something
  ^^^^^
test.rb:4:5: W: end at 4, 4 is not aligned with if at 2, 2
    end
    ^^^

1 file inspected, 3 offences detected

Emacs

The Emacs formatter displays the offences in a format suitable for consumption by Emacs (and possibly other tools).

rubocop --format emacs test.rb

/Users/bozhidar/projects/test.rb:1:1: C: Use snake_case for methods and variables.
/Users/bozhidar/projects/test.rb:2:3: C: Favor modifier if/unless usage when you have a single-line body. Another good alternative is the usage of control flow &&/||.
/Users/bozhidar/projects/test.rb:4:5: W: end at 4, 4 is not aligned with if at 2, 2

1 file inspected, 3 offences detected

Simple (default in RuboCop prior to version 0.9)

The name of the formatter says it all :-)

rubocop --format simple test.rb

== test.rb ==
C:  1:  1: Use snake_case for methods and variables.
C:  2:  3: Favor modifier if/unless usage when you have a single-line body. Another good alternative is the usage of control flow &&/||.
W:  4:  5: end at 4, 4 is not aligned with if at 2, 2

1 file inspected, 3 offences detected

File List Formmater

Sometimes you might want to just open all files with offences in your favorite editor. This formatter outputs just the names of the files with offences in them and makes it possible to do something like:

rubocop --format files | xargs vim

JSON Formatter

You can get RuboCop's inspection result in JSON format by passing --format json option in command line. The JSON structure is like the following example:

{
  "metadata": {
    "rubocop_version": "0.9.0",
    "ruby_engine": "ruby",
    "ruby_version": "2.0.0",
    "ruby_patchlevel": "195",
    "ruby_platform": "x86_64-darwin12.3.0"
  },
  "files": [{
      "path": "lib/foo.rb",
      "offences": []
    }, {
      "path": "lib/bar.rb",
      "offences": [{
          "severity": "convention",
          "message": "Line is too long. [81/79]",
          "cop_name": "LineLength",
          "corrected": true,
          "location": {
            "line": 546,
            "column": 80
          }
        }, {
          "severity": "warning",
          "message": "Unreachable code detected.",
          "cop_name": "UnreachableCode",
          "corrected": false,
          "location": {
            "line": 15,
            "column": 9
          }
        }
      ]
    }
  ],
  "summary": {
    "offence_count": 2,
    "target_file_count": 2,
    "inspected_file_count": 2
  }
}

OffenceCount Formatter

Sometimes when first applying RuboCop to a codebase, it's nice to be able to see where most of your style cleanup is going to be spent.

With this in mind, you can use the offence count formatter to outline the offended cops and the number of offences found for each by running:

rubocop --format offences

(87)  Documentation
(12)  DotPosition
(8)   AvoidGlobalVars
(7)   EmptyLines
(6)   AssignmentInCondition
(4)   Blocks
(4)   CommentAnnotation
(3)   BlockAlignment
(1)   IndentationWidth
(1)   AvoidPerlBackrefs
(1)   ColonMethodCall

Custom Formatters

You can customize RuboCop's output format with custom formatter.

Creating Custom Formatter

To implement a custom formatter, you need to subclass Rubocop::Formatter::BaseFormatter and override some methods, or implement all formatter API methods by duck typing.

Please see the documents below for more formatter API details.

Using Custom Formatter in Command Line

You can tell RuboCop to use your custom formatter with a combination of --format and --require option. For example, when you have defined MyCustomFormatter in ./path/to/my_custom_formatter.rb, you would type this command:

$ rubocop --require ./path/to/my_custom_formatter --format MyCustomFormatter

Note: The path passed to --require is directly passed to Kernel.require. If your custom formatter file is not in $LOAD_PATH, you need to specify the path as relative path prefixed with ./ explicitly, or absolute path.

Compatibility

RuboCop supported only MRI 1.9 & MRI 2.0 prior to version 0.8. After RuboCop 0.8, JRuby and Rubinius in 1.9 modes are also supported.

Editor integration

Emacs

rubocop.el is a simple Emacs interface for RuboCop. It allows you to run RuboCop inside Emacs and quickly jump between problems in your code.

flycheck > 0.9 also supports RuboCop and uses it by default when available.

Vim

The vim-rubocop plugin runs RuboCop and displays the results in Vim.

There's also a RuboCop checker in syntastic.

Sublime Text 2

If you're a ST2 user you might find the Sublime RuboCop plugin useful.

Other Editors

Here's one great opportunity to contribute to RuboCop - implement RuboCop integration for your favorite editor.

Guard integration

If you're fond of Guard you might like guard-rubocop. It allows you to automatically check Ruby code style with RuboCop when files are modified.

Rake integration

To use RuboCop in your Rakefile add the following:

require 'rubocop/rake_task'

Rubocop::RakeTask.new

The above will use default values

require 'rubocop/rake_task'

desc 'Run RuboCop on the lib directory'
Rubocop::RakeTask.new(:rubocop) do |task|
  task.patterns = ['lib/**/*.rb']
  # don't abort rake on failure
  task.fail_on_error = false
end

Team

Here's a list of RuboCop's core developers:

Contributors

Here's a list of all the people who have contributed to the development of RuboCop.

I'm extremely grateful to each and every one of them!

If you'd like to contribute to RuboCop, please take the time to go through our short contribution guidelines.

Converting more of the Ruby Style Guide into RuboCop cops is our top priority right now. Writing a new cop is a great way to dive into RuboCop!

Of course, bug reports and suggestions for improvements are always welcome. GitHub pull requests are even better! :-)

Mailing List

If you're interested in everything regarding RuboCop's development, consider joining its Google Group.

Changelog

RuboCop's changelog is available here.

Copyright

Copyright (c) 2012-2013 Bozhidar Batsov. See LICENSE.txt for further details.