Skip to content

Instantly share code, notes, and snippets.

@brand-it
Forked from mpeteuil/rubocop_pre_commit_hook
Last active July 21, 2020 15:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brand-it/619a9788e277b6699bbf5bed16bd9462 to your computer and use it in GitHub Desktop.
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.
#!/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'
@brand-it
Copy link
Author

Add to .git/hooks/pre-commit This will auto correct for you as well. Most of the time is simple things right.

@brand-it
Copy link
Author

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