Red Green Repeat Adventures of a Spec Driven Junkie

How to: Use rubocop to Improve a Ruby Codebase's Style

tl;dr: To get a sorted list of all the rubocop offenses in your Ruby codebase:

rubocop | awk ' { print $2 $3 }' | grep  "\(^C:.*\|^W:.*\)"| sort | uniq -c | sort -n

Know how to use rubocop, a Ruby code linting tool, to automatically correct small errors and list out a Ruby codebase’s top offenders to improve the Ruby codebase and/or developer style.

I demonstrate the commands: rubocop -A to auto-correct and a quick one-liner to feed rubocop’s output into get a report of the top offenders.

You will understand that you can use rubocop to improve a Ruby codebase’s style and/or contributors to the Ruby codebase.

This article will take you less than three minutes to read.

Six of the Twelve Divine Generals source and more information

Introduction

Ever since I discovered rubocop, a Ruby code linting tool, I have incorporated into my work flow:

  1. test
  2. code
  3. re-factor
  4. run rubocop to have zero new offenses

As a manager of the team, I am not directly contributing codebase anymore. At the same time, I want contributors to be cognizant of the number of rubocop offenses in the Ruby codebase, indirectly improving the codebase’s style.

Only by knowing the number of offenses, they will maintain and/or reduce rubocop offenses.

How do I get contributors to improve a Ruby codebase’s style?

  • Run rubocop in auto-correct mode
  • List out top rubocop offenses

Auto-correct with rubocop -A

Rubocop’s automatic fix: rubocop -A does a great job and corrects all the things it can fix without side effects.

This relieves the team from making silly changes that rubocop itself can manage. For example:

vagrant@ubuntu-xenial:~$ rubocop -A
Inspecting 4 files
...C
...
sendgrid-test.rb:98:13: C: Style/GlobalVars: Do not introduce global variables.
  subject = $SUBJECT_LINE
            ^^^^^^^^^^^^^

4 files inspected, 77 offenses detected, 71 offenses corrected

Nice - the codebase is cleaner, rubocop fixed the simple errors, and the codebase’s style is consistent.

Offense Frequency?

What about the automatically uncorrectable ones?

Even though rubocop -A can fix items, there can be more left. Some may be easy (i.e. “line length exceeds limit”) to difficult (i.e. “ABC complexity is greater than allowed. If you want more info on ABC complexity, I wrote this article).

How can one find out which rubocop offense is the greatest in the Ruby codebase?

As rubocop outputs the offenses as text, that means we can direct rubocop’s output into shell utilities like: grep, awk, sort, and uniq.

rubocop | awk ' { print $2 $3 }' | grep  "\(^C:.*\|^W:.*\)"| sort | uniq -c
vagrant@ubuntu-xenial:~$ rubocop | awk '{ print $2 $3 }' | grep "\(^C:.*\|W:.*\)" | sort | uniq -c | sort -n
      1 C:Naming/FileName:
      1 C:Style/MixinUsage:
      4 C:Style/GlobalVars:

Seeing that in the above codebase, using global variables, I can:

  • correct those offenses
  • avoid using that pattern in the future
  • look up better ways to solve instead of causing an offense
  • discuss with the team better solutions
  • if it’s important to have that offense, just turn that rule off

Those are all habits of better development considerations: improving style. Working code is binary. Style of working code is subjective.

Conclusion

I love having rubocop auto-correct errors and doing simple styling changes for the whole Ruby codebase so those small things are consistent without additional effort from the team.

In cases where auto-correct does not work, feeding rubocop’s output into UNIX utilities help us find the greatest class of offenders.

By having a list of offenders with their frequency in this specific Ruby codebase, it provides information and direction to start thinking addressing larger problems.

At the end, the codebase’s style will improve by being more consistent and having fewer offenses.