How to integrate rubocop with Rake?

2019-03-17 08:24发布

问题:

rubocop is a code style checker for Ruby. A similar tool to rubocop, Cane, can be integrated with Rake. I prefer rubocop to Cane since rubocop makes checks based on the Ruby Style Guide and it seems to spot more problems. To automate the process of style checking I would like to integrate rubocop with Rake so that the build fails if code quality is lacking.

Gem already supports adding tests to packages via Rake. I would like to do the same with style checks so that style checks are run along with the tests. How can I do this?

If it helps to start with a Rakefile here is one:

# -*- coding: utf-8; mode: ruby -*-

require 'bundler/gem_tasks'
require 'rake/testtask'

Rake::TestTask.new do |t|
  t.libs << 'test'
  t.test_files = FileList['test/unit/test*.rb']
end

desc 'Run tests'
task default: :test

回答1:

I would recommend shelling out to the rubocop program. It's the simplest solution. Just add this to your Rakefile:

task test: :rubocop

task :rubocop do
  sh 'rubocop'
end


回答2:

As of version 0.10.0 rubocop contain a custom rake task that you can use. Just put the following in your Rakefile

require 'rubocop/rake_task'

RuboCop::RakeTask.new

Make sure to use upper-case 'R' and 'C' or you will get a NameError.



回答3:

I highly recommend,

require 'rubocop/rake_task'

RuboCop::RakeTask.new(:rubocop) do |t|
  t.options = ['--display-cop-names']
end

This uses the rubocop's own rake tasks and allows you to pass options if you like.



回答4:

You will probably find https://github.com/yujinakayama/guard-rubocop useful if you use Guard for your RSpec tests. It enables Rubocop to give you instant feedback as soon as you save the file, along with your test results.



回答5:

You can shell out via Rake with the options you prefer:

  desc 'Run Rubocop with options'
  task rubocop: :environment do
    sh 'bundle exec rubocop -D --format offenses --format progress || true'
  end

I then recommend modifying the default task to include the output. The trick is to clear the task and then add back what you want. Note the need to end with || true so that an error from Rubocop will not prevent the next task from running. Here's what I do, which also uses parallel tests:

task(:default).clear.enhance ['parallel:parallel_prepare', 'parallel:spec',
                              'parallel:features', 'lint:rubocop',
                              'lint:rails_best_practices']