Reputation: 10009
I have created spec/lint/rubocop_spec.rb which runs Rubocop style checker on the files changed between current branch and master. This works when I test locally but not when the test run on the build server Circle.ci.
I suspect it is because only the branch in question is downloaded, so it does not find any differences between master. Is there a better way than git co master && git pull origin master
?
Can I query the Github API perhaps to get the files changed listed?
require 'spec_helper'
describe 'Check that the files we have changed have correct syntax' do
before do
current_sha = `git rev-parse --verify HEAD`.strip!
files = `git diff master #{current_sha} --name-only | grep .rb`
files.tr!("\n", ' ')
@report = 'nada'
if files.present?
puts "Changed files: #{files}"
@report = `rubocop #{files}`
puts "Report: #{@report}"
end
end
it { @report.match('Offenses').should_not be true }
end
Upvotes: 16
Views: 16328
Reputation: 71
If someone finds this thread because Rubocop is running slow for them locally, make sure you have not turned off Rubocop's default caching. For some reason my .rubocop.yml
file had UseCache: false
and once I deleted that line linting time improved 10x (from ~30s to ~3s).
Upvotes: 0
Reputation: 523
Maybe you could leverage CircleCI’s dynamic configuration feature.
There is a specific guide on how to execute specific workflows or steps based on which files are modified (https://circleci.com/docs/using-dynamic-configuration/#execute-specific-workflows-or-steps-based-on-which-files-are-modified).
Upvotes: 0
Reputation: 6628
One simpler solution:
git diff origin/master --name-only | xargs rubocop --force-exclusion
Explanation: I rarely have master
up to date locally, but doing git fetch
updates origin/master
so I want to diff against that. I can't get the other proposed solutions with diff-tree
and origin/master
to work.
Upvotes: 5
Reputation: 4506
You don't have to use github api, or even ruby (unless you want to wrap the responses) you can just run:
git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | xargs rubocop --force-exclusion
see http://www.red56.uk/2017/03/26/running-rubocop-on-changed-files/ for longer write-up of this
Upvotes: 13
Reputation: 21
I don't have high enough reputation to comment on an answer, so I am posting an answer to add a refinement I found useful:
git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} HEAD | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs bundle exec rubocop --force-exclusion
The addition of --force-exclusion
makes RuboCop respect the Exclude declarations in its config file (here using the default ./.rubocop.yml
). You put those declarations in for a reason, right?! ;)
Upvotes: 2
Reputation: 737
Here's another alternative that compares the current branch to origin/master
(should work with any repo hosting - just tried it on circleci with a bitbucket repo). It also passes a .rubocop.yml
config file option (you can remove that part if you don't need it).
require 'spec_helper'
RSpec.describe 'Check that the files we have changed have correct syntax' do
before do
current_sha = 'origin/master..HEAD'
@files = `git diff-tree --no-commit-id --name-only -r #{current_sha} | grep .rb`
@files.tr!("\n", ' ')
end
it 'runs rubocop on changed ruby files' do
if @files.empty?
puts "Linting not performed. No ruby files changed."
else
puts "Running rubocop for changed files: #{@files}"
result = system "bundle exec rubocop --config .rubocop.yml --fail-level warn #{@files}"
expect(result).to be(true)
end
end
end
Original gist here: https://gist.github.com/djburdick/5104d15f612c15dde65f#gistcomment-2029606
Upvotes: 1
Reputation: 1719
I found https://github.com/m4i/rubocop-git which works very well. However it works on your git diff (optionally with --cached) so it does not allow you to compare branches.
Upvotes: 4
Reputation: 10009
I fixed it by querying api.github.com. This will run rubocop on all files that has been changed between current_sha and the master branch.
require 'spec_helper'
describe 'Check that the files we have changed have correct syntax' do
before do
current_sha = `git rev-parse --verify HEAD`.strip!
token = 'YOUR GITHUB TOKEN'
url = 'https://api.github.com/repos/orwapp/orwapp/compare/' \
"master...#{current_sha}?access_token=#{token}"
files = `curl -i #{url} | grep filename | cut -f2 -d: | grep \.rb | tr '"', '\ '`
files.tr!("\n", ' ')
@report = 'nada'
if files.present?
puts "Changed files: #{files}"
@report = `rubocop #{files}`
puts "Report: #{@report}"
end
end
it { expect(@report.match('Offenses')).to be_falsey }
end
Upvotes: 5