Class: Audition::Report

Inherits:
Object
  • Object
show all
Defined in:
lib/audition/report.rb,
lib/audition/report/json.rb,
lib/audition/report/text.rb,
lib/audition/report/style.rb,
lib/audition/report/sweep.rb,
lib/audition/report/github.rb

Overview

Aggregates static findings and dynamic results into a verdict and the counts the renderers work from. Rendering lives in the Report::Text, Report::Json, and Report::Github classes.

Defined Under Namespace

Classes: Github, Json, Style, Sweep, Text

Constant Summary collapse

VERDICTS =
{
  not_ready: "not ractor-ready",
  blocked: "own code is ractor-ready; blocked by dependencies",
  risky: "risky: warnings only, no hard errors",
  ready: "ractor-ready as far as Audition can tell"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_type:, target_root:, findings:, dynamic_results: [], unsafe_fixes: 0, baselined: 0) ⇒ Report

Returns a new instance of Report.

Parameters:

  • target_type (Symbol) —
  • target_root (String)
  • findings (Array<Finding>) —

    static plus dynamic findings

  • dynamic_results (Array<Dynamic::Result>) (defaults to: [])
  • unsafe_fixes (Integer) (defaults to: 0) —

    shown as the --fix-unsafe hint

  • baselined (Integer) (defaults to: 0) —

    findings hidden by the baseline



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/audition/report.rb', line 24

def initialize(target_type:, target_root:, findings:,
  dynamic_results: [], unsafe_fixes: 0,
  baselined: 0)
  @target_type = target_type
  @target_root = target_root
  @findings = findings.sort_by do |f|
    [f.path, f.line || 0, -f.severity_rank]
  end
  @dynamic_results = dynamic_results
  @unsafe_fixes = unsafe_fixes
  @baselined = baselined
end

Instance Attribute Details

#baselined ⇒ Object (readonly)

Returns the value of attribute baselined.



15
16
17
# File 'lib/audition/report.rb', line 15

def baselined
  @baselined
end

#dynamic_results ⇒ Object (readonly)

Returns the value of attribute dynamic_results.



15
16
17
# File 'lib/audition/report.rb', line 15

def dynamic_results
  @dynamic_results
end

#findings ⇒ Object (readonly)

Returns the value of attribute findings.



15
16
17
# File 'lib/audition/report.rb', line 15

def findings
  @findings
end

#target_root ⇒ Object (readonly)

Returns the value of attribute target_root.



15
16
17
# File 'lib/audition/report.rb', line 15

def target_root
  @target_root
end

#target_type ⇒ Object (readonly)

Returns the value of attribute target_type.



15
16
17
# File 'lib/audition/report.rb', line 15

def target_type
  @target_type
end

#unsafe_fixes ⇒ Object (readonly)

Returns the value of attribute unsafe_fixes.



15
16
17
# File 'lib/audition/report.rb', line 15

def unsafe_fixes
  @unsafe_fixes
end

Instance Method Details

#counts ⇒ Object

Test findings count apart at every severity: they are the target's code, but a production boot never loads them, so they never touch the verdict.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/audition/report.rb', line 66

def counts
  @counts ||= begin
    base = {error: 0, dep_error: 0, warning: 0, info: 0,
            test_error: 0, test_warning: 0, test_info: 0,
            fixable: 0}
    findings.each_with_object(base) do |f, acc|
      if f.error? && f.dependency?
        acc[:dep_error] += 1
      elsif f.test?
        acc[:"test_#{f.severity}"] += 1
      else
        acc[f.severity] += 1
      end
      # Only safe autofixes count: `--fix` alone would not
      # touch an unsafe-only finding, so advertising it as
      # fixable would send users in circles.
      if f.autofix && !f.autofix.unsafe?
        acc[:fixable] += 1
      end
    end
  end
end

#dependency_errors? ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/audition/report.rb', line 59

def dependency_errors?
  counts[:dep_error].positive?
end

#own_errors? ⇒ Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/audition/report.rb', line 55

def own_errors?
  counts[:error].positive?
end

#verdict ⇒ Symbol

Policy: own errors condemn the target outright; dependency errors (or a failed probe with clean own findings) mean the target is fine but cannot run here yet; anything softer is merely risky.

Returns:

  • (Symbol) —

    :not_ready, :blocked, :risky, or :ready



44
45
46
47
48
49
50
51
52
53
# File 'lib/audition/report.rb', line 44

def verdict
  return :not_ready if own_errors?
  return :blocked if dependency_errors? ||
    dynamic_results.any? { |r| !r.passed }
  return :risky if counts[:warning].positive?

  # Info notes describe things that work on Ruby 4.0 and are
  # only worth knowing; they do not taint the verdict.
  :ready
end