Technekes Rubocop Introduction and Instructions
inherit_from:
- .rubocop_todo.yml
AllCops:
Exclude:
- vendor/**
- bin/**
- config/environments/**
Documentation:
# don't require classes to be documented
Enabled: false
Encoding:
# no need to always specify encoding
Enabled: false
AlignParameters:
# allow for multi-line methods to have normal indentation.
# for example:
#
# Person.where(
# first_name: 'tom',
# last_name: 'foolery'
# )
EnforcedStyle: with_fixed_indentation
Style/AlignParameters:
# allow for end of if to be aligned with a variable.
# for example:
#
# foo = if a == b
# 'bar'
# else
# 'baz'
# end
EnforcedStyle: with_fixed_indentation
Lint/EndAlignment:
AlignWith: variable
ClassAndModuleChildren:
# ok to use compact style when modules are predefined.
# for example the following is fine so long as we're sure that
# module MDB has already been required/defined.
#
# class MDB::Person; end
Enabled: false
Add RuboCop for dev
and test
groups in your Gemfile.
group :development, :test do
gem 'rubocop'
end
Install RuboCop
> bundle install
Copy the standard Technekes configuration for RuboCop to the project.
> curl -o .rubocop.yml https://gist.githubusercontent.com/johnallen3d/36da743fee550d91bef0/raw/rubocop.yml
Generate an override configuration file for existing projects. The generated file .rubocop_todo.yml
contains configuration to disable cops that currently detect an offense in the code by excluding the offending files, or disabling the cop altogether once a file count limit has been reached.
> bundle exec rubocop --auto-gen-config
From the projects root run the rubocop
command to execute the cops.
> bundle exec rubocop
In order to make RuboCop part of our daily workflow let's get it integrated with rake, guard and CI.
Add Rubocop to the default rake task in your Rakefile (may need to be tailored to project).
# Rakefile
if %w(development test).include?(ENV['RAILS_ENV'])
require 'rspec/core/rake_task'
require 'rubocop/rake_task'
RSpec::Core::RakeTask.new(:spec) do |spec|
spec.pattern = 'spec/**/*_spec.rb'
end
RuboCop::RakeTask.new(:rubocop)
task default: [:rubocop, :spec]
end
With this configuration simply running rake
(or bundle exec rake
if required) will run all specs and RuboCop. For example:
> bundle exec rake
Running RuboCop...
Inspecting 19 files
...................
19 files inspected, no offenses detected
/usr/local/bin/ruby -I/usr/local/bundle/gems/rspec-core-3.3.2/lib:/usr/local/bundle/gems/rspec-support-3.3.0/lib /usr/local/bundle/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*/\*_spec.rb
No examples found.
Finished in 0.00018 seconds (files took 0.06957 seconds to load)
0 examples, 0 failures
If the project you're working on is configured with Guard (if not, why?!?) then the guard-rubocop gem can be used to integrate RuboCop into your Guard workflow.
Include the Guard plugins for RSpec and RuboCop.
group :development, :test do
gem 'rubocop'
gem 'guard-rspec'
gem 'guard-rubocop'
end
Install Guard and it's plugins.
> bundle install
> bundle exec guard init rspec
> bundle exec guard init rubocop
Execute the Guard binary to start watching files.
> bundle exec guard
# inside a container?
> guard -p -l 5
There are many editor plugin that will help make RuboCop part of your everyday development workflow. Check out the editor integration section in the RuboCop README for details on your editor of choice.
If the project has a CI script or task that relies on the default rake task then RuboCop is now also integrated with CI builds. If not either modify the CI script/task to run the default rake task or append bundle exec rubocop
along side the RSpec command.
For example a ci script (./script/ci
) might look like this.
#!/bin/bash
echo "perform necessary setup"
# bundle exec rake db:migrate
echo "run all specs and rubocop"
bundle exec rake
A goal of the engineering team is to improve code quality and consistancy. One of the simplest ways to head in that direction is to start (or further) the use of RuboCop. If you're not farmiliar, RuboCop is a static Ruby code analyzer that use a common Ruby Style Guide as it's basis for enforcing standards. Once installed (it's just a gem) the RuboCop binary can be used as part of our development workflow to help enforce standards and consistancy on a change by change basis (with the help of Guard for example).
Realizing that some projects currently have a version of RuboCop setup and some do not at all we would like to take a gradual approach to introducing RuboCop. The idea would be to get RuboCop installed on an existing code base and then disable all of the cops that are not passing at the outset. From there we would spend a little time each week (or as you're naturally editing an existing piece of code) bringing things up to snuff. In addition we will hook RuboCop into our CI scripts and fail builds if all cops are not passing.