Module: GraphQL::Modernize::Reporter

Defined in:
lib/graphql/modernize/reporter.rb

Class Method Summary collapse

Class Method Details

.diffs(result) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/graphql/modernize/reporter.rb', line 41

def diffs(result)
  result.files.filter_map do |file|
    next if file.source_file.source == file.rewritten

    Astel::Diff.unified(file.source_file.source, file.rewritten, path: relative_path(file.source_file.path))
  end.join
end

.escape(value) ⇒ Object



98
99
100
# File 'lib/graphql/modernize/reporter.rb', line 98

def escape(value)
  value.to_s.gsub("%", "%25").gsub("\r", "%0D").gsub("\n", "%0A").gsub(":", "%3A").gsub(",", "%2C")
end

.github(result) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/graphql/modernize/reporter.rb', line 49

def github(result)
  result.files.flat_map(&:offenses).map do |offense|
    message = escape(offense.message)
    "::warning file=#{escape(offense.path)},line=#{offense.location.start_line}," \
      "col=#{offense.location.start_column + 1},title=#{offense.rule_id}::#{message}"
  end.join("\n") << (result.files.any? { |file| file.offenses.any? } ? "\n" : "")
end

.offense_payload(offense) ⇒ Object



85
86
87
88
89
90
# File 'lib/graphql/modernize/reporter.rb', line 85

def offense_payload(offense)
  { rule_id: offense.rule_id, path: offense.path, line: offense.location.start_line,
    column: offense.location.start_column + 1, message: offense.message, safety: offense.safety,
    correctable: offense.correctable?, corrected: offense.corrected?,
    conflicting_rule_id: offense.conflicting_rule_id }
end

.payload(result) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/graphql/modernize/reporter.rb', line 57

def payload(result)
  {
    files: result.files.length,
    iterations: result.iterations,
    parse_errors: result.parse_errors.map { |path, errors| { path: path, errors: errors } },
    offenses: result.files.flat_map(&:offenses).map { |offense| offense_payload(offense) }
  }
end

.relative_path(path) ⇒ Object



92
93
94
95
96
# File 'lib/graphql/modernize/reporter.rb', line 92

def relative_path(path)
  Pathname.new(path).relative_path_from(Pathname.new(Dir.pwd)).to_s
rescue ArgumentError
  path
end

.render(format, result, diff: true) ⇒ Object



11
12
13
14
15
16
17
18
19
20
# File 'lib/graphql/modernize/reporter.rb', line 11

def render(format, result, diff: true)
  case format.to_s
  when "text" then text(result, diff: diff)
  when "diff" then diffs(result)
  when "json" then JSON.pretty_generate(payload(result)) << "\n"
  when "github" then github(result)
  when "sarif" then JSON.pretty_generate(sarif_payload(result)) << "\n"
  else raise Error, "Unknown output format: #{format}"
  end
end

.sarif_payload(result) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/graphql/modernize/reporter.rb', line 66

def sarif_payload(result)
  offenses = result.files.flat_map(&:offenses)
  rules = offenses.uniq(&:rule_id).map do |offense|
    { id: offense.rule_id, shortDescription: { text: offense.message } }
  end
  results = offenses.map do |offense|
    {
      ruleId: offense.rule_id,
      message: { text: offense.message },
      locations: [{ physicalLocation: {
        artifactLocation: { uri: offense.path },
        region: { startLine: offense.location.start_line, startColumn: offense.location.start_column + 1 }
      } }]
    }
  end
  { version: "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
    runs: [{ tool: { driver: { name: "graphql-modernize", rules: rules } }, results: results }] }
end

.text(result, diff: true) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/graphql/modernize/reporter.rb', line 22

def text(result, diff: true)
  offenses = result.files.flat_map(&:offenses)
  output = result.parse_errors.map do |path, errors|
    "#{path}: parse error: #{errors.join(', ')}"
  end.join("\n")
  output << "\n" unless output.empty?
  offense_output = offenses.map do |offense|
    status = offense.corrected? ? " corrected" : ""
    conflict = offense.conflicting_rule_id ? " conflicts_with=#{offense.conflicting_rule_id}" : ""
    "#{offense.path}:#{offense.location.start_line}:#{offense.location.start_column + 1}: " \
      "[#{offense.rule_id}]#{status}#{conflict} #{offense.message}"
  end.join("\n")
  output << offense_output
  output << "\n" unless output.empty?
  output << diffs(result) if diff
  changed = result.files.count { |file| file.source_file.source != file.rewritten }
  output << "#{result.files.length} files inspected, #{offenses.length} offenses, #{changed} files changed\n"
end