mux_tf 0.4.8 → 0.5.2

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: 9360bb62c3df497bb64e7cbbab15025e1a9f3618b74a3469db097329832f365e
4
- data.tar.gz: 646cb9832629e10c63c9a80982ce931d22fc1dd9c32f32dfc79edd9f8e864ba9
3
+ metadata.gz: ad025779e41606eb4bd006dd9e796127b0e327e53611721ae4ca7186658987a7
4
+ data.tar.gz: dc4758018d33671a6a0f3cc3ce65b0976e1ae35753ec66c9ffa2e647f3f1845d
5
5
  SHA512:
6
- metadata.gz: fb7fed0568c1d001a168623a0071c469f3be6b812235f962901f63505108869dfee859f62f2ac773f444b4a128552ca487711f6d7b4ce117d0008bfa30f6b056
7
- data.tar.gz: d31b175be20f0b94d02c9bff65b27925984463b268d1dd3378a2d347e42b7f476aa1a1264b6c74c4fa03a64a3c03d39e0f0b1a6a8b318bde346ee7b5c6e3dc8c
6
+ metadata.gz: dd2cafd746e7eb24bccf066475b9b95a9b5201624ac14fa462666644a2ea8b0a35c1bbb8a78d31987884f43477c37efbdec480babd2050a9d4699b78e07f2cb6
7
+ data.tar.gz: 7d54a48d72d7129cac2eec2287d4e78244fe857cf67a838213a0c0c00c59fa7e0fcaf77af8b592b8108083618b4d9fd46d83d6e998d17cdc9b888c77c48098dd
data/exe/tf_current CHANGED
@@ -2,8 +2,9 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  begin
5
- $LOAD_PATH << File.expand_path(File.join(__dir__, "..", "lib"))
5
+ $LOAD_PATH.unshift File.expand_path(File.join(__dir__, "..", "lib"))
6
6
 
7
+ require "deps"
7
8
  require "mux_tf"
8
9
 
9
10
  MuxTf::Cli.run(:current, ARGV)
data/exe/tf_mux CHANGED
@@ -2,8 +2,9 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  begin
5
- $LOAD_PATH << File.expand_path(File.join(__dir__, "..", "lib"))
5
+ $LOAD_PATH.unshift File.expand_path(File.join(__dir__, "..", "lib"))
6
6
 
7
+ require "deps"
7
8
  require "mux_tf"
8
9
 
9
10
  MuxTf::Cli.run(:mux, ARGV)
data/exe/tf_plan_summary CHANGED
@@ -2,8 +2,9 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  begin
5
- $LOAD_PATH << File.expand_path(File.join(__dir__, "..", "lib"))
5
+ $LOAD_PATH.unshift File.expand_path(File.join(__dir__, "..", "lib"))
6
6
 
7
+ require "deps"
7
8
  require "mux_tf"
8
9
 
9
10
  MuxTf::Cli.run(:plan_summary, ARGV)
data/lib/mux_tf.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./deps"
4
-
5
3
  require "English"
6
4
 
7
5
  require "shellwords"
@@ -22,6 +20,7 @@ require "tty-table"
22
20
  require "dotenv"
23
21
 
24
22
  require_relative "./mux_tf/version"
23
+ require_relative "./mux_tf/resource_tokenizer"
25
24
  require_relative "./mux_tf/cli"
26
25
  require_relative "./mux_tf/tmux"
27
26
  require_relative "./mux_tf/terraform_helpers"
@@ -103,9 +103,9 @@ module MuxTf
103
103
  tf_validate.parsed_output
104
104
  end
105
105
 
106
- def create_plan(filename)
106
+ def create_plan(filename, targets: [])
107
107
  log "Preparing Plan ...", depth: 1
108
- exit_code, meta = PlanFormatter.pretty_plan(filename)
108
+ exit_code, meta = PlanFormatter.pretty_plan(filename, targets: targets)
109
109
  case exit_code
110
110
  when 0
111
111
  [:ok, meta]
@@ -276,8 +276,8 @@ module MuxTf
276
276
  end
277
277
  end
278
278
 
279
- def run_plan
280
- plan_status, @plan_meta = create_plan(PLAN_FILENAME)
279
+ def run_plan(targets: [])
280
+ plan_status, @plan_meta = create_plan(PLAN_FILENAME, targets: targets)
281
281
 
282
282
  case plan_status
