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.
This gem provides features such as:
-
An index of the project files with their respective number of smells:
-
When analysing code like the following:
class Dirty
def awful(x, y)
if y
@screen = widgets.map {|w| w.each {|key| key += 3}}
end
end
end
It basically turns something like this:
Into something like this:
-
It uses your source control system (only Git, Mercurial and Perforce are currently supported) to compare your currently uncommitted changes with your last commit.
Warning: If your code is not as you expect it to be after running RubyCritic, please check your source control system stash.
Checkout the /docs
if you want to read more about our core metrics.
RubyCritic can be installed with the following command:
$ gem install rubycritic
If you'd rather install RubyCritic using Bundler, add this line to your application's Gemfile:
gem "rubycritic", require: false
And then execute:
$ bundle
Running rubycritic
with no arguments will analyse all the Ruby files in the
current directory:
$ rubycritic
Alternatively you can pass rubycritic
a list of files and directories.
The analysis will be scoped to the provided files and directories:
$ rubycritic app lib/foo.rb
For a full list of the command-line options run:
$ rubycritic --help
Command flag | Description |
---|---|
-v / --version |
Displays the current version and exits |
-p / --path |
Set path where report will be saved (tmp/rubycritic by default) |
--coverage-path |
Set path where SimpleCov will be saved (./coverage by default) |
-f / --format |
Report smells in the given format(s)1 |
--custom-format path:classname |
Load and instantiate custom formatter(s)2 |
-s / --minimum-score |
Set a minimum score (FLOAT: ex: 96.28), default: 0 |
-m / --mode-ci |
Use CI mode3 |
-b / --branch |
Set branch to compare |
-t / --maximum-decrease |
Threshold for score difference between two branches4 |
--deduplicate-symlinks |
De-duplicate symlinks based on their final target |
--suppress-ratings |
Suppress letter ratings |
--no-browser |
Do not open html report with browser |
- Available output formats:
html
(default; will open in a browser)json
console
lint
- See custom formatters docs
- Faster, analyses diffs w.r.t base_branch (default: main), see
-b
- Works only with
-b
, default: 0
You also can use a config file. Just create a .rubycritic.yml
on your project root path.
Here are one example:
mode_ci:
enabled: true # default is false
branch: 'production' # default is main
branch: 'production' # default is main
path: '/tmp/mycustompath' # Set path where report will be saved (tmp/rubycritic by default)
coverage_path: '/tmp/coverage' # Set path where SimpleCov coverage will be saved (./coverage by default)
threshold_score: 10 # default is 0
deduplicate_symlinks: true # default is false
suppress_ratings: true # default is false
no_browser: true # default is false
formats: # Available values are: html, json, console, lint. Default value is html.
- console
minimum_score: 95 # default is 0
paths: # Files to analyse. Churn calculation is scoped to these files when using Git SCM.
- 'app/controllers/'
- 'app/models/'
Reek
:RubyCritic
utilizesReek
's default configuration loading mechanism. This means that if you have an existingReek
configuration file, you can just put this into your project root andRubyCritic
will respect this configuration.flay
: We useflay
's default configuration.flog
: We useflog
's default configuration with a couple of smaller tweaks:all
: Forcesflog
to report scores on all classes and methods. Without this optionflog
will only give results up to a certain threshold.continue
: Makes it so thatflog
does not abort when a ruby file cannot be parsed.methods
: Configuresflog
to skip code outside of methods. It preventsflog
from reporting on the "methods"private
andprotected
. It also preventsflog
from reporting on Rails methods likebefore_action
andhas_many
.
If you're fond of Guard you might like guard-rubycritic. It automatically analyses your Ruby files as they are modified.
For continuous integration, you can give Jenkins CI a spin. With it, you can easily build your own (poor-man's) Code Climate!
You can use RubyCritic as Rake command in its most simple form like this:
require "rubycritic/rake_task"
RubyCritic::RakeTask.new
A more sophisticated Rake task that would make use of all available configuration options could look like this:
RubyCritic::RakeTask.new do |task|
# Name of RubyCritic task. Defaults to :rubycritic.
task.name = 'something_special'
# Glob pattern to match source files. Defaults to FileList['.'].
task.paths = FileList['vendor/**/*.rb']
# You can pass all the options here in that are shown by "rubycritic -h" except for
# "-p / --path" since that is set separately. Defaults to ''.
task.options = '--mode-ci --format json'
# Defaults to false
task.verbose = true
# Fail the Rake task if RubyCritic doesn't pass. Defaults to true
task.fail_on_error = true
end
RubyCritic will try to open the generated report with a browser by default. If you don't want this you can prevent this behaviour by setting the options correspondingly:
RubyCritic::RakeTask.new do |task|
task.options = '--no-browser'
end
If you wish to create multiple Rake tasks (e.g., for local & for ci-specific configuration), you can do so! If you decide to do this, you should provide a clearer description for each task:
# for local
RubyCritic::RakeTask.new("local", "Run RubyCritic (local configuration)" do |task|
# ...
end
# for CI
RubyCritic::RakeTask.new("ci", "Run RubyCritic (CI configuration)" do |task|
task.options = "--mode-ci"
# ...
end
See formatters
RubyCritic is supporting Ruby versions:
Ruby version | Latest RubyCritic version |
---|---|
2.4 | v4.7.0 |
2.5 | v4.7.0 |
2.6 | v4.7.0 |
2.7 | v4.9.x |
3.0 | latest |
3.1 | latest |
3.2 | latest |
3.3 | latest |
RubyCritic doesn't have to remain a second choice to other code quality analysis services. Together, we can improve it and continue to build on the great code metric tools that are available in the Ruby ecosystem.
Arguably, the better_errors gem only got popular after receiving a (pretty awesome) Pull Request that changed its page design.
Similarly, Pull Requests that improve the look and feel of the gem, that tweak the calculation of ratings or that fix existing issues will be most welcome. Just commenting on an issue and giving some insight into how something should work will be appreciated. No contribution is too small.
See RubyCritic's contributing guidelines about how to proceed.
RubyCritics
initial author was Guilherme Simões.
The current core team consists of:
RubyCritic is maintained and funded by Whitesmith. Tweet your questions or suggestions to @Whitesmithco.