Class: MuxTf::StderrLineHandler

Inherits:
Object
  • Object
show all
Includes:
Coloring, ErrorHandlingMethods, PiotrbCliUtils::Util
Defined in:
lib/mux_tf/stderr_line_handler.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ErrorHandlingMethods

#handle_error_states, #log_unhandled_line, #print_errors, #setup_error_handling

Methods included from Coloring

included, #pastel

Constructor Details

#initialize(operation: nil) ⇒ StderrLineHandler

Returns a new instance of StderrLineHandler.



13
14
15
16
17
18
19
# File 'lib/mux_tf/stderr_line_handler.rb', line 13

def initialize(operation: nil)
  @operation = operation
  @held_messages = []
  @parser = StatefulParser.new(normalizer: pastel.method(:strip))
  @meta = {}
  setup_error_handling(@parser, from_states: [:none])
end

Instance Attribute Details

#metaObject (readonly)

Returns the value of attribute meta.



11
12
13
# File 'lib/mux_tf/stderr_line_handler.rb', line 11

def meta
  @meta
end

Instance Method Details

#do_print_errorsObject



102
103
104
# File 'lib/mux_tf/stderr_line_handler.rb', line 102

def do_print_errors
  print_errors(@meta) if @meta[:errors] && !@meta[:errors].empty?
end

#flushObject



95
96
97
98
99
100
# File 'lib/mux_tf/stderr_line_handler.rb', line 95

def flush
  @held_messages.each do |msg|
    log msg, depth: 2
  end
  @held_messages = []
end

#handle(raw_line) ⇒ Object



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
# File 'lib/mux_tf/stderr_line_handler.rb', line 38

def handle(raw_line)
  return if raw_line.strip.empty?

  if raw_line =~ /Error when retrieving token from sso: Token has expired and refresh failed/
    log "#{pastel.red('error')}: SSO Session expired.", depth: 2
    return
  end

  # [✘] error when retrieving credentials from custom process. please login using 'granted sso login --sso-start-url https://janeapp.awsapps.com/start --sso-region us-east-1'
  if raw_line =~ /error when retrieving credentials from custom process. please login using '([^']+)'/
    unless @sso_expired
      @sso_expired = true
      log "#{pastel.red('error')}: SSO Session expired.", depth: 2
      log "#{pastel.red('error')}: Run: #{$LAST_MATCH_INFO[1]}", depth: 2
    end
    return
  end

  if raw_line.strip[0] == "{" && raw_line.strip[-1] == "}"
    begin
      # assuming that stderr is JSON and TG logs
      parsed_line = JSON.parse(raw_line)
      transform_paths!(parsed_line, "msg")
      transform_paths!(parsed_line, "prefix")
      parsed_line["msg"].gsub!("#{Dir.getwd}/", "")
      parsed_line["prefix"]&.strip!&.gsub!(/^\[/, "")&.gsub!(/\]$/, "") # rubocop:disable Style/SafeNavigationChainLength
      parsed_line["prefix"]&.gsub!(Dir.getwd, "")
      if @operation == :plan
        handle_plan_json(parsed_line)
      else
        log format_tg_log_line(parsed_line), depth: 2
      end
    rescue JSON::ParserError => e
      log "#{pastel.red('error')}: failed to parse JSON: #{e.message}", depth: 2
      log raw_line.rstrip, depth: 2
    end
  else
    @parser.parse(raw_line.rstrip) do |state, line|
      # log raw_line.rstrip, depth: 2
      log_unhandled_line(state, line, reason: "unexpected state in StderrLineHandler") unless handle_error_states(@meta, state, line)
    end
  end
end

#handle_plan_json(parsed_line) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/mux_tf/stderr_line_handler.rb', line 82

def handle_plan_json(parsed_line)
  if parsed_line["msg"] =~ /terraform invocation failed in/
    @held_messages << format_tg_log_line(parsed_line)
  elsif parsed_line["msg"] =~ /1 error occurred/ && parsed_line["msg"] =~ /exit status 2\n/
    # 2 = Succeeded with non-empty diff (changes present)
    # clear the held messages and swallow up this message too
    @held_messages = []
  else
    # flush
    log format_tg_log_line(parsed_line), depth: 2
  end
end

#merge_meta_into(other_meta) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/mux_tf/stderr_line_handler.rb', line 106

def merge_meta_into(other_meta)
  [:errors, :warnings].each do |type|
    if @meta[type]
      other_meta[type] ||= []
      other_meta[type] += @meta[type]
    end
  end

  extra_keys = @meta.keys - [:errors, :warnings]
  return unless extra_keys.any?

  log "Unhandled keys in stderr_handler.meta: #{extra_keys.inspect}"
  log @meta.inspect
end

#transform_paths!(hash, key) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/mux_tf/stderr_line_handler.rb', line 21

def transform_paths!(hash, key)
  return unless hash[key]

  if key == "prefix"
    hash[key].strip!
    hash[key].gsub!(/^\[/, "")
    hash[key].gsub!(/\]$/, "")
  end

  hash[key].gsub!("#{Dir.getwd}/", "")
  hash[key].gsub!(Dir.getwd, "")

  hash[key].gsub!($LAST_MATCH_INFO[1], "<cache>/") if hash[key].match(%r{(\.terragrunt-cache/[^/]+/[^/]+/)})

  hash
end