Lint your Ruby code with Overcommit and static analysis tools

Using Git hooks to control code quality for Ruby, Rails and Chef

What is Linter?

Linter is a static analysis tool such as RuboCop. It checks the written code and makes suggestions based on pre-defined rules by community-driven coding style guides and common idioms.

Most definitions of linter default behavior can be changed for the needs of your team and project via various configuration options.

Why linting and following style guides is important?

There are many reasons to lint the code:

  1. It maintains code consistency
  2. It helps catch unnecessary code
  3. It helps avoid conflicts between developers and also to remember about the conventions
  4. It helps optimize performance and avoid problems with security

Don’t forget to lint with Git hooks and Overcommit

Git hooks are scripts that execute before or after actions such as: commit, push, and receive. Git hooks are available out of the box.

From my experience, pre-commit hooks are perfect for automated running the enabled linters to check new changes.

Installation

gem install overcommit

Or using bundler

gem ‘overcommit’

Initialize configuration file:

touch .overcommit.yml

And override default configuration under your needs.

example of .overcommit.yml file

Before starting development overcommit should be installed the following commands:

overcommit --install
overcommit --sign

Adding RuboCop to your project

Add RuboCop to project Gemfile:

gem ‘rubocop’, require: false

And now you can check current code by just typing:

rubocop

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

rubocop -a

Also feel free to configure it for your preferences. Init .rubocop.yml into project folder and override needed options.

Initialize configuration file:

touch .rubocop.yml
example of .rubocop.yml file

Finally, enable pre-commit hook into overcommit.

PreCommit:
RuboCop:
enabled: true

The analyzer will be launched automatically for new code changes, which you will try to add to the new commit.

Most useful tools to linting of Ruby code

Fasterer

It is well known that the Ruby language not the fastest. Fasterer helps us to make our code faster by some speed improvements based on fast-ruby.

gem ‘fasterer’

Run analyzer:

fasterer

Initialize configuration file:

touch .fasterer.yml

Use list of available definitions to override them.

example of .fasterer.yml file

Enable into overcommit config:

PreCommit:
Fasterer:
enabled: true

bundler-audit

Check Gemfile.lock for installation from non-secured connections and the presence of versions of gems with vulnerabilities.

gem ‘bundler-audit’

Manual running:

bundle-audit

Enable into overcommit config:

PreCommit:
BundleAudit:
enabled: true

Example of output before trying commit:

Reek

Reek is a tool that examines Ruby classes, modules and methods and reports any Code Smells it finds.
Reek currently includes checks for some aspects of Control Couple, Data Clump, Feature Envy, Large Class, Long Parameter List, Simulated Polymorphism, Too Many Statements, Uncommunicative Name, Unused Parameters and more. See the Code Smells for up to date details of exactly what Reek will check in your code.

It also one of the most popular analyzer that can help growth quality of code base.

gem ‘reek’

Can be configured for example via config.reek file by overriding huge list of default options.

touch config.reek
example of config.reek file

Enable into overcommit config:

PreCommit:
Reek:
enabled: true

Static analysis tools for Rails applications

rails_best_practices

rails_best_practices is a code metric tool to check the quality of Rails code.

Helps to find unused methods, missing indexes into database tables and many other things.

gem ‘rails_best_practices’

Run from root app directory:

rails_best_practices .

Or for HTML output:

rails_best_practices -f html .

Enable into overcommit:

PreCommit:
RailsBestPractices:
enabled: true

The downside is that, rails_best_practices with pre-commit checks whole code of projects instead of only new changes.

Brakeman

One more tool which checks applications for security vulnerabilities — brakeman.

gem ‘brakeman’, require: false

It can be integrated with overcommit by pre-hush hook.

PrePush:
Brakeman:
enabled: true

rails_schema_up_to_date pre-commit hook

Overcommit includes useful option which can helps check to see whether the schema file is in line with the migrations.

PreCommit:
RailsSchemaUpToDate:
enabled: true

Linting for Chef

Foodcritic is a tool which helps writing quality and safer Chef cookbooks Out of the box Foodcritic contains over 70 cookbook rules, and plugin system for writing your own rules.

Monolithic repo mode

Add to Gemfile of Chef project:

gem ‘foodcritic’

And it will check your custom cookbooks into site-cookbooks folder, roles and environments files.

PreCommit:
Foodcritic:
enabled: true
cookbooks_directory: ‘site-cookbooks’
environments_directory: ‘environments’
roles_directory: ‘roles’
include:
- ‘site-cookbooks/**/*’
- ‘environments/**/*’
- ‘roles/**/*’

Single cookbook repo mode

The default. Use this if your repository contains just a single cookbook. To get this to work well, you need to write into configuration something like:

PreCommit:
Foodcritic:
enabled: true
include:
— ‘attributes/**/*’
— ‘definitions/**/*’
— ‘files/**/*’
— ‘libraries/**/*’
— ‘providers/**/*’
— ‘recipes/**/*’
— ‘resources/**/*’
— ‘templates/**/*’

berksfile_check pre-commit hook

If you are using Berkshelf to manage cookbooks, it option can check that local Berksfile.lock matches Berksfile when either changes.

PreCommit:
BerksfileCheck:
enabled: true

Other tools

https://github.com/whitesmith/rubycritic — RubyCritic is a gem that wraps around static analysis gems such as Reek, Flay and Flog to provide a quality report of your Ruby code.

https://github.com/CoralineAda/fukuzatsu- Fukuzatsu is a tool for measuring code complexity in Ruby class files. Its analysis generates scores based on cyclomatic complexity algorithms.

https://github.com/mmozuras/pronto — Quick automated code review of your changes.