Review of Ruby Static Analysis Tools
Having trouble deciding which tool to use for Ruby Static Analysis, or perhaps unsure whether you found the most common ones? Here’s a small list that may be helpful:
The available cops include: Style, Lint, Metrics and Rails (which, as you may have guessed, is targeted at Rails applications).
Accordingly, cops detect offenses. With the following sample code:
def camelMethod puts "This line has 3 spaces indentation" end
Rubocop would display the following output:
code.rb:1:5: C: Use snake_case for method names. def camelMethod ^^^^^^^^^^^ code.rb:2:1: C: Use 2 (not 3) spaces for indentation. puts "This line has 3 spaces indentation" ^^^ code.rb:2:9: C: Prefer single-quoted strings when you don't need string interpolation or special symbols. puts "This line has 3 spaces indentation" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 file inspected, 3 offenses detected
You can enable/disable specific cops and alter their behaviour, namely severity-wise. Speaking of which, there are four types of severities: convention, warning, error, and fatal.
There’s also a cache mechanism to deal with huge projects when you’ve only modified a couple of files.
Rubocop integrates with several editors.
Reek detects code smells.
Bad smells are the symptoms that may (but not necessarily do) indicate a deeper problem.
Reek includes checks for several aspects, including Control Couple, Data Clump, Feature Envy, Large Class, Long Parameter List, Simulated Polymorphism, Too Many Statements, Uncommunicative Name, Unused Parameters and more (see Code Smell for more details).
Here's an example of Reek's output:
code.rb -- 1 warning: :UncommunicativeMethodName: camelMethod has the name 'camelMethod' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
The configuration is based on a file in the project directory, but specific smells can be suppressed for specific methods or classes, or even only suppressed until a certain threshold is reached.
It does make sense; if you had a bowl of cooked rice you wouldn’t say the dish smelled bad because of one roasted grain, but if you had too many of those that would probably spark a smell alert. Similarly, an instance wouldn’t smell, but you could set up a limit to how many would.
Every smell has some basic options that allow you to enable detection or exclude parts of the project.
I’m including Brakeman on the list even though it is a very different tool than the other ones here, but there’s a reason for this.
Brakeman is a vulnerability scanner for Ruby on Rails applications; however, it runs on code, not on the website itself, meaning that you don’t need to set up your web server to run the tool, and you can start using it from day one, just as you’re writing your first lines of code.
Since it parses the code itself, Brakeman will not catch problems related to the database or the web server itself but, on the other hand, the tool is capable of finding problems before they become exploitable.
It includes a plugin for Hudson/Jenkins and, as many other tools, it separates issues in different levels: high, medium and weak.
Which one should I use?
As with any other list of tools, it boils down to a matter of personal choice, although for some scenarios there are some clean winners.
If you’re going for vulnerabilities in Rails, you should definitely check Brakeman. If you’re trying to keep your code clean and according to the community guidelines (or others) then Rubocop may be the tool for you. And if you’re looking for signs of potential problems then maybe Reek is the way to go.
Also, if you’re looking for a simple and time-saving way to integrate these kinds of checks in your workflow you should definitely try Codacy. Codacy integrates Brakeman and Rubocop and even supports these tools’ configuration files. Codacy also allows you to monitor issues over time and see the impact each commit has on your code base (new issues and fixed issues). It’s a great way to make sure your code is safe and sound and also an awesome tool to bring one up to speed with a language’s best practices.
There are several Ruby Static Analysis tools, each of them with their own strengths (and many of them are complementary, not just alternatives to each others).
In fact, there are quite a few missing from this list, and some of them may be quite relevant to what you’re doing.
If there’s any other you think deserves a mention, please let me know in the comments.