terraform_landscape 0.2.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98a71818264c2488766b447e16abbd2be9eb743ddd8faf717df0b0652742ea36
4
- data.tar.gz: 883c3799319b75efb960a6e185897a581d2362e4499c0f442dcf155669221d04
3
+ metadata.gz: d67a499f9c9745e1444129aee8abdbbead348f66374080896e8dc15fd411e90c
4
+ data.tar.gz: 9a54df826e4075b9faee8fe9de305f95265c480eafaa955a01470945073e073b
5
5
  SHA512:
6
- metadata.gz: d49d670112420768a487c6f69a009923a75607d8cfcc58beffa8824c96aec6ddd931a8c71b2281a69ea300558be4b05ce2058fb57b0ac1df101dac3e7fee0104
7
- data.tar.gz: 42b90645cf8ab30928c2257afc11ebf943afe1216e9983f14c652808e8d22cd0a7b3cc9e988fa384b0158003696ed60b985b0b18959b7c2b80ff99497b574382
6
+ metadata.gz: 3bd6351fd9ad2847f496546032d42d20dd2676865ba0dca5146a44ebf921815d70cb93ae550fb8ae67f97690c28e9d9206fc7fa5ddf2fa281ddd1c8e5e532399
7
+ data.tar.gz: 589ca816d9f1ba3144ffc1e22d43fde6e846732ffdef0f327d068a06f978deb6c4f02329cc44bab4c94da50b7baa27f8d8c2e8e334ed3bed9dfb94ae3156a66c
@@ -38,7 +38,7 @@ grammar TerraformPlan
38
38
  end
39
39
 
40
40
  rule resource_header
