Have a look at our new Handbook: "Transitioning from Monolith to Microservices"!  Discover →

    11 Oct 2022 · Software Engineering

    How to Use Rubocop for Your Team’s Rails Apps

    5 min read
    Contents

    Rubocop is an incredibly popular Ruby gem for linting Ruby code. With very little configuration, Rubocop scans a repository for violations of the Ruby community’s style standards. In many cases, it can even autocorrect violations, which Rubocop calls “offenses”.

    Rubocop can be configured to run in a continuous integration pipeline, ensuring that code meets a given set of standards before merging into the main branch. You can also run Rubocop locally, in a container, or even with the VS Code extension. Many high-performing teams find this helpful in enforcing team standards, given Rubocop’s flexibility with rule configurations that allow for custom rules.

    Rubocop (by default) scans an entire project, so the time it takes to run will increase with the size of the project, which could slow down CI builds. Many teams find this to be a fair trade-off given the benefits of using Rubocop in a project.

    Adding Rubocop to an existing app

    Adding Rubocop to an existing application is easy in theory, but can quickly become overwhelming if the project in question does not meet the style guidelines. Fortunately, Rubocop can address one violation at a time.

    To add Rubocop to a Ruby on Rails application, begin by adding it to the Gemfile:

    gem 'rubocop', require: false

    Then, run:

    bundle install

    Next, to run Rubocop, in your project directory simply run:

    bundle exec rubocop

    Unless you’re really lucky, an existing project will probably have a number of violations. Fitting with the theme, Rubocop calls these style violations “Offenses”.

    You can organize Rubocop’s output by running:

    bundle exec rubocop --format offenses

    Automatically correcting offenses

    If you like, Rubocop can actually automatically correct a great deal of violations, just by passing the autocorrect flag:

    bundle exec rubocop -a

    Many choose to automatically correct these types of offenses to reduce the burden of making such a high volume of minor changes to satisfy code standards. If you do auto-correct changes, it’s wise to double check the diff before making any commits.

    Ignoring existing violations

    When adding Rubocop to a new project, you may find that the number of existing violations is overwhelming.

    Many choose to start by excluding existing violations, only failing checks for new occurrences. This is a great way to ensure that new code meets standards, but product work does not have to stop entirely while old code is refactored.

    To ignore existing violations, just run:

    bundle exec rubocop --auto-gen-config

    This runs Rubocop, and generates a new file, .rubocop_todo.yml. This creates a list of exclusions that tell Rubocop what to ignore, but also serves to remind you what is left to fix.

    If you run Rubocop again, you’ll see that there are NO offenses!

    Now your team can go through and make more manageable changes while removing exclusions from the Rubocop todo file.

    Changing rules to fit team standards

    Rubocop defaults to the Ruby standard style guide, which some teams may want to deviate from. Style standards are an important part of a healthy engineering culture, and naturally Rubocop allows for customization.

    Rubocop gets its configuration from the automatically generated .rubocop.yml file. If you’ve already run Rubocop with --auto-gen-config, then your configuration file is set to inherit from it. This works because the rubocop_todo.yml file is just a fancy configuration file, so the main configuration file can inherit from it.

    .rubocop_todo.yml provides good examples of rules being changed. If you want to exclude specific files or directories from failing a particular rule, you can do so like this:

    Layout/EmptyLinesAroundClassBody:
      Exclude:
        - 'app/controllers/checkout_controller.rb'

    This particular configuration excludes the file named app/controllers/checkout_controller.rb from failing the Layout/EmptyLinesAroundClassBody check.

    You can also override the values that checks specifically look for. One such example is method length, where you can set the maximum accepted lines in a method in your project by adding the following to your config:

    Metrics/MethodLength:
      Max: 24

    You can disable specific rules as well. This example disables the Style/StringLiterals check for the whole project:

    Style/StringLiterals:
      Enabled: false

    Setting custom style standards in the codebase itself is a great way to ensure that entire teams have a say in the decisions regarding style. Opening a pull request to change the style standards ensures that developers get a chance to review and comment, and also doesn’t disrupt their workflow

    You can even create a custom check, but the complexity around that is a bit beyond the scope of this article.

    Running Rubocop in Semaphore

    Running Rubocop in continuous integration is a common way to enforce that style standards are met before code is merged. This is pretty easy to do with Semaphore.

    Next, sign up for Semaphore – it’s fastest to sign up with Github to save some Github configuration later. The hobby plan will fit our needs for this example. Click “Create New”, and select “Choose Repository” to connect Semaphore to your existing Github repository.Select the basic “Ruby on Rails” workflow and edit it to add a line for bundle exec rubocop:

    checkout
    sem-version ruby 2.6.5
    cache restore
    bundle install --deployment --path vendor/bundle
    cache store
    bundle exec rubocop

    Alternatively, you can add bundle exec rubocop to almost any existing CI configuration just as easily.

    Rubocop helps your team decide on and enforce code standards in Ruby projects, which will undoubtedly improve the quality of your codebase over time. Running Rubocop in CI forces code that gets merged into the master branch to conform to standards. Pairing this with Rubocop’s flexibility in rules allows teams to incrementally improve a codebase without becoming overwhelmed. In this article, you’ve seen how easy it is to add Rubocop to an existing codebase, even if style violations are everywhere. Add Rubocop to your Rails applications today for incremental improvements on the style of your code!

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    mm
    Writen by:
    Jeff is a Software Engineer writing code, fixing bugs, and helping patients get the medications they need to live healthy lives.
    Avatar for Jeff Morhous
    Reviewed by:
    I picked up most of my soft/hardware troubleshooting skills in the US Army. A decade of Java development drove me to operations, scaling infrastructure to cope with the thundering herd. Engineering coach and CTO of Teleclinic.