Class: Audition::Baseline

Inherits:
Object
  • Object
show all
Defined in:
lib/audition/baseline.rb

Overview

Incremental-adoption ledger (.audition-baseline.json): known findings recorded as counts per "check|relative/path" so line drift never invalidates it. Present findings up to the recorded count are hidden; anything beyond is new and fails as usual.

Constant Summary collapse

FILE =
".audition-baseline.json"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(counts) ⇒ Baseline

Returns a new instance of Baseline.



42
43
44
# File 'lib/audition/baseline.rb', line 42

def initialize(counts)
  @counts = counts
end

Class Method Details

.key(finding, root) ⇒ Object



36
37
38
39
40
# File 'lib/audition/baseline.rb', line 36

def self.key(finding, root)
  relative =
    finding.path.to_s.delete_prefix("#{root}/")
  "#{finding.check}|#{relative}"
end

.load(root) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/audition/baseline.rb', line 27

def self.load(root)
  path = path_for(root)
  return nil unless File.file?(path)

  new(JSON.parse(File.read(path)))
rescue JSON::ParserError => e
  raise Error, "#{path}: #{e.message}"
end

.path_for(root) ⇒ Object



13
14
15
# File 'lib/audition/baseline.rb', line 13

def self.path_for(root)
  File.join(root.to_s, FILE)
end

.write(root, findings) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/audition/baseline.rb', line 17

def self.write(root, findings)
  counts = Hash.new(0)
  findings.each { |f| counts[key(f, root)] += 1 }
  File.write(
    path_for(root),
    JSON.pretty_generate(counts.sort.to_h) << "\n"
  )
  counts.values.sum
end

Instance Method Details

#filter(findings, root:) ⇒ Array(Array<Finding>, Integer)

Budget per key is consumed in finding order.

Parameters:

  • findings (Array<Finding>)
  • root (String)

    target root for relative paths

Returns:

  • (Array(Array<Finding>, Integer))

    visible findings and the hidden count



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/audition/baseline.rb', line 52

def filter(findings, root:)
  budget = @counts.dup
  hidden = 0
  visible = findings.reject do |finding|
    key = self.class.key(finding, root)
    next false unless budget.fetch(key, 0).positive?

    budget[key] -= 1
    hidden += 1
    true
  end
  [visible, hidden]
end