283
283
  when :ok
@@ -6,7 +6,7 @@ module MuxTf
6
6
  extend PiotrbCliUtils::Util
7
7
 
8
8
  class << self
9
- def pretty_plan(filename)
9
+ def pretty_plan(filename, targets: [])
10
10
  pastel = Pastel.new
11
11
 
12
12
  phase = :init
@@ -15,7 +15,7 @@ module MuxTf
15
15
 
16
16
  parser = StatefulParser.new(normalizer: pastel.method(:strip))
17
17
  parser.state(:info, /^Acquiring state lock/)
18
- parser.state(:error, /Error locking state/, %i[none blank info])
18
+ parser.state(:error, /(╷|Error locking state|Error:)/, %i[none blank info])
19
19
  parser.state(:refreshing, /^.+: Refreshing state... \[id=/, %i[none info])
20
20
  parser.state(:refreshing, /Refreshing Terraform state in-memory prior to plan.../, %i[none blank info])
21
21
  parser.state(:refresh_done, /^----------+$/, [:refreshing])
@@ -26,9 +26,9 @@ module MuxTf
26
26
  parser.state(:error_lock_info, /Lock Info/, [:error])
27
27
  parser.state(:error, /^$/, [:error_lock_info])
28
28
 
29
- parser.state(:plan_error, /^Error: /, %i[refreshing refresh_done])
29
+ parser.state(:plan_error, /^╷|Error: /, %i[refreshing refresh_done])
30
30
 
31
- status = tf_plan(out: filename, detailed_exitcode: true, compact_warnings: true) { |raw_line|
31
+ status = tf_plan(out: filename, detailed_exitcode: true, compact_warnings: true, targets: targets) { |raw_line|
32
32
  parser.parse(raw_line.rstrip) do |state, line|
33
33
  case state
34
34
  when :none
@@ -6,6 +6,8 @@ module MuxTf
6
6
  include TerraformHelpers
7
7
  include PiotrbCliUtils::Util
8
8
 
9
+ PLAN_FILENAME = "foo.tfplan"
10
+
9
11
  def self.from_file(file)
10
12
  data = data_from_file(file)
11
13
  new data
@@ -137,11 +139,7 @@ module MuxTf
137
139
 
138
140
  if !result.empty?
139
141
  log "Re-running apply with the selected resources ..."
140
- status = tf_apply(targets: result)
141
- unless status.success?
142
- log Paint["Failed! (#{status.status})", :red]
143
- throw :abort, "Apply Failed! #{status.status}"
144
- end
142
+ run_plan(targets: result)
145
143
  else
146
144
  throw :abort, "nothing selected"
147
145
  end
@@ -151,6 +149,48 @@ module MuxTf
151
149
 
152
150
  attr_reader :parts
153
151
 
152
+ def create_plan(filename, targets: [])
153
+ log "Preparing Plan ...", depth: 1
154
+ exit_code, meta = PlanFormatter.pretty_plan(filename, targets: targets)
155
+ case exit_code
156
+ when 0
157
+ [:ok, meta]
158
+ when 1
159
+ [:error, meta]
160
+ when 2
161
+ [:changes, meta]
162
+ else
163
+ log Paint["terraform plan exited with an unknown exit code: #{exit_code}", :yellow]
164
+ [:unknown, meta]
165
+ end
166
+ end
167
+
168
+ def run_plan(targets: [])
169
+ plan_status, @plan_meta = create_plan(PLAN_FILENAME, targets: targets)
170
+
171
+ case plan_status
172
+ when :ok
173
+ log "no changes", depth: 1
174
+ when :error
175
+ log "something went wrong", depth: 1
176
+ when :changes
177
+ log "Printing Plan Summary ...", depth: 1
178
+ pretty_plan_summary(PLAN_FILENAME)
179
+ when :unknown
180
+ # nothing
181
+ end
182
+ plan_status
183
+ end
184
+
185
+ def pretty_plan_summary(filename)
186
+ plan = PlanSummaryHandler.from_file(filename)
187
+ plan.flat_summary.each do |line|
188
+ log line, depth: 2
189
+ end
190
+ log "", depth: 2
191
+ log plan.summary, depth: 2
192
+ end
193
+
154
194
  def prune_unchanged_deps(parts)
155
195
  valid_addresses = parts.map { |part| part[:address] }
156
196
 
@@ -250,11 +290,21 @@ module MuxTf
250
290
  end
251
291
 
252
292
  def format_address(address)
253
- parts = address.split(".")
254
- parts.each_with_index do |part, index|
255
- parts[index] = Paint[part, :cyan] if index.odd?
293
+ result = []
294
+ parts = ResourceTokenizer.tokenize(address)
295
+ parts.each_with_index do |(part_type, part_value), index|
296
+ case part_type
297
+ when :rt
298
+ result << "." if index > 0
299
+ result << Paint[part_value, :cyan]
300
+ when :rn
301
+ result << "."
302
+ result << part_value
303
+ when :ri
304
+ result << Paint[part_value, :green]
305
+ end
256
306
  end
257
- parts.join(".")
307
+ result.join
258
308
  end
259
309
  end
260
310
  end
@@ -0,0 +1,62 @@
1
+ class ResourceTokenizer
2
+ def self.split(resource)
3
+ tokenize(resource).map(&:last)
4
+ end
5
+
6
+ def self.tokenize(resource)
7
+ result = []
8
+ n = 0
9
+ pn = 0
10
+ state = :rt
11
+ until n >= resource.length
12
+ case state
13
+ when :rt
14
+ # looking for .
15
+ if resource[n] == "."
16
+ # reached the dot ..
17
+ result << [:rt, resource[pn...n]]
18
+ pn = n + 1
19
+ state = :rn
20
+ end
21
+ when :rn
22
+ # looking for [ or .
23
+ if resource[n] == "."
24
+ # reached the dot ..
25
+ result << [:rn, resource[pn...n]]
26
+ pn = n + 1
27
+ state = :rt
28
+ end
29
+ if resource[n] == "["
30
+ # reached the open bracket
31
+ result << [:rn, resource[pn...n]]
32
+ pn = n
33
+ state = :ri
34
+ end
35
+ if n == resource.length - 1
36
+ # last character .. close the current group
37
+ # the last thing should only ever be an index or a name
38
+ result << [:rn, resource[pn..n]]
39
+ pn = n
40
+ state = :done
41
+ end
42
+ when :ri
43
+ # looking for ]
44
+ if resource[n] == "]"
45
+ # reached the close bracket
46
+ result << [:ri, resource[pn..n]]
47
+ pn = n + 1
48
+ state = :rt
49
+ if resource[n + 1] == "."
50
+ pn = n + 2
51
+ n += 1
52
+ end
53
+ end
54
+ else
55
+ warn "unhandled state: #{state.inspect}"
56
+ end
57
+ # p resource[n]
58
+ n += 1
59
+ end
60
+ result
61
+ end
62
+ end
@@ -37,13 +37,18 @@ module MuxTf
37
37
  stream_or_run_terraform(cmd, &block)
38
38
  end
39
39
 
40
- def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, &block)
40
+ def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, targets: [], &block)
41
41
  args = []
42
42
  args += ["-out", out]
43
43
  args << "-input=#{input.inspect}" unless input.nil?
44
44
  args << "-compact-warnings" if compact_warnings
45
45
  args << "-no-color" unless color
46
46
  args << "-detailed-exitcode" if detailed_exitcode
47
+ if targets && !targets.empty?
48
+ targets.each do |target|
49
+ args << "-target=#{target}"
50
+ end
51
+ end
47
52
 
48
53
  cmd = tf_prepare_command(["plan", *args], need_auth: true)
49
54
  stream_or_run_terraform(cmd, &block)
@@ -73,7 +78,7 @@ module MuxTf
73
78
  end
74
79
 
75
80
  def stream_or_run_terraform(args, &block)
76
- if block_given?
81
+ if block
77
82
  stream_terraform(args, &block)
78
83
  else
79
84
  run_terraform(args)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MuxTf
4
- VERSION = "0.4.8"
4
+ VERSION = "0.5.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mux_tf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Banasik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-25 00:00:00.000000000 Z
11
+ date: 2021-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -143,6 +143,7 @@ files:
143
143
  - lib/mux_tf/cli/plan_summary.rb
144
144
  - lib/mux_tf/plan_formatter.rb
145
145
  - lib/mux_tf/plan_summary_handler.rb
146
+ - lib/mux_tf/resource_tokenizer.rb
146
147
  - lib/mux_tf/terraform_helpers.rb
147
148
  - lib/mux_tf/tmux.rb
148
149
  - lib/mux_tf/version.rb