41
- _? change:('~' / '-/+' / '-' / '+' / '<=') _ type:[a-zA-Z0-9_-]+ '.' name:[\S]+ _ '(' reason1:[^)]+ ')' _ '(' reason2:[^)]+ ')' {
41
+ ws? change:('~' / '-/+' / '-' / '+' / '<=') ws type:[a-zA-Z0-9_-]+ '.' name:[\S]+ ws '(' reason1:[^)]+ ')' ws '(' reason2:[^)]+ ')' {
42
42
  def to_ast
43
43
  {
44
44
  change: change.text_value.to_sym,
@@ -50,7 +50,7 @@ grammar TerraformPlan
50
50
  end
51
51
  }
52
52
  /
53
- _? change:('~' / '-/+' / '-' / '+' / '<=') _ type:[a-zA-Z0-9_-]+ '.' name:[\S]+ _ '(' reason:[^)]+ ')' {
53
+ ws? change:('~' / '-/+' / '-' / '+' / '<=') ws type:[a-zA-Z0-9_-]+ '.' name:[\S]+ ws '(' reason:[^)]+ ')' {
54
54
  def to_ast
55
55
  {
56
56
  change: change.text_value.to_sym,
@@ -61,7 +61,7 @@ grammar TerraformPlan
61
61
  end
62
62
  }
63
63
  /
64
- _? change:('~' / '-/+' / '-' / '+' / '<=') _ type:[a-zA-Z0-9_-]+ '.' name:[\S]+ {
64
+ ws? change:('~' / '-/+' / '-' / '+' / '<=') ws type:[a-zA-Z0-9_-]+ '.' name:[\S]+ {
65
65
  def to_ast
66
66
  {
67
67
  change: change.text_value.to_sym,
@@ -73,13 +73,13 @@ grammar TerraformPlan
73
73
  end
74
74
 
75
75
  rule attribute_list
76
- _ item:attribute "\n" attrs:attribute_list {
76
+ ws item:attribute "\n" attrs:attribute_list {
77
77
  def to_ast
78
78
  item.to_ast.merge(attrs.to_ast)
79
79
  end
80
80
  }
81
81
  /
82
- _ item:attribute {
82
+ ws item:attribute {
83
83
  def to_ast
84
84
  item.to_ast
85
85
  end
@@ -87,7 +87,7 @@ grammar TerraformPlan
87
87
  end
88
88
 
89
89
  rule attribute
90
- attribute_name:(!': ' .)* ':' _? attribute_value:[^\n]+ {
90
+ attribute_name:(!': ' .)* ':' ws? attribute_value:[^\n]+ {
91
91
  def to_ast
92
92
  { attribute_name.text_value => sanitize_value_and_reason }
93
93
  end
@@ -115,7 +115,7 @@ grammar TerraformPlan
115
115
  }
116
116
  end
117
117
 
118
- rule _
118
+ rule ws
119
119
  [ ]+
120
120
  end
121
121
  end
@@ -30,9 +30,14 @@ module TerraformLandscape
30
30
 
31
31
  def define_commands
32
32
  command :print do |c|
33
- c.action do
34
- print
33
+ c.action do |_args, options|
34
+ print(options.__hash__)
35
35
  end
36
+ c.description = <<-TXT
37
+ Pretty-prints your Terraform plan output.
38
+
39
+ If an error occurs while parsing the Terraform output, print will automatically fall back on the original Terraform output. To view the stack trace instead, provide the global --trace option.
40
+ TXT
36
41
  end
37
42
 
38
43
  global_option '--no-color', 'Do not output any color' do
@@ -43,9 +48,9 @@ module TerraformLandscape
43
48
  default_command :print
44
49
  end
45
50
 
46
- def print
51
+ def print(options)
47
52
  printer = Printer.new(@output)
48
- printer.process_stream(STDIN)
53
+ printer.process_stream(ARGF, options)
49
54
  end
50
55
  end
51
56
  end
@@ -6,4 +6,7 @@ module TerraformLandscape
6
6
 
7
7
  REPO_URL = 'https://github.com/coinbase/terraform_landscape'.freeze
8
8
  BUG_REPORT_URL = "#{REPO_URL}/issues".freeze
9
+
10
+ FALLBACK_MESSAGE = 'Terraform Landscape: a parsing error occured.' \
11
+ ' Falling back to original Terraform output...'.freeze
9
12
  end
@@ -1,16 +1,17 @@
1
1
  require 'stringio'
2
2
 
3
3
  module TerraformLandscape
4
- # Takes output from Terraform executable nad outputs it in a prettified
4
+ # Takes output from Terraform executable and outputs it in a prettified
5
5
  # format.
6
6
  class Printer
7
7
  def initialize(output)
8
8
  @output = output
9
9
  end
10
10
 
11
- def process_stream(io) # rubocop:disable Metrics/MethodLength
11
+ def process_stream(io, options = {}) # rubocop:disable Metrics/MethodLength
12
12
  apply = nil
13
13
  buffer = StringIO.new
14
+ original_tf_output = StringIO.new
14
15
  begin
15
16
  block_size = 1024
16
17
 
@@ -21,7 +22,9 @@ module TerraformLandscape
21
22
 
22
23
  readable_fds.each do |f|
23
24
  begin
24
- buffer << strip_ansi(f.read_nonblock(block_size))
25
+ new_output = f.read_nonblock(block_size)
26
+ original_tf_output << new_output
27
+ buffer << strip_ansi(new_output)
25
28
  rescue IO::WaitReadable # rubocop:disable Lint/HandleExceptions
26
29
  # Ignore; we'll call IO.select again
27
30
  rescue EOFError
@@ -34,9 +37,17 @@ module TerraformLandscape
34
37
  replace: ''))
35
38
  done = true if apply
36
39
  end
37
- process_string(buffer.string)
38
40
 
39
- @output.print apply if apply
41
+ begin
42
+ process_string(buffer.string)
43
+ @output.print apply if apply
44
+ rescue ParseError, TerraformPlan::ParseError => e
45
+ raise e if options[:trace]
46
+
47
+ @output.warning FALLBACK_MESSAGE
48
+ @output.print original_tf_output.string
49
+ end
50
+
40
51
  @output.write_from(io)
41
52
  ensure
42
53
  io.close
@@ -46,10 +57,15 @@ module TerraformLandscape
46
57
  def process_string(plan_output) # rubocop:disable Metrics/MethodLength
47
58
  scrubbed_output = strip_ansi(plan_output)
48
59
 
60
+ # Our grammar assumes output with Unix line endings
61
+ scrubbed_output.gsub!("\r\n", "\n")
62
+
49
63
  # Remove initialization messages like
50
64
  # "- Downloading plugin for provider "aws" (1.1.0)..."
65
+ # "- module.base_network"
51
66
  # as these break the parser which thinks "-" is a resource deletion
52
67
  scrubbed_output.gsub!(/^- .*\.\.\.$/, '')
68
+ scrubbed_output.gsub!(/^- module\..*$/, '')
53
69
 
54
70
  # Remove separation lines that appear after refreshing state
55
71
  scrubbed_output.gsub!(/^-+$/, '')
@@ -2,7 +2,6 @@ require 'colorize'
2
2
  require 'diffy'
3
3
  require 'json'
4
4
  require 'treetop'
5
- require 'string_undump'
6
5
 
7
6
  ########################################################################
8
7
  # Represents the parsed output of `terraform plan`.
@@ -25,6 +24,10 @@ class TerraformLandscape::TerraformPlan # rubocop:disable Metrics/ClassLength
25
24
 
26
25
  DEFAULT_DIFF_CONTEXT_LINES = 5
27
26
 
27
+ UNICODE_ESCAPER = proc { |s|
28
+ format('\u%04X', s.codepoints[0])
29
+ }
30
+
28
31
  class ParseError < StandardError; end
29
32
 
30
33
  class << self
@@ -103,6 +106,10 @@ class TerraformLandscape::TerraformPlan # rubocop:disable Metrics/ClassLength
103
106
  longest_name_length + 8
104
107
  end
105
108
 
109
+ def undump(value)
110
+ value.encode('ASCII', fallback: UNICODE_ESCAPER).undump
111
+ end
112
+
106
113
  def json?(value)
107
114
  ['{', '['].include?(value.to_s[0]) &&
108
115
  (JSON.parse(value) rescue nil) # rubocop:disable Style/RescueModifier
@@ -179,8 +186,8 @@ class TerraformLandscape::TerraformPlan # rubocop:disable Metrics/ClassLength
179
186
  )
180
187
  # Since the attribute line is always of the form "old value" => "new value"
181
188
  attribute_value =~ /^ *(".*") *=> *(".*") *$/
182
- old = Regexp.last_match[1].undump
183
- new = Regexp.last_match[2].undump
189
+ old = undump(Regexp.last_match[1])
190
+ new = undump(Regexp.last_match[2])
184
191
 
185
192
  return if old == new && new != '<sensitive>' # Don't show unchanged attributes
186
193
 
@@ -219,7 +226,7 @@ class TerraformLandscape::TerraformPlan # rubocop:disable Metrics/ClassLength
219
226
  @out.print " #{attribute_name}:".ljust(attribute_value_indent_amount, ' ')
220
227
  .colorize(change_color)
221
228
 
222
- evaluated_string = attribute_value.undump
229
+ evaluated_string = undump(attribute_value)
223
230
  if json?(evaluated_string)
224
231
  @out.print to_pretty_json(evaluated_string).gsub("\n",
225
232
  "\n#{attribute_value_indent}")
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  module TerraformLandscape
5
- VERSION = '0.2.2'.freeze
5
+ VERSION = '0.3.4'.freeze
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terraform_landscape
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Coinbase
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-11-30 00:00:00.000000000 Z
12
+ date: 2021-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize
@@ -53,20 +53,6 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '3.0'
56
- - !ruby/object:Gem::Dependency
57
- name: string_undump
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - "~>"
61
- - !ruby/object:Gem::Version
62
- version: 0.1.1
63
- type: :runtime
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: 0.1.1
70
56
  - !ruby/object:Gem::Dependency
71
57
  name: treetop
72
58
  requirement: !ruby/object:Gem::Requirement
@@ -112,15 +98,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
98
  requirements:
113
99
  - - ">="
114
100
  - !ruby/object:Gem::Version
115
- version: '2'
101
+ version: '2.5'
116
102
  required_rubygems_version: !ruby/object:Gem::Requirement
117
103
  requirements:
118
104
  - - ">="
119
105
  - !ruby/object:Gem::Version
120
106
  version: '0'
121
107
  requirements: []
122
- rubyforge_project:
123
- rubygems_version: 2.7.7
108
+ rubygems_version: 3.1.4
124
109
  signing_key:
125
110
  specification_version: 4
126
111
  summary: Pretty-print Terraform plan output