Class: Necropsy::Guardrail::Quarantine

Inherits:
Object
  • Object
show all
Defined in:
lib/necropsy/guardrail/quarantine.rb

Constant Summary collapse

ANNOTATION_PREFIX =
'# necropsy:quarantine'

Instance Method Summary collapse

Constructor Details

#initialize(report:, root:) ⇒ Quarantine

Returns a new instance of Quarantine.



10
11
12
13
# File 'lib/necropsy/guardrail/quarantine.rb', line 10

def initialize(report:, root:)
  @report = report
  @root = root
end

Instance Method Details

#suggestions(min_confidence: :high) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/necropsy/guardrail/quarantine.rb', line 15

def suggestions(min_confidence: :high)
  report.dead_methods(min_confidence: min_confidence).map do |finding|
    {
      finding: finding,
      annotation: "#{ANNOTATION_PREFIX} since=#{Date.today.iso8601}",
      path: File.join(root, finding.node.file),
      line: finding.node.line
    }
  end
end

#write(min_confidence: :high) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/necropsy/guardrail/quarantine.rb', line 26

def write(min_confidence: :high)
  grouped = suggestions(min_confidence: min_confidence).group_by { |suggestion| suggestion[:path] }
  grouped.each do |path, entries|
    source = File.binread(path)
    newline = source[/\r\n|\n/] || "\n"
    trailing_newline = source.end_with?("\r\n", "\n")
    lines = source.split(/\r\n|\n/, -1)
    lines.pop if trailing_newline
    entries.sort_by { |entry| -entry[:line] }.each do |entry|
      index = [entry[:line] - 1, 0].max
      next if index.positive? && lines[index - 1]&.include?(ANNOTATION_PREFIX)

      indent = lines[index][/^\s*/] || ''
      lines.insert(index, "#{indent}#{entry[:annotation]}")
    end
    rewritten = lines.join(newline)
    rewritten << newline if trailing_newline
    File.binwrite(path, rewritten)
  end
end