Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rubocop pre commit
#!/usr/bin/env ruby
require 'rubocop'
module DirtyCop
extend self # In your face, style guide!
def bury_evidence?(file, line)
!report_offense_at?(file, line)
end
def uncovered_targets
@files
end
def cover_up_unmodified(ref, only_changed_lines = true)
@files = files_modified_since(ref)
@line_filter = build_line_filter(@files, ref) if only_changed_lines
end
def process_bribe
ref = '--staged HEAD'
only_changed_lines = true
cover_up_unmodified ref, only_changed_lines
end
private
def report_offense_at?(file, line)
!@line_filter || @line_filter.fetch(file)[line]
end
def files_modified_since(ref)
`git diff --diff-filter=AM --name-only #{ref}`.
lines.
map(&:chomp).
grep(/\.rb$/).
map { |file| File.absolute_path(file) }
end
def build_line_filter(files, ref)
result = {}
suspects = files_modified_since(ref)
suspects.each do |file|
result[file] = lines_modified_since(file, ref)
end
result
end
def lines_modified_since(file, ref)
ranges =
`git diff -p -U0 #{ref} #{file}`.
lines.
grep(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/) { $1.to_i...($1.to_i + $2.to_i) }.
reverse
mask = Array.new(ranges.first.end)
ranges.each do |range|
range.each do |line|
mask[line] = true
end
end
mask
end
end
module RuboCop
class TargetFinder
alias find_unpatched find
def find(args)
replacement = DirtyCop.uncovered_targets
return replacement if replacement
find_unpatched(args)
end
end
class Runner
alias inspect_file_unpatched inspect_file
def inspect_file(file)
offenses, updated = inspect_file_unpatched(file)
offenses = offenses.reject { |o| DirtyCop.bury_evidence?(file.path, o.line) }
[offenses, updated]
end
end
end
def print_header(header)
puts "\e[33m#{header}\e[0m"
end
failed = false
# ESLint
print_header 'Strat eslint analysis...'
`PATH="$(npm bin)":"$PATH"`
if `which eslint` == 'eslint not found'
puts 'WARNING: You need to install ESLint to lint your files (SKIP ESLint)'
else
files_js = `git diff --staged --name-only --diff-filter=d`.lines.map(&:chomp).grep(/\.coffee|\.js$/)
files_js.each do |file|
result = `git show :#{file} | eslint --stdin --stdin-filename "#{file}"`
puts result
failed = result.lines.count > 1
end
puts '[SKIPPED] Nothing to check' if files_js.empty?
end
puts "\n"
print_header 'Start Rubocop analysis...'
if DirtyCop.process_bribe.any?
failed ||= RuboCop::CLI.new.run != 0
else
puts '[SKIPPED] No ruby files changed'
end
puts "\n"
merge_branch = ENV['MERGE_BRANCH'] || 'master'
staged_diff = "git diff --staged #{merge_branch} --name-only --relative --diff-filter=d"
only_rb_without_specs = %x( #{staged_diff} | grep '\\.rb' | grep -v '_spec' ).gsub(/\n/, ' ')
print_header 'Start yaml_check analysis...'
if `which yaml_check` == 'yaml_check not found'
puts 'WARNING: You need to install yaml_check (SKIP yaml_check)'
else
i18n_files = %x( #{staged_diff} | grep '\\/config\\/locales' | grep '\\.yml' ).gsub(/\n/, ' ')
result = %x( yaml_check #{i18n_files} )
if result == ''
puts '[SKIPPED] No yaml files to check'
else
puts result
end
failed ||= result.include?('[FAILED]')
end
puts "\n"
print_header 'Start yardoc analysis...'
if `which yard` == `yard not found`
puts 'WARNING: You need to install yard (SKIP yard)'
else
if only_rb_without_specs != ''
result = %x( cd `git rev-parse --show-toplevel` && yard stats --list-undoc )
puts result
failed ||= !result.include?('100.00% documented')
else
puts '[SKIPPED] No ruby files changed'
end
end
puts "\n"
print_header 'Start flay analysis...'
if `which flay` == 'flay not found'
puts 'WARNING: You need to install flay (SKIP flay)'
else
if only_rb_without_specs != ''
result = %x( flay -v --diff #{only_rb_without_specs} )
puts result
else
puts '[SKIPPED] No ruby files changed'
end
end
puts "\n"
print_header 'Start flog analysis...'
if `which flog` == 'flog not found'
puts 'WARNING: You need to install flog (SKIP flog)'
else
if only_rb_without_specs != ''
result = %x( flog -m #{only_rb_without_specs} )
puts result
else
puts '[SKIPPED] No ruby files changed.'
end
end
puts "\n"
exit 1 if failed
exit 0
#!/usr/bin/env ruby
require 'rubocop'
module DirtyCop
extend self # In your face, style guide!
def bury_evidence?(file, line)
!report_offense_at?(file, line)
end
def uncovered_targets
@files
end
def cover_up_unmodified(ref, only_changed_lines = true)
@files = files_modified_since(ref)
@line_filter = build_line_filter(@files, ref) if only_changed_lines
end
def process_bribe
ref = '--staged HEAD'
only_changed_lines = true
cover_up_unmodified ref, only_changed_lines
end
private
def report_offense_at?(file, line)
!@line_filter || @line_filter.fetch(file)[line]
end
def files_modified_since(ref)
`git diff --diff-filter=AM --name-only #{ref}`.
lines.
map(&:chomp).
grep(/\.rb$/).
map { |file| File.absolute_path(file) }
end
def build_line_filter(files, ref)
result = {}
suspects = files_modified_since(ref)
suspects.each do |file|
result[file] = lines_modified_since(file, ref)
end
result
end
def lines_modified_since(file, ref)
ranges =
`git diff -p -U0 #{ref} #{file}`.
lines.
grep(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/) { $1.to_i...($1.to_i + $2.to_i) }.
reverse
mask = Array.new(ranges.first.end)
ranges.each do |range|
range.each do |line|
mask[line] = true
end
end
mask
end
end
module RuboCop
class TargetFinder
alias find_unpatched find
def find(args)
replacement = DirtyCop.uncovered_targets
return replacement if replacement
find_unpatched(args)
end
end
class Runner
alias inspect_file_unpatched inspect_file
def inspect_file(file)
offenses, updated = inspect_file_unpatched(file)
offenses = offenses.reject { |o| DirtyCop.bury_evidence?(file.path, o.line) }
[offenses, updated]
end
end
end
if DirtyCop.process_bribe.any?
exit RuboCop::CLI.new.run
end
# ESLint
`PATH="$(npm bin)":"$PATH"`
if `which eslint` == 'eslint not found'
puts 'WARNING: You need to install ESLint to lint your files (SKIP ESLint)'
else
failure = false
files_js = `git diff --staged --name-only --diff-filter=d`.lines.map(&:chomp).grep(/\.coffee|\.js$/)
files_js.each do |file|
result = `git show :#{file} | eslint --stdin --stdin-filename "#{file}"`
puts result if result != ''
failure = failure || result.lines.count > 1
end
exit failure ? 1 : 0
end
@thomet

This comment has been minimized.

Copy link
Owner Author

@thomet thomet commented Sep 4, 2018

Update: Rubocop now checks only changed lines instead of files

@thomet

This comment has been minimized.

Copy link
Owner Author

@thomet thomet commented Sep 4, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.