class Danger::DangerWCC::RubocopExceptions

Constants

COMMENT_LINE_REGEX
DISABLE_REGEX
ENABLE_REGEX

Public Class Methods

new(plugin, options = {}) click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 13
def initialize(plugin, options = {})
  @plugin = plugin
  @options = options
end

Public Instance Methods

perform() click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 18
def perform
  find_new_exceptions.each do |e|
    message = build_message(e)
    severity = message_severity(e)
    issue(message,
          severity: severity, file: e[:file], line: e[:disabled_at])
  end
end

Private Instance Methods

build_message(e) click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 29
def build_message(e)
  message = "Rubocop rule #{e[:rule]} disabled in"\
              " #{plugin.github.html_link(e[:file])}"
  message +=
    if !e[:context_lines].empty?
      "  explanation:\n\t> " + e[:context_lines].join("\n\t> ")
    else
      "  \nPlease provide an explanation why this rule was disabled."
    end
  unless e[:inline] || e[:reenabled]
    message += "\n\nThe rule was not reenabled!\n"\
      'Please add a `rubocop:enable` comment so the rule is disabled '\
      'for the minimal scope.'
  end
  message
end
find_context(diff_lines) click to toggle source

rubocop:enable Metrics/AbcSize

# File lib/wcc/rubocop_exceptions.rb, line 81
def find_context(diff_lines)
  # search for all non-`rubocop:` comment lines immediately
  # preceding this disable which were added by this hunk
  diff_lines
    .drop_while { |l| rubocop_line?(l) }
    .take_while { |l| l.addition? && l.content =~ COMMENT_LINE_REGEX }
    .map { |l| l.content.match(COMMENT_LINE_REGEX).captures[0] }
end
find_new_exceptions() click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 56
def find_new_exceptions
  find_in_diff(DISABLE_REGEX) do |m, line, hunk, file, _diff|
    make_violation(File.read(file.b_path), hunk, line, m.captures[0])
      .merge!(file: file.b_path)
  end
end
find_reenable(file_contents, line_number, rule) click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 90
def find_reenable(file_contents, line_number, rule)
  # search for the reenabling of this line
  length_to_end = file_contents.lines.length - line_number
  file_contents.lines[line_number, length_to_end]
    .find_index do |l|
      m = l.match(ENABLE_REGEX)
      !m.nil? && rule.casecmp(m.captures[0]) == 0
    end
end
make_violation(file_contents, hunk, line, rule) click to toggle source

rubocop:disable Metrics/AbcSize

# File lib/wcc/rubocop_exceptions.rb, line 64
def make_violation(file_contents, hunk, line, rule)
  is_inline_comment = !/^\s*\+?\s*\#/.match(line.content)

  reenable_line_offset = find_reenable(file_contents,
                                       line.line_number.right,
                                       rule)

  {
    rule: rule,
    disabled_at: line.line_number.right,
    inline: is_inline_comment,
    reenabled: !reenable_line_offset.nil?,
    context_lines: find_context(hunk.lines.drop(hunk.lines.index(line)))
  }
end
message_severity(e) click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 46
def message_severity(e)
  if !e[:inline] && !e[:reenabled]
    'fail'
  elsif e[:context_lines].empty?
    'warn'
  else
    'message'
  end
end
rubocop_line?(l) click to toggle source
# File lib/wcc/rubocop_exceptions.rb, line 100
def rubocop_line?(l)
  l.content =~ DISABLE_REGEX || l.content =~ ENABLE_REGEX
end