Salud to Dev.to community! A couple of weeks back I have posted first time here in Dev.to
, motivating myself to post articles about Ruby, Rails, Javascript and Development in general.
Today's short write up will be to run Rubocop only on changed files and creating binstubs.
When starting a project, setting up and following style guides is pretty easy. However, when we inherit a legacy codebase or try to apply them on already existing medium to large scale applications, we quickly get frustrated as there are already hundreds if not thousands of failures that we have to fix.
A better way to do this is to progressively run robocop as we continue with our development. Each time you touch part of your codebase, Rubocop will only analyze and lint the given changed files.
So, let's start.
First, we will have to create a custom binstub
to run Rubocop instead of default rubocop
command. Then we will be writing logic inside the binstub
to find changed files using git
and apply robocop
on them.(Aneeta has a handy article about this here)
To create a binstub
Bundler provides bundler --binstubs gemname
but we will not need any of the boilerplate, so let's just create an empty file named rubocop
in our bin/
directory.
Once, we have created the file, we will have to write logic to compare current changes to the master branch(or the branch of your choice) as below:
#!/usr/bin/env ruby
# frozen_string_literal: true
class RubocopRunner
COMPARE_TO_BRANCH = 'master'
def self.check_branch_validity
current_branch = `git branch | grep \\* | cut -d ' ' -f2`.strip
if current_branch.empty? || current_branch == COMPARE_TO_BRANCH
puts "No git found, or you are still on #{COMPARE_TO_BRANCH} branch."
exit 0
end
end
def self.check_non_committed_changes
system("git ls-files -m | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs bundle exec rubocop #{ARGV.join(' ')}")
end
def self.check_committed_changes
system("git diff-tree -r --no-commit-id --name-only head origin/master | xargs bundle exec rubocop #{ARGV.join(' ')}")
end
end
RubocopRunner.check_branch_validity
RubocopRunner.check_non_committed_changes
RubocopRunner.check_committed_changes
Now we can run bundle exec bin/rubocop
and see it only apply on changed files. And don't forget to add your .rubocop.yml
configuration file to root directory of your project.
Hope it helps, and let me know if there is anything that does not work as expected!
See you soon!
Top comments (2)
You could use github.com/AtakamaLLC/lint-diffs, which works with any languages in your repo, in addition to ruby, (even bash scripts and README files), and works with any type of source control.
Thank you so much for this, exactly what I was looking for to introduce Rubocop on an existing project!