mux_tf 0.4.6 → 0.5.0

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: 72095840d17350f49c8cd49b97dc28db32948d51f17c572b5addaa51e6f01d6f
4
- data.tar.gz: 51a4a8c094983a7d0c09b4fb61ace1c23a387cd24e4f13cd7b55653ec98fbacb
3
+ metadata.gz: a1742588983c720769618427118003ad76ab69f8be2035b19f8c779ab1876669
4
+ data.tar.gz: 12563430cfe99792a995675611a0dbd8aad9582d6ed063c0a38335dec1bac6b0
5
5
  SHA512:
6
- metadata.gz: 7855009e15efa1a70256b9afc2cfa64452feff27a95aad28e2eb6171a70ad69ceee864b92d4e1cd41ee5cc296e68739c6d64fa86c599c8dde996bed4aef44a08
7
- data.tar.gz: 6a27ffa3d8305525f5e1f7861f448253a3f81d1e5b4c5af82f255abc2232a476e91cd589f747c9a5e8858a9ec880bcf8c4d2911265e81228337fe10f4514a46a
6
+ metadata.gz: 302ebae8183b41dfb4c7218d95dcdf9d0117df023caf80c6a38ec9969071b6af55d538e73eb08e6ef275816e6dc29220277c4b731202df9f5f30b9f4e3013c5c
7
+ data.tar.gz: 3af421ee73ec82cb62d0b9e8ae41c9a220b5feae31dda1328b14c71aa8d6e02b5acd858da13fe606ecfcfeaf290f99a9d7b0806b0b2f9ea40e752d5f8d544bc6
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,8 +15,8 @@ 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])
19
- parser.state(:refreshing, /^.+: Refreshing state... \[id=/, %i[none])
18
+ parser.state(:error, /(╷|Error locking state|Error:)/, %i[none blank info])
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])
22
22
  parser.state(:refresh_done, /^$/, [:refreshing])
@@ -28,7 +28,7 @@ module MuxTf
28
28
 
29
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
@@ -126,6 +126,10 @@ module MuxTf
126
126
  next
127
127
  end
128
128
  case stripped_line
129
+ when /^Downloading (?<repo>[^ ]+) (?<version>[^ ]+) for (?<module>[^ ]+)\.\.\./
130
+ print "D"
131
+ when /^- (?<module>[^ ]+) in (?<path>.+)$/
132
+ print "."
129
133
  when ""
130
134
  puts
131
135
  else
@@ -182,6 +186,9 @@ module MuxTf
182
186
  next
183
187
  end
184
188
  case stripped_line
189
+ when /^- Reusing previous version of (?<module>.+) from the dependency lock file$/
190
+ info = $LAST_MATCH_INFO.named_captures
191
+ log "- [FROM-LOCK] #{info["module"]}", depth: 2
185
192
  when /^- (?<module>.+) is built in to Terraform$/
186
193
  info = $LAST_MATCH_INFO.named_captures
187
194
  log "- [BUILTIN] #{info["module"]}", depth: 2
@@ -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,55 @@
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
+ when :ri
36
+ # looking for ]
37
+ if resource[n] == "]"
38
+ # reached the close bracket
39
+ result << [:ri, resource[pn..n]]
40
+ pn = n + 1
41
+ state = :rt
42
+ if resource[n + 1] == "."
43
+ pn = n + 2
44
+ n += 1
45
+ end
46
+ end
47
+ else
48
+ warn "unhandled state: #{state.inspect}"
49
+ end
50
+ # p resource[n]
51
+ n += 1
52
+ end
53
+ result
54
+ end
55
+ 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.6"
4
+ VERSION = "0.5.0"
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.6
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Banasik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-23 00:00:00.000000000 Z
11
+ date: 2021-07-23 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
@@ -170,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
171
  - !ruby/object:Gem::Version
171
172
  version: '0'
172
173
  requirements: []
173
- rubygems_version: 3.0.3
174
+ rubygems_version: 3.1.4
174
175
  signing_key:
175
176
  specification_version: 4
176
177
  summary: Terraform Multiplexing Scripts