class DiffCop

Constants

VERSION

Attributes

lint_results[RW]
patches[RW]
raw_lint_results[RW]

Public Instance Methods

print!() click to toggle source

take the generated lint results and print the relevant offenses to stdout (CLI)

start() click to toggle source

generate patches, run the linter and filter to only relevant results

# File lib/diff_cop.rb, line 9
def start
  @patches = generate_patches.group_by(&:file)
  @raw_lint_results = parsed_raw_lint_results(patches.keys)
  @lint_results = filter_raw_lint_results(
    raw_lint_results['files'] || [],
    patches
  )

  self
end

Private Instance Methods

diff_output() click to toggle source

get git diff output for staged files A or M filtered with .rb or .rake extensions

# File lib/diff_cop.rb, line 46
def diff_output
  `
    git diff \
      --diff-filter=AM \
      --ignore-space-at-eol \
      --no-color \
      --cached \
      -p \
      -- '*.rb' '*.rake'
  `
end
filter_raw_lint_results(raw_lint_results, all_patches) click to toggle source

[{

path: ...,
offenses: []

}]

[]<GitDiffParser::Patch>

# File lib/diff_cop.rb, line 105
def filter_raw_lint_results(raw_lint_results, all_patches)
  raw_lint_results.inject({}) do |memo, result|
    file_patches = all_patches.fetch(result['path'])

    relevant_offenses = result['offenses'].select do |offense|
      offense['patch'] =
        find_patch_for_line_number(file_patches, offense['location']['line'])
    end

    memo[result['path']] = relevant_offenses if relevant_offenses.any?
    memo
  end
end
find_patch_for_line_number(file_patches, line_number) click to toggle source

find the patch in the provided list which contains the line number provided

# File lib/diff_cop.rb, line 77
def find_patch_for_line_number(file_patches, line_number)
  file_patches.detect do |patch|
    patch.changed_line_numbers.include?(line_number)
  end
end
generate_messages() click to toggle source
# File lib/diff_cop.rb, line 83
  def generate_messages
    @lint_results.flat_map do |(file_path, offenses)|
      offenses.
        group_by { |o| o['location']['line'] }.
        map do |(line_no, line_offenses)|
          line_content = get_line_content(line_offenses.first['patch'], line_no)
          <<-MSG
#{file_path}:#{line_no}:

    #{line_content}
    #{line_offenses.map { |o| o['message'] }.join("\n    ")}
          MSG
        end
    end
  end
generate_patches() click to toggle source
# File lib/diff_cop.rb, line 58
def generate_patches
  GitDiffParser.parse(diff_output)
end
get_line_content(patch, line_number) click to toggle source

get the line content from the patch containing the provided line number

# File lib/diff_cop.rb, line 69
def get_line_content(patch, line_number)
  patch.
    changed_lines.
    detect { |line| line.number == line_number }.
    instance_variable_get(:@content)
end
parsed_raw_lint_results(files) click to toggle source

json-parsed rubocop results

# File lib/diff_cop.rb, line 63
def parsed_raw_lint_results(files)
  return {} unless files.any?
  JSON.parse(`rubocop -R #{files.join(' ')} --format json`)
end