Module: Moult::Formatters::GateSarif

Defined in:
lib/moult/formatters/gate_sarif.rb

Overview

SARIF 2.1.0 projection of the gate verdict — the static-analysis interchange format GitHub code scanning and reviewdog consume. One rule per policy rule; one result (level "error") per contributing finding behind a failed rule. Emits the document only; uploading it is the consumer's job.

A finding's value is a graded/classified signal (confidence/ABC/mass/ severity), so the result text reports it as such — never as a certainty.

Constant Summary collapse

SARIF_SCHEMA =
"https://json.schemastore.org/sarif-2.1.0.json"
INFORMATION_URI =
"https://github.com/moult-rb/moult-rb"

Class Method Summary collapse

Class Method Details

.document(report) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/moult/formatters/gate_sarif.rb', line 26

def document(report)
  {
    "$schema" => SARIF_SCHEMA,
    "version" => "2.1.0",
    "runs" => [{
      "tool" => {
        "driver" => {
          "name" => "moult",
          "version" => Moult::VERSION,
          "informationUri" => INFORMATION_URI,
          "rules" => report.rules.map { |r| rule_descriptor(r) }
        }
      },
      "results" => results(report)
    }]
  }
end

.message(rule, finding) ⇒ Object



73
74
75
# File 'lib/moult/formatters/gate_sarif.rb', line 73

def message(rule, finding)
  GateMessage.for(rule, finding)
end

.physical_location(finding) ⇒ Object



67
68
69
70
71
# File 'lib/moult/formatters/gate_sarif.rb', line 67

def physical_location(finding)
  location = {"artifactLocation" => {"uri" => finding.path}}
  location["region"] = {"startLine" => finding.line} if finding.line
  location
end

.render(report) ⇒ String

Parameters:

Returns:

  • (String)


22
23
24
# File 'lib/moult/formatters/gate_sarif.rb', line 22

def render(report)
  JSON.pretty_generate(document(report))
end

.result(rule, finding) ⇒ Object



58
59
60
61
62
63
64
65
# File 'lib/moult/formatters/gate_sarif.rb', line 58

def result(rule, finding)
  {
    "ruleId" => rule.rule,
    "level" => "error",
    "message" => {"text" => message(rule, finding)},
    "locations" => [{"physicalLocation" => physical_location(finding)}]
  }
end

.results(report) ⇒ Object



52
53
54
55
56
# File 'lib/moult/formatters/gate_sarif.rb', line 52

def results(report)
  report.rules.select { |r| r.evaluated && r.passed == false }.flat_map do |rule|
    rule.findings.map { |f| result(rule, f) }
  end
end

.rule_descriptor(rule) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/moult/formatters/gate_sarif.rb', line 44

def rule_descriptor(rule)
  {
    "id" => rule.rule,
    "shortDescription" => {"text" => rule.rule.tr("_", " ")},
    "properties" => {"threshold" => rule.threshold.to_s, "evaluated" => rule.evaluated}
  }
end