mux_tf 0.12.0 → 0.14.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 +4 -4
- data/exe/tf_current +2 -0
- data/exe/tf_mux +2 -0
- data/exe/tf_plan_summary +2 -0
- data/lib/deps.rb +10 -1
- data/lib/mux_tf/cli/current.rb +239 -63
- data/lib/mux_tf/cli/plan_summary.rb +2 -1
- data/lib/mux_tf/cli.rb +5 -3
- data/lib/mux_tf/coloring.rb +23 -0
- data/lib/mux_tf/plan_formatter.rb +520 -54
- data/lib/mux_tf/plan_summary_handler.rb +100 -125
- data/lib/mux_tf/plan_utils.rb +360 -0
- data/lib/mux_tf/terraform_helpers.rb +52 -9
- data/lib/mux_tf/tmux.rb +2 -0
- data/lib/mux_tf/version.rb +1 -1
- data/lib/mux_tf.rb +18 -10
- data/mux_tf.gemspec +3 -1
- metadata +33 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9a03af7a131fd34e58d5fb27d3c578154f49246634a684980e6ebc16aa28d08
|
4
|
+
data.tar.gz: d093d1604dabbeb1aed8ef5b1ebc3e33a0b5e3575602f7b3802796b2b51f7a7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7809b83e63a8aa17671ef6fbaac79a09cd7aa8216fdd1ccd390f2e32ee0b4ec0a85e4f6653d4c4bbbafcb99d47076413a9135f970f4d4c0f7f8608b2e8858f5f
|
7
|
+
data.tar.gz: c9dd73ed72236b568c7bbdc34ede9701e1d1db94403ccd2e84ee611cd58500e73810f50c9c0bdd6817c2ef7f8bd5d504fd945d86d340db95d9246e797376efb4
|
data/exe/tf_current
CHANGED
data/exe/tf_mux
CHANGED
data/exe/tf_plan_summary
CHANGED
data/lib/deps.rb
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
require "bundler/inline"
|
4
4
|
|
5
|
-
|
5
|
+
dep_def = proc do
|
6
6
|
gemspec(path: File.join(__dir__, ".."))
|
7
7
|
end
|
8
|
+
|
9
|
+
begin
|
10
|
+
gemfile(&dep_def)
|
11
|
+
rescue Bundler::GemNotFound
|
12
|
+
gemfile(true) do
|
13
|
+
source "https://rubygems.org"
|
14
|
+
instance_exec(&dep_def)
|
15
|
+
end
|
16
|
+
end
|
data/lib/mux_tf/cli/current.rb
CHANGED
@@ -4,13 +4,14 @@ require "bundler"
|
|
4
4
|
|
5
5
|
module MuxTf
|
6
6
|
module Cli
|
7
|
-
module Current
|
7
|
+
module Current # rubocop:disable Metrics/ModuleLength
|
8
8
|
extend TerraformHelpers
|
9
9
|
extend PiotrbCliUtils::Util
|
10
10
|
extend PiotrbCliUtils::CriCommandSupport
|
11
11
|
extend PiotrbCliUtils::CmdLoop
|
12
|
+
include Coloring
|
12
13
|
|
13
|
-
class << self
|
14
|
+
class << self # rubocop:disable Metrics/ClassLength
|
14
15
|
def run(args)
|
15
16
|
version_check
|
16
17
|
|
@@ -19,8 +20,21 @@ module MuxTf
|
|
19
20
|
return
|
20
21
|
end
|
21
22
|
|
23
|
+
unless args.empty?
|
24
|
+
root_cmd = build_root_cmd
|
25
|
+
valid_commands = root_cmd.subcommands.map(&:name)
|
26
|
+
|
27
|
+
if args[0] && valid_commands.include?(args[0])
|
28
|
+
stop_reason = catch(:stop) {
|
29
|
+
root_cmd.run(args, {}, hard_exit: true)
|
30
|
+
}
|
31
|
+
log pastel.red("Stopped: #{stop_reason}") if stop_reason
|
32
|
+
return
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
22
36
|
folder_name = File.basename(Dir.getwd)
|
23
|
-
log "Processing #{
|
37
|
+
log "Processing #{pastel.cyan(folder_name)} ..."
|
24
38
|
|
25
39
|
ENV["TF_IN_AUTOMATION"] = "1"
|
26
40
|
ENV["TF_INPUT"] = "0"
|
@@ -32,19 +46,16 @@ module MuxTf
|
|
32
46
|
return launch_cmd_loop(:error) unless upgrade_status == :ok
|
33
47
|
end
|
34
48
|
|
35
|
-
plan_status
|
49
|
+
plan_status = run_plan
|
36
50
|
|
37
51
|
case plan_status
|
38
52
|
when :ok
|
39
|
-
log "
|
53
|
+
log "exiting", depth: 1
|
40
54
|
when :error
|
41
|
-
log "something went wrong", depth: 1
|
42
55
|
launch_cmd_loop(plan_status)
|
43
|
-
when :changes
|
44
|
-
log "Printing Plan Summary ...", depth: 1
|
45
|
-
pretty_plan_summary(plan_filename)
|
56
|
+
when :changes # rubocop:disable Lint/DuplicateBranch
|
46
57
|
launch_cmd_loop(plan_status)
|
47
|
-
when :unknown
|
58
|
+
when :unknown # rubocop:disable Lint/DuplicateBranch
|
48
59
|
launch_cmd_loop(plan_status)
|
49
60
|
end
|
50
61
|
end
|
@@ -58,38 +69,105 @@ module MuxTf
|
|
58
69
|
def version_check
|
59
70
|
return unless VersionCheck.has_updates?
|
60
71
|
|
61
|
-
log
|
62
|
-
log "New version of #{
|
63
|
-
log "You are currently on version: #{
|
64
|
-
log "Latest version found is: #{
|
65
|
-
log "Run `#{
|
66
|
-
log
|
72
|
+
log pastel.yellow("=" * 80)
|
73
|
+
log "New version of #{pastel.cyan('mux_tf')} is available!"
|
74
|
+
log "You are currently on version: #{pastel.yellow(VersionCheck.current_gem_version)}"
|
75
|
+
log "Latest version found is: #{pastel.green(VersionCheck.latest_gem_version)}"
|
76
|
+
log "Run `#{pastel.green('gem install mux_tf')}` to update!"
|
77
|
+
log pastel.yellow("=" * 80)
|
67
78
|
end
|
68
79
|
|
69
|
-
|
70
|
-
|
71
|
-
|
80
|
+
# block is expected to return a touple, the first element is a list of remedies
|
81
|
+
# the rest are any additional results
|
82
|
+
def remedy_retry_helper(from:, level: 1, attempt: 0, &block)
|
83
|
+
catch(:abort) do
|
84
|
+
until attempt > 1
|
85
|
+
attempt += 1
|
86
|
+
remedies, *results = block.call
|
87
|
+
return results if remedies.empty?
|
88
|
+
|
89
|
+
remedy_status, _remedy_results = process_remedies(remedies, from: from, level: level)
|
90
|
+
return unless remedy_status
|
91
|
+
end
|
92
|
+
log "!! giving up because attempt: #{attempt}"
|
93
|
+
end
|
72
94
|
end
|
73
95
|
|
74
|
-
|
96
|
+
# returns boolean true if succeeded
|
97
|
+
def run_validate(level: 1)
|
98
|
+
remedy_retry_helper(from: :validate, level: level) do
|
99
|
+
validation_info = validate
|
100
|
+
PlanFormatter.print_validation_errors(validation_info)
|
101
|
+
remedies = PlanFormatter.process_validation(validation_info)
|
102
|
+
[remedies, validation_info]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def process_remedies(remedies, from: nil, level: 1, retry_count: 0) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
107
|
+
remedies = remedies.dup
|
108
|
+
remedy = nil
|
109
|
+
wrap_log = lambda do |msg, color: nil|
|
110
|
+
[
|
111
|
+
from ? pastel.cyan("#{from} -> ") : nil,
|
112
|
+
pastel.cyan(remedy ? "[remedy: #{remedy}]" : "[process remedies]"),
|
113
|
+
" ",
|
114
|
+
color ? pastel.decorate(msg, color) : msg,
|
115
|
+
" ",
|
116
|
+
level > 1 ? pastel.cyan("[lv #{level}]") : nil,
|
117
|
+
retry_count.positive? ? pastel.cyan("[try #{retry_count}]") : nil
|
118
|
+
].compact.join
|
119
|
+
end
|
120
|
+
results = {}
|
121
|
+
if retry_count > 5
|
122
|
+
log wrap_log["giving up because retry_count: #{retry_count}", color: :yellow], depth: 1
|
123
|
+
log wrap_log["unprocessed remedies: #{remedies.to_a}", color: :red], depth: 1
|
124
|
+
return [false, results]
|
125
|
+
end
|
75
126
|
if remedies.delete? :init
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
127
|
+
remedy = :init
|
128
|
+
log wrap_log["Running terraform init ..."], depth: 2
|
129
|
+
exit_code, meta = PlanFormatter.run_tf_init
|
130
|
+
print_errors_and_warnings(meta)
|
131
|
+
remedies = PlanFormatter.init_status_to_remedies(exit_code, meta)
|
132
|
+
status, r_results = process_remedies(remedies, from: from, level: level + 1)
|
133
|
+
results.merge!(r_results)
|
134
|
+
return [true, r_results] if status
|
135
|
+
end
|
136
|
+
if remedies.delete?(:plan)
|
137
|
+
remedy = :plan
|
138
|
+
log wrap_log["Running terraform plan ..."], depth: 2
|
139
|
+
plan_status = run_plan(retry_count: retry_count)
|
140
|
+
results[:plan_status] = plan_status
|
141
|
+
return [false, results] unless [:ok, :changes].include?(plan_status)
|
82
142
|
end
|
83
143
|
if remedies.delete? :reconfigure
|
84
|
-
|
85
|
-
|
86
|
-
|
144
|
+
remedy = :reconfigure
|
145
|
+
log wrap_log["Running terraform init ..."], depth: 2
|
146
|
+
result = remedy_retry_helper(from: :reconfigure, level: level + 1, attempt: retry_count) {
|
147
|
+
exit_code, meta = PlanFormatter.run_tf_init(reconfigure: true)
|
148
|
+
print_errors_and_warnings(meta)
|
149
|
+
remedies = PlanFormatter.init_status_to_remedies(exit_code, meta)
|
150
|
+
[remedies, exit_code, meta]
|
151
|
+
}
|
152
|
+
unless result
|
153
|
+
log wrap_log["Failed", color: :red], depth: 2
|
154
|
+
return [false, result]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
if remedies.delete? :user_error
|
158
|
+
remedy = :user_error
|
159
|
+
log wrap_log["user error encountered!", color: :red]
|
160
|
+
log wrap_log["-" * 40, color: :red]
|
161
|
+
log wrap_log["!! User Error, Please fix the issue and try again", color: :red]
|
162
|
+
log wrap_log["-" * 40, color: :red]
|
163
|
+
return [false, results]
|
87
164
|
end
|
88
165
|
unless remedies.empty?
|
89
|
-
|
90
|
-
|
166
|
+
remedy = nil
|
167
|
+
log wrap_log["Unprocessed remedies: #{remedies.to_a}", color: :red], depth: 1 if level == 1
|
168
|
+
return [false, results]
|
91
169
|
end
|
92
|
-
true
|
170
|
+
[true, results]
|
93
171
|
end
|
94
172
|
|
95
173
|
def validate
|
@@ -108,7 +186,7 @@ module MuxTf
|
|
108
186
|
when 2
|
109
187
|
[:changes, meta]
|
110
188
|
else
|
111
|
-
log
|
189
|
+
log pastel.yellow("terraform plan exited with an unknown exit code: #{exit_code}")
|
112
190
|
[:unknown, meta]
|
113
191
|
end
|
114
192
|
end
|
@@ -118,9 +196,9 @@ module MuxTf
|
|
118
196
|
|
119
197
|
case status
|
120
198
|
when :error, :unknown
|
121
|
-
log
|
199
|
+
log pastel.red("Dropping to command line so you can fix the issue!")
|
122
200
|
when :changes
|
123
|
-
log
|
201
|
+
log pastel.yellow("Dropping to command line so you can review the changes.")
|
124
202
|
end
|
125
203
|
cmd_loop(status)
|
126
204
|
end
|
@@ -135,9 +213,9 @@ module MuxTf
|
|
135
213
|
prompt = "#{folder_name} => "
|
136
214
|
case status
|
137
215
|
when :error, :unknown
|
138
|
-
prompt = "[#{
|
216
|
+
prompt = "[#{pastel.red(status.to_s)}] #{prompt}"
|
139
217
|
when :changes
|
140
|
-
prompt = "[#{
|
218
|
+
prompt = "[#{pastel.yellow(status.to_s)}] #{prompt}"
|
141
219
|
end
|
142
220
|
|
143
221
|
run_cmd_loop(prompt) do |cmd|
|
@@ -157,11 +235,31 @@ module MuxTf
|
|
157
235
|
root_cmd.add_command(upgrade_cmd)
|
158
236
|
root_cmd.add_command(reconfigure_cmd)
|
159
237
|
root_cmd.add_command(interactive_cmd)
|
238
|
+
root_cmd.add_command(plan_details_cmd)
|
160
239
|
|
161
240
|
root_cmd.add_command(exit_cmd)
|
241
|
+
root_cmd.add_command(define_cmd("help", summary: "Show help for commands") { |_opts, _args, cmd| puts cmd.supercommand.help })
|
162
242
|
root_cmd
|
163
243
|
end
|
164
244
|
|
245
|
+
def plan_summary_text
|
246
|
+
plan_filename = PlanFilenameGenerator.for_path
|
247
|
+
if File.exist?("#{plan_filename}.txt") && File.mtime("#{plan_filename}.txt").to_f >= File.mtime(plan_filename).to_f
|
248
|
+
File.read("#{plan_filename}.txt")
|
249
|
+
else
|
250
|
+
puts "Inspecting Changes ... #{plan_filename}"
|
251
|
+
data = PlanUtils.text_version_of_plan_show(plan_filename)
|
252
|
+
File.write("#{plan_filename}.txt", data)
|
253
|
+
data
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def plan_details_cmd
|
258
|
+
define_cmd("details", summary: "Show Plan Details") do |_opts, _args, _cmd|
|
259
|
+
puts plan_summary_text
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
165
263
|
def plan_cmd
|
166
264
|
define_cmd("plan", summary: "Re-run plan") do |_opts, _args, _cmd|
|
167
265
|
run_validate && run_plan
|
@@ -182,28 +280,30 @@ module MuxTf
|
|
182
280
|
|
183
281
|
def shell_cmd
|
184
282
|
define_cmd("shell", summary: "Open your default terminal in the current folder") do |_opts, _args, _cmd|
|
185
|
-
log
|
186
|
-
log
|
283
|
+
log pastel.yellow("Launching shell ...")
|
284
|
+
log pastel.yellow("When it exits you will be back at this prompt.")
|
187
285
|
system ENV.fetch("SHELL")
|
188
286
|
end
|
189
287
|
end
|
190
288
|
|
191
289
|
def force_unlock_cmd
|
192
|
-
define_cmd("force-unlock", summary: "Force unlock state after encountering a lock error!") do
|
290
|
+
define_cmd("force-unlock", summary: "Force unlock state after encountering a lock error!") do # rubocop:disable Metrics/BlockLength
|
193
291
|
prompt = TTY::Prompt.new(interrupt: :noop)
|
194
292
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
293
|
+
lock_info = @last_lock_info
|
294
|
+
|
295
|
+
if lock_info
|
296
|
+
table = TTY::Table.new(header: %w[Field Value])
|
297
|
+
table << ["Lock ID", lock_info[:lock_id]]
|
298
|
+
table << ["Operation", lock_info[:operation]]
|
299
|
+
table << ["Who", lock_info[:who]]
|
300
|
+
table << ["Created", lock_info[:created]]
|
200
301
|
|
201
|
-
|
302
|
+
puts table.render(:unicode, padding: [0, 1])
|
202
303
|
|
203
|
-
if @plan_meta && @plan_meta["error"] == "lock"
|
204
304
|
done = catch(:abort) {
|
205
|
-
if
|
206
|
-
"Are you sure you want to force unlock a lock for operation: #{
|
305
|
+
if lock_info[:operation] != "OperationTypePlan" && !prompt.yes?(
|
306
|
+
"Are you sure you want to force unlock a lock for operation: #{lock_info[:operation]}",
|
207
307
|
default: false
|
208
308
|
)
|
209
309
|
throw :abort
|
@@ -214,19 +314,19 @@ module MuxTf
|
|
214
314
|
default: false
|
215
315
|
)
|
216
316
|
|
217
|
-
status = tf_force_unlock(id:
|
317
|
+
status = tf_force_unlock(id: lock_info[:lock_id])
|
218
318
|
if status.success?
|
219
319
|
log "Done!"
|
220
320
|
else
|
221
|
-
log
|
321
|
+
log pastel.red("Failed with status: #{status}")
|
222
322
|
end
|
223
323
|
|
224
324
|
true
|
225
325
|
}
|
226
326
|
|
227
|
-
log
|
327
|
+
log pastel.yellow("Aborted") unless done
|
228
328
|
else
|
229
|
-
log
|
329
|
+
log pastel.red("No lock error or no plan ran!")
|
230
330
|
end
|
231
331
|
end
|
232
332
|
end
|
@@ -243,8 +343,9 @@ module MuxTf
|
|
243
343
|
|
244
344
|
def reconfigure_cmd
|
245
345
|
define_cmd("reconfigure", summary: "Reconfigure modules/plguins") do |_opts, _args, _cmd|
|
246
|
-
|
247
|
-
|
346
|
+
exit_code, meta = PlanFormatter.run_tf_init(reconfigure: true)
|
347
|
+
print_errors_and_warnings(meta)
|
348
|
+
if exit_code != 0
|
248
349
|
log meta.inspect unless meta.empty?
|
249
350
|
log "Reconfigure Failed!"
|
250
351
|
end
|
@@ -257,7 +358,7 @@ module MuxTf
|
|
257
358
|
begin
|
258
359
|
abort_message = catch(:abort) { plan.run_interactive }
|
259
360
|
if abort_message
|
260
|
-
log
|
361
|
+
log pastel.red("Aborted: #{abort_message}")
|
261
362
|
else
|
262
363
|
run_plan
|
263
364
|
end
|
@@ -268,8 +369,78 @@ module MuxTf
|
|
268
369
|
end
|
269
370
|
end
|
270
371
|
|
271
|
-
def
|
272
|
-
|
372
|
+
def print_errors_and_warnings(meta) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
373
|
+
message = []
|
374
|
+
message << pastel.yellow("#{meta[:warnings].length} Warnings") if meta[:warnings]
|
375
|
+
message << pastel.red("#{meta[:errors].length} Errors") if meta[:errors]
|
376
|
+
if message.length.positive?
|
377
|
+
log ""
|
378
|
+
log "Encountered: #{message.join(' and ')}"
|
379
|
+
log ""
|
380
|
+
end
|
381
|
+
|
382
|
+
meta[:warnings]&.each do |warning|
|
383
|
+
log "-" * 20
|
384
|
+
log pastel.yellow("Warning: #{warning[:message]}")
|
385
|
+
warning[:body]&.each do |line|
|
386
|
+
log pastel.yellow(line), depth: 1
|
387
|
+
end
|
388
|
+
log ""
|
389
|
+
end
|
390
|
+
|
391
|
+
meta[:errors]&.each do |error|
|
392
|
+
log "-" * 20
|
393
|
+
log pastel.red("Error: #{error[:message]}")
|
394
|
+
error[:body]&.each do |line|
|
395
|
+
log pastel.red(line), depth: 1
|
396
|
+
end
|
397
|
+
log ""
|
398
|
+
end
|
399
|
+
|
400
|
+
return unless message.length.positive?
|
401
|
+
|
402
|
+
log ""
|
403
|
+
end
|
404
|
+
|
405
|
+
def detect_remedies_from_plan(meta)
|
406
|
+
remedies = Set.new
|
407
|
+
meta[:errors]&.each do |error|
|
408
|
+
remedies << :plan if error[:message].include?("timeout while waiting for plugin to start")
|
409
|
+
end
|
410
|
+
remedies << :unlock if lock_error?(meta)
|
411
|
+
remedies
|
412
|
+
end
|
413
|
+
|
414
|
+
def lock_error?(meta)
|
415
|
+
meta && meta["error"] == "lock"
|
416
|
+
end
|
417
|
+
|
418
|
+
def extract_lock_info(meta)
|
419
|
+
{
|
420
|
+
lock_id: meta["ID"],
|
421
|
+
operation: meta["Operation"],
|
422
|
+
who: meta["Who"],
|
423
|
+
created: meta["Created"]
|
424
|
+
}
|
425
|
+
end
|
426
|
+
|
427
|
+
def run_plan(targets: [], level: 1, retry_count: 0)
|
428
|
+
plan_status, = remedy_retry_helper(from: :plan, level: level, attempt: retry_count) {
|
429
|
+
@last_lock_info = nil
|
430
|
+
|
431
|
+
plan_status, meta = create_plan(plan_filename, targets: targets)
|
432
|
+
|
433
|
+
print_errors_and_warnings(meta)
|
434
|
+
|
435
|
+
remedies = detect_remedies_from_plan(meta)
|
436
|
+
|
437
|
+
if remedies.include?(:unlock)
|
438
|
+
@last_lock_info = extract_lock_info(meta)
|
439
|
+
throw :abort, [plan_status, meta]
|
440
|
+
end
|
441
|
+
|
442
|
+
[remedies, plan_status, meta]
|
443
|
+
}
|
273
444
|
|
274
445
|
case plan_status
|
275
446
|
when :ok
|
@@ -277,25 +448,30 @@ module MuxTf
|
|
277
448
|
when :error
|
278
449
|
log "something went wrong", depth: 1
|
279
450
|
when :changes
|
280
|
-
|
281
|
-
|
451
|
+
unless ENV["JSON_PLAN"]
|
452
|
+
log "Printing Plan Summary ...", depth: 1
|
453
|
+
pretty_plan_summary(plan_filename)
|
454
|
+
end
|
455
|
+
puts plan_summary_text if ENV["JSON_PLAN"]
|
282
456
|
when :unknown
|
283
457
|
# nothing
|
284
458
|
end
|
459
|
+
|
285
460
|
plan_status
|
286
461
|
end
|
287
462
|
|
463
|
+
public :run_plan
|
464
|
+
|
288
465
|
def run_upgrade
|
289
466
|
exit_code, meta = PlanFormatter.run_tf_init(upgrade: true)
|
467
|
+
print_errors_and_warnings(meta)
|
290
468
|
case exit_code
|
291
469
|
when 0
|
292
470
|
[:ok, meta]
|
293
471
|
when 1
|
294
472
|
[:error, meta]
|
295
|
-
# when 2
|
296
|
-
# [:changes, meta]
|
297
473
|
else
|
298
|
-
log
|
474
|
+
log pastel.yellow("terraform init upgrade exited with an unknown exit code: #{exit_code}")
|
299
475
|
[:unknown, meta]
|
300
476
|
end
|
301
477
|
end
|
@@ -6,6 +6,7 @@ module MuxTf
|
|
6
6
|
extend PiotrbCliUtils::Util
|
7
7
|
extend PiotrbCliUtils::ShellHelpers
|
8
8
|
extend TerraformHelpers
|
9
|
+
import Coloring
|
9
10
|
|
10
11
|
class << self
|
11
12
|
def run(args)
|
@@ -33,7 +34,7 @@ module MuxTf
|
|
33
34
|
|
34
35
|
if options[:interactive]
|
35
36
|
abort_message = catch(:abort) { plan.run_interactive }
|
36
|
-
log
|
37
|
+
log pastel.red("Aborted: #{abort_message}") if abort_message
|
37
38
|
else
|
38
39
|
if options[:hierarchy]
|
39
40
|
plan.nested_summary.each do |line|
|
data/lib/mux_tf/cli.rb
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
module MuxTf
|
4
4
|
module Cli
|
5
|
+
extend PiotrbCliUtils::Util
|
6
|
+
|
5
7
|
def self.run(mode, args)
|
6
8
|
case mode
|
7
9
|
when :mux
|
8
|
-
require_relative "
|
10
|
+
require_relative "cli/mux"
|
9
11
|
MuxTf::Cli::Mux.run(args)
|
10
12
|
when :current
|
11
|
-
require_relative "
|
13
|
+
require_relative "cli/current"
|
12
14
|
MuxTf::Cli::Current.run(args)
|
13
15
|
when :plan_summary
|
14
|
-
require_relative "
|
16
|
+
require_relative "cli/plan_summary"
|
15
17
|
MuxTf::Cli::PlanSummary.run(args)
|
16
18
|
else
|
17
19
|
fail_with "unhandled mode: #{mode.inspect}"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MuxTf
|
4
|
+
module Coloring
|
5
|
+
def pastel
|
6
|
+
self.class.pastel
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(other)
|
10
|
+
other.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def pastel
|
15
|
+
instance = Pastel.new
|
16
|
+
instance.alias_color(:orange, :yellow)
|
17
|
+
instance.alias_color(:gray, :bright_black)
|
18
|
+
instance.alias_color(:grey, :bright_black)
|
19
|
+
instance
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|