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:
- It maintains code consistency
- It helps catch unnecessary code
- It helps avoid conflicts between developers and also to remember about the conventions
- 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.
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
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.
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
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.