-
-
Save brand-it/619a9788e277b6699bbf5bed16bd9462 to your computer and use it in GitHub Desktop.
Ruby style guide git pre-commit hook using Rubocop as the style guide checker. Only runs on staged ruby files that have been added and/or modified.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# frozen_string_literal: true | |
require 'json' | |
def files | |
@files ||= begin | |
`git diff --staged --name-only --cached`.split("\n").reject do |file| | |
!File.exists?(file) | |
end | |
end | |
end | |
def rubocop | |
@rubocop ||= JSON.parse( | |
`bundle exec rubocop --parallel --force-exclusion --format json #{files.join(' ')}`, | |
symbolize_names: true | |
) | |
end | |
def violations | |
rubocop[:files].select { |x| x[:offenses].any? } | |
end | |
def format_violations | |
violations.each do |violation| | |
violation[:offenses].each do |offense| | |
puts "#{violation[:path]}:#{offense.dig(:location, :line)}:#{offense.dig(:location, :column)} #{offense[:cop_name]} #{offense[:message]}\n" | |
end | |
end | |
puts "\n\n#{rubocop.dig(:summary, :inspected_file_count)} file inspected, #{rubocop.dig(:summary, :offense_count)} offense detected" | |
end | |
def success(message) | |
puts message | |
exit 0 | |
end | |
def rubocop_autocorrect | |
`bundle exec rubocop -A #{files.join(' ')}` | |
end | |
def waiting | |
index = 0 | |
chars = %w[| / - \\] | |
while @rubocop.nil? | |
print "rubocop analyzing ... #{chars[(index += 1) % chars.length]}\r" | |
sleep(1) | |
end | |
puts 'rubocop analyzing ... done' | |
end | |
success('no file to check') if files.size.zero? | |
[].tap do |threads| | |
threads << Thread.new { rubocop } | |
threads << Thread.new { waiting } | |
threads.map(&:join) | |
end | |
exit true if violations.empty? | |
format_violations | |
# Open input from keyboard usin IO.new(0) normal standard in is closed | |
fd = IO.sysopen '/dev/tty', 'r' | |
ios = IO.new(fd, 'r') | |
print 'Do you want to fix and exit?(Y) ' | |
if ios.gets.chomp == 'Y' | |
rubocop_autocorrect | |
exit 1 | |
end | |
print 'Do you want to commit anyway?(Y) ' | |
exit ios.gets.chomp == 'Y' |
The only thing I change from the original was turning on the auto correct flag. I wanted this to fix the silly things like spaces and other peace that I know Rubocop can do. Something to note however checks your PR because it is an automated tool, but you never know.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add to
.git/hooks/pre-commit
This will auto correct for you as well. Most of the time is simple things right.