Last active
October 6, 2015 13:40
-
-
Save pointlessone/cfc46820a01db1222f54 to your computer and use it in GitHub Desktop.
Rubocop pre-commit check
This file contains hidden or 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
# 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 |
This file contains hidden or 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
#!/bin/sh | |
DIR=$(dirname $0) | |
echo $DIR | |
for f in $0.*; do | |
echo $f | |
if [[ -x $f ]]; then | |
$f || exit $? | |
fi | |
done |
This file contains hidden or 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 | |
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