Skip to content

Instantly share code, notes, and snippets.

@zeisler
Last active April 27, 2021 20:28
Show Gist options
  • Save zeisler/65f1cecad37f8683abb3775109bc3503 to your computer and use it in GitHub Desktop.
Save zeisler/65f1cecad37f8683abb3775109bc3503 to your computer and use it in GitHub Desktop.
rubocop git hook
#!/usr/bin/env ruby
require "fileutils"
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'tty-command'
end
def check!(project_root, git_root, force_exit = false, rubocop_format = 'fu')
Bundler.with_clean_env do
Dir.chdir(project_root) do
require 'tty-command'
cmd = TTY::Command.new(pty: true, printer: :quiet)
result = cmd.run!("bundle exec rubocop -f #{rubocop_format} --cache true #{ARGV.join { ' ' }}")
pid = fork do
if result.status.zero?
hook_dir = File.join(git_root, ".git/hooks")
Dir.mkdir(hook_dir) unless Dir.exist?(hook_dir)
make_bash_file(project_root, "#{hook_dir}/pre-commit", "\u001b[32mRubocop is passing\u001b[0m", 0)
make_bash_file(project_root, "#{hook_dir}/pre-push", "\u001b[32mRubocop is passing\u001b[0m", 0)
cmd = TTY::Command.new(pty: true, printer: :null)
cmd.run!("dir-fingerprint -q #{project_root}")
else
hook_dir = File.join(git_root, ".git/hooks")
Dir.mkdir(hook_dir) unless Dir.exist?(hook_dir)
make_bash_file(project_root, "#{hook_dir}/pre-commit", result.out, 0)
make_bash_file(project_root, "#{hook_dir}/pre-push", result.out, 1)
end
end
Process.detach(pid)
exit result.status
end
end
end
def make_bash_file(project_root, path, msg, exit)
directories = "."
Dir.chdir(project_root) do
directories = Dir.glob("./**/*.rb").map { |f| File.dirname(f).split("/")[1] }.uniq.join(" ")
end
ruby_file = <<~RUBY_FILE
#!/usr/bin/env ruby
results = ""
Dir.chdir('#{project_root}') do
results = `dir-fingerprint -q -files #{directories}`.chomp.split("\\n")[3]
end
if results.include?("true")
puts "\u001b[33mRubocop out of date\u001b[0m"
system("RUBOCOP_FORMAT='p' rubocop!")
exit $?.exitstatus
else
puts <<~RUBOCOP_OUTPUT
#{msg.gsub("\r", " ")}
RUBOCOP_OUTPUT
exit #{exit}
end
RUBY_FILE
File.open(path, 'w') do |file|
file.write(ruby_file)
end
FileUtils.chmod("+x", path)
end
check! ENV["DIR"] || `pwd`.chomp, ENV["GIT_ROOT"] || `git rev-parse --show-toplevel`.chomp, ENV["FORCE_EXIT"], ENV["RUBOCOP_FORMAT"] || 'p'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment