Skip to content

Instantly share code, notes, and snippets.

@pointlessone
Last active October 6, 2015 13:40
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pointlessone/cfc46820a01db1222f54 to your computer and use it in GitHub Desktop.
Save pointlessone/cfc46820a01db1222f54 to your computer and use it in GitHub Desktop.
Rubocop pre-commit check
# Installation
Put these files in your `.git/hooks` directory and make them executable.
# Changelog
## 1.2
* Check for RuboCop updates
## 1.1
* Fixed affected line detection
* Viloations are now sorted by line number
## 1.0
Initial release
#!/bin/sh
DIR=$(dirname $0)
echo $DIR
for f in $0.*; do
echo $f
if [[ -x $f ]]; then
$f || exit $?
fi
done
#!/usr/bin/env ruby
require 'net/http'
require 'english'
require 'shellwords'
require 'tmpdir'
require 'rubocop'
def check_version
uri = URI.parse("https://rubygems.org/api/v1/versions/rubocop/latest.json")
data = JSON.parse(Net::HTTP.get(uri))
if RuboCop::Version::STRING < data["version"]
puts "A newer version of RuboCop is available!",
" Your version: #{RuboCop::Version::STRING}",
" New version: #{data["version"]}"
end
end
RUBOCOP_CONFIG_STORE = RuboCop::ConfigStore.new
def style_violations(file_name, lines)
Dir.mktmpdir "rubocop" do |dir|
# Check out staged version of a file
`git checkout-index --prefix='#{dir}/' '#{file_name}'`
rubocop = RuboCop::Cop::Team.new(RuboCop::Cop::Cop.all, RUBOCOP_CONFIG_STORE.for(file_name))
parsed_source = RuboCop::ProcessedSource.new(File.read("#{dir}/#{file_name}"), file_name)
offenses = rubocop.inspect_file(parsed_source)
offenses.select do |o|
lines.include?(o.line) || [:error, :fatal].include?(o.severity.name)
end.sort_by(&:line)
end
end
def changed_files
`git status --porcelain`.split(/\n/)
.select { |file_name_with_status|
['A', 'M'].include? file_name_with_status[0]
}
.map { |file_name_with_status|
file_name_with_status.shellsplit[1]
}
.select { |file_name|
['.rb', '.rake'].include? File.extname(file_name)
}
end
def report
@report ||= {}.tap do |offenses|
changed_files.each do |file|
diff = `git diff -U0 --staged '#{file}'`
n = 0
hunk = false
lines = []
diff.split("\n").each do |line|
if m = /^@@ -\d+(,\d+)? \+(?<line>\d+)(,\d+)? @@/.match(line)
n = m[:line].to_i
hunk = true
elsif /^\+/.match(line) && hunk
lines << n
n += 1
end
end
offenses[file] = style_violations(file, lines)
end
end
end
check_version
if report.any?
formatter = RuboCop::Formatter::ClangStyleFormatter.new(STDOUT)
formatter.started(report.keys)
report.each do |file, offenses|
formatter.file_finished(file, offenses)
end
formatter.finished(report.keys)
end
# Only complain but don't block the commit
exit 0 # $CHILD_STATUS.to_s[-1].to_i
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment