File: issue_reporter.rb

package info (click to toggle)
puppet-agent 7.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,092 kB
  • sloc: ruby: 245,074; sh: 456; makefile: 38; xml: 33
file content (137 lines) | stat: -rw-r--r-- 5,311 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
module Puppet::Pops
class IssueReporter

  # @param acceptor [Validation::Acceptor] the acceptor containing reported issues
  # @option options [String] :message (nil) A message text to use as prefix in
  #   a single Error message
  # @option options [Boolean] :emit_warnings (false) whether warnings should be emitted
  # @option options [Boolean] :emit_errors (true) whether errors should be
  #   emitted or only the given message
  # @option options [Exception] :exception_class (Puppet::ParseError) The exception to raise
  #
  def self.assert_and_report(acceptor, options)
    return unless acceptor

    max_errors       = options[:max_errors]   || Puppet[:max_errors]
    max_warnings     = options[:max_warnings] || Puppet[:max_warnings]
    max_deprecations = options[:max_deprecations] || (Puppet[:disable_warnings].include?('deprecations') ? 0 : Puppet[:max_deprecations])

    emit_warnings    = options[:emit_warnings] || false
    emit_errors      = options[:emit_errors].nil? ? true : !!options[:emit_errors]
    emit_message     = options[:message]
    emit_exception   = options[:exception_class] || Puppet::ParseErrorWithIssue

    # If there are warnings output them
    warnings = acceptor.warnings
    if emit_warnings && warnings.size > 0
      formatter = Validation::DiagnosticFormatterPuppetStyle.new
      emitted_w = 0
      emitted_dw = 0
      acceptor.warnings.each do |w|
        if w.severity == :deprecation
          # Do *not* call Puppet.deprecation_warning it is for internal deprecation, not
          # deprecation of constructs in manifests! (It is not designed for that purpose even if
          # used throughout the code base).
          #
          log_message(:warning, formatter, w) if emitted_dw < max_deprecations
          emitted_dw += 1
        else
          log_message(:warning, formatter, w) if emitted_w < max_warnings
          emitted_w += 1
        end
        break if emitted_w >= max_warnings && emitted_dw >= max_deprecations # but only then
      end
    end

    # If there were errors, report the first found. Use a puppet style formatter.
    errors = acceptor.errors
    if errors.size > 0
      unless emit_errors
        raise emit_exception.new(emit_message)
      end
      formatter = Validation::DiagnosticFormatterPuppetStyle.new
      if errors.size == 1 || max_errors <= 1
        # raise immediately
        exception = create_exception(emit_exception, emit_message, formatter, errors[0])
        # if an exception was given as cause, use it's backtrace instead of the one indicating "here"
        if errors[0].exception
          exception.set_backtrace(errors[0].exception.backtrace)
        end
        raise exception
      end
      emitted = 0
      if emit_message
        Puppet.err(emit_message)
      end
      errors.each do |e|
        log_message(:err, formatter, e)
        emitted += 1
        break if emitted >= max_errors
      end
      giving_up_message = if (emit_warnings && warnings.size > 0)
                            _("Language validation logged %{error_count} errors, and %{warning_count} warnings. Giving up") %
                                { error_count: errors.size, warning_count: warnings.size }
                          else
                            _("Language validation logged %{error_count} errors. Giving up") %
                                { error_count: errors.size }
                          end
      exception = emit_exception.new(giving_up_message)
      exception.file = errors[0].file
      raise exception
    end
  end

  def self.format_with_prefix(prefix, message)
    return message unless prefix
    [prefix, message].join(' ')
  end

  def self.warning(semantic, issue, args)
    Puppet::Util::Log.create({
      :level => :warning,
      :message => issue.format(args),
      :arguments => args,
      :issue_code => issue.issue_code,
      :file => semantic.file,
      :line => semantic.line,
      :pos => semantic.pos,
    })
  end

  def self.error(exception_class, semantic, issue, args)
    raise exception_class.new(issue.format(args), semantic.file, semantic.line, semantic.pos, nil, issue.issue_code, args)
  end

  def self.create_exception(exception_class, emit_message, formatter, diagnostic)
    file = diagnostic.file
    file = (file.is_a?(String) && file.empty?) ? nil : file
    line = pos = nil
    if diagnostic.source_pos
      line = diagnostic.source_pos.line
      pos = diagnostic.source_pos.pos
    end
    exception_class.new(format_with_prefix(emit_message, formatter.format_message(diagnostic)), file, line, pos, nil, diagnostic.issue.issue_code, diagnostic.arguments)
  end
  private_class_method :create_exception

  def self.log_message(severity, formatter, diagnostic)
    file = diagnostic.file
    file = (file.is_a?(String) && file.empty?) ? nil : file
    line = pos = nil
    if diagnostic.source_pos
      line = diagnostic.source_pos.line
      pos = diagnostic.source_pos.pos
    end
    Puppet::Util::Log.create({
        :level => severity,
        :message => formatter.format_message(diagnostic),
        :arguments => diagnostic.arguments,
        :issue_code => diagnostic.issue.issue_code,
        :file => file,
        :line => line,
        :pos => pos,
      })
  end
  private_class_method :log_message
end
end