mux_tf 0.15.0 → 0.17.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/lib/mux_tf/cli/current/plan_command.rb +131 -0
- data/lib/mux_tf/cli/current.rb +172 -206
- data/lib/mux_tf/cli/mux.rb +168 -5
- data/lib/mux_tf/cli/plan_summary.rb +12 -21
- data/lib/mux_tf/error_handling_methods.rb +79 -0
- data/lib/mux_tf/formatter_common.rb +257 -0
- data/lib/mux_tf/handlers/plan_handler.rb +8 -0
- data/lib/mux_tf/handlers.rb +6 -0
- data/lib/mux_tf/init_formatter.rb +306 -0
- data/lib/mux_tf/plan_formatter.rb +285 -602
- data/lib/mux_tf/plan_summary_handler.rb +52 -31
- data/lib/mux_tf/plan_utils.rb +215 -56
- data/lib/mux_tf/resource_tokenizer.rb +1 -1
- data/lib/mux_tf/stderr_line_handler.rb +145 -0
- data/lib/mux_tf/terraform_helpers.rb +46 -7
- data/lib/mux_tf/tmux.rb +55 -6
- data/lib/mux_tf/version.rb +1 -1
- data/lib/mux_tf/yaml_cache.rb +51 -34
- data/lib/mux_tf.rb +6 -12
- data/mux_tf.gemspec +12 -1
- metadata +110 -9
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
module MuxTf
|
5
|
+
class StderrLineHandler
|
6
|
+
include PiotrbCliUtils::Util
|
7
|
+
include Coloring
|
8
|
+
|
9
|
+
include ErrorHandlingMethods
|
10
|
+
|
11
|
+
attr_reader :meta
|
12
|
+
|
13
|
+
def initialize(operation: nil)
|
14
|
+
@operation = operation
|
15
|
+
@held_messages = []
|
16
|
+
@parser = StatefulParser.new(normalizer: pastel.method(:strip))
|
17
|
+
@meta = {}
|
18
|
+
setup_error_handling(@parser, from_states: [:none])
|
19
|
+
end
|
20
|
+
|
21
|
+
def transform_paths!(hash, key)
|
22
|
+
return unless hash[key]
|
23
|
+
|
24
|
+
if key == "prefix"
|
25
|
+
hash[key].strip!
|
26
|
+
hash[key].gsub!(/^\[/, "")
|
27
|
+
hash[key].gsub!(/\]$/, "")
|
28
|
+
end
|
29
|
+
|
30
|
+
hash[key].gsub!("#{Dir.getwd}/", "")
|
31
|
+
hash[key].gsub!(Dir.getwd, "")
|
32
|
+
|
33
|
+
hash[key].gsub!($LAST_MATCH_INFO[1], "<cache>/") if hash[key].match(%r{(\.terragrunt-cache/[^/]+/[^/]+/)})
|
34
|
+
|
35
|
+
hash
|
36
|
+
end
|
37
|
+
|
38
|
+
def handle(raw_line)
|
39
|
+
return if raw_line.strip.empty?
|
40
|
+
|
41
|
+
if raw_line =~ /Error when retrieving token from sso: Token has expired and refresh failed/
|
42
|
+
log "#{pastel.red('error')}: SSO Session expired.", depth: 2
|
43
|
+
return
|
44
|
+
end
|
45
|
+
|
46
|
+
# [✘] 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'
|
47
|
+
if raw_line =~ /error when retrieving credentials from custom process. please login using '([^']+)'/
|
48
|
+
unless @sso_expired
|
49
|
+
@sso_expired = true
|
50
|
+
log "#{pastel.red('error')}: SSO Session expired.", depth: 2
|
51
|
+
log "#{pastel.red('error')}: Run: #{$LAST_MATCH_INFO[1]}", depth: 2
|
52
|
+
end
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
if raw_line.strip[0] == "{" && raw_line.strip[-1] == "}"
|
57
|
+
begin
|
58
|
+
# assuming that stderr is JSON and TG logs
|
59
|
+
parsed_line = JSON.parse(raw_line)
|
60
|
+
transform_paths!(parsed_line, "msg")
|
61
|
+
transform_paths!(parsed_line, "prefix")
|
62
|
+
parsed_line["msg"].gsub!("#{Dir.getwd}/", "")
|
63
|
+
parsed_line["prefix"]&.strip!&.gsub!(/^\[/, "")&.gsub!(/\]$/, "") # rubocop:disable Style/SafeNavigationChainLength
|
64
|
+
parsed_line["prefix"]&.gsub!(Dir.getwd, "")
|
65
|
+
if @operation == :plan
|
66
|
+
handle_plan_json(parsed_line)
|
67
|
+
else
|
68
|
+
log format_tg_log_line(parsed_line), depth: 2
|
69
|
+
end
|
70
|
+
rescue JSON::ParserError => e
|
71
|
+
log "#{pastel.red('error')}: failed to parse JSON: #{e.message}", depth: 2
|
72
|
+
log raw_line.rstrip, depth: 2
|
73
|
+
end
|
74
|
+
else
|
75
|
+
@parser.parse(raw_line.rstrip) do |state, line|
|
76
|
+
# log raw_line.rstrip, depth: 2
|
77
|
+
log_unhandled_line(state, line, reason: "unexpected state in StderrLineHandler") unless handle_error_states(@meta, state, line)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def handle_plan_json(parsed_line)
|
83
|
+
if parsed_line["msg"] =~ /terraform invocation failed in/
|
84
|
+
@held_messages << format_tg_log_line(parsed_line)
|
85
|
+
elsif parsed_line["msg"] =~ /1 error occurred/ && parsed_line["msg"] =~ /exit status 2\n/
|
86
|
+
# 2 = Succeeded with non-empty diff (changes present)
|
87
|
+
# clear the held messages and swallow up this message too
|
88
|
+
@held_messages = []
|
89
|
+
else
|
90
|
+
# flush
|
91
|
+
log format_tg_log_line(parsed_line), depth: 2
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def flush
|
96
|
+
@held_messages.each do |msg|
|
97
|
+
log msg, depth: 2
|
98
|
+
end
|
99
|
+
@held_messages = []
|
100
|
+
end
|
101
|
+
|
102
|
+
def do_print_errors
|
103
|
+
print_errors(@meta) if @meta[:errors] && !@meta[:errors].empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
def merge_meta_into(other_meta)
|
107
|
+
[:errors, :warnings].each do |type|
|
108
|
+
if @meta[type]
|
109
|
+
other_meta[type] ||= []
|
110
|
+
other_meta[type] += @meta[type]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
extra_keys = @meta.keys - [:errors, :warnings]
|
115
|
+
return unless extra_keys.any?
|
116
|
+
|
117
|
+
log "Unhandled keys in stderr_handler.meta: #{extra_keys.inspect}"
|
118
|
+
log @meta.inspect
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def format_tg_log_line(line_data)
|
124
|
+
# {
|
125
|
+
# "level"=>"error",
|
126
|
+
# "msg"=>"terraform invocation failed in /Users/piotr/Work/janepods/accounts/eks-dev/unstable-1/kluster/.terragrunt-cache/Gqer3b7TGI4swB-Nw7Pe5DUIrus/JkQqfrQedXyGMwcl4yYfGocMcvk/modules/kluster",
|
127
|
+
# "prefix"=>"[/Users/piotr/Work/janepods/accounts/eks-dev/unstable-1/kluster] ",
|
128
|
+
# "time"=>"2024-02-28T16:14:28-08:00"
|
129
|
+
# }
|
130
|
+
|
131
|
+
msg = ""
|
132
|
+
msg += case line_data["level"]
|
133
|
+
when "info"
|
134
|
+
pastel.cyan(line_data["level"])
|
135
|
+
when "error"
|
136
|
+
pastel.red(line_data["level"])
|
137
|
+
else
|
138
|
+
pastel.orange(line_data["level"])
|
139
|
+
end
|
140
|
+
msg += ": #{line_data['msg']}"
|
141
|
+
msg += " [#{line_data['prefix']}]" if line_data["prefix"] && !line_data["prefix"].empty?
|
142
|
+
msg
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -11,6 +11,30 @@ module MuxTf
|
|
11
11
|
run_terraform(tf_prepare_command(["force-unlock", "-force", id], need_auth: true))
|
12
12
|
end
|
13
13
|
|
14
|
+
def tf_stream_helper(cmd, operation:, echo_stdout: false, &block)
|
15
|
+
# stdout = ""
|
16
|
+
|
17
|
+
stderr_handler = StderrLineHandler.new(operation: operation)
|
18
|
+
|
19
|
+
result_struct = stream_terraform(cmd, split_streams: true) { |(stream, raw_line)|
|
20
|
+
case stream
|
21
|
+
when :command
|
22
|
+
log "Running command: #{raw_line.strip} ...", depth: 2
|
23
|
+
when :stdout
|
24
|
+
# stdout += raw_line
|
25
|
+
print raw_line if echo_stdout
|
26
|
+
block&.call(:stdout, raw_line)
|
27
|
+
when :stderr
|
28
|
+
stderr_handler.handle(raw_line)
|
29
|
+
end
|
30
|
+
}
|
31
|
+
|
32
|
+
stderr_handler.flush
|
33
|
+
stderr_handler.do_print_errors
|
34
|
+
|
35
|
+
result_struct
|
36
|
+
end
|
37
|
+
|
14
38
|
def tf_apply(filename: nil, targets: [])
|
15
39
|
args = []
|
16
40
|
args << filename if filename
|
@@ -21,26 +45,38 @@ module MuxTf
|
|
21
45
|
end
|
22
46
|
|
23
47
|
cmd = tf_prepare_command(["apply", *args], need_auth: true)
|
24
|
-
|
48
|
+
|
49
|
+
tf_stream_helper(cmd, operation: :apply, echo_stdout: true)
|
25
50
|
end
|
26
51
|
|
27
52
|
def tf_validate
|
28
53
|
cmd = tf_prepare_command(["validate", "-json"], need_auth: true)
|
29
|
-
|
54
|
+
|
55
|
+
stdout = ""
|
56
|
+
|
57
|
+
tf_stream_helper(cmd, operation: :validate) do |stream, raw_line|
|
58
|
+
stdout += raw_line if stream == :stdout
|
59
|
+
end
|
60
|
+
|
61
|
+
throw :abort, false if stdout.strip.empty?
|
62
|
+
|
63
|
+
JSON.parse(stdout)
|
30
64
|
end
|
31
65
|
|
32
|
-
def tf_init(input: nil, upgrade: nil, reconfigure: nil, color: true, &block)
|
66
|
+
def tf_init(input: nil, upgrade: nil, reconfigure: nil, color: true, json: false, &block)
|
33
67
|
args = []
|
34
68
|
args << "-input=#{input.inspect}" unless input.nil?
|
35
69
|
args << "-upgrade" unless upgrade.nil?
|
36
70
|
args << "-reconfigure" unless reconfigure.nil?
|
37
71
|
args << "-no-color" unless color
|
72
|
+
args << "-json" if json
|
38
73
|
|
39
74
|
cmd = tf_prepare_command(["init", *args], need_auth: true)
|
40
|
-
|
75
|
+
stream_terraform(cmd, split_streams: true, &block)
|
41
76
|
end
|
42
77
|
|
43
|
-
def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, targets: [], json: false,
|
78
|
+
def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, targets: [], json: false, split_streams: false,
|
79
|
+
&block)
|
44
80
|
args = []
|
45
81
|
args += ["-out", out]
|
46
82
|
args << "-input=#{input.inspect}" unless input.nil?
|
@@ -55,7 +91,7 @@ module MuxTf
|
|
55
91
|
end
|
56
92
|
|
57
93
|
cmd = tf_prepare_command(["plan", *args], need_auth: true)
|
58
|
-
stream_or_run_terraform(cmd, split_streams: json, &block)
|
94
|
+
stream_or_run_terraform(cmd, split_streams: json || split_streams, &block)
|
59
95
|
end
|
60
96
|
|
61
97
|
def tf_show(file, json: false, capture: false)
|
@@ -132,7 +168,10 @@ module MuxTf
|
|
132
168
|
stderr_thread.join
|
133
169
|
output_queue.close
|
134
170
|
end
|
135
|
-
|
171
|
+
until output_queue.closed? && output_queue.empty?
|
172
|
+
value = output_queue.pop
|
173
|
+
yield(value) unless value.nil?
|
174
|
+
end
|
136
175
|
wait_thr.value # Process::Status object returned.
|
137
176
|
end
|
138
177
|
end
|
data/lib/mux_tf/tmux.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
+
require "open3"
|
4
5
|
|
5
6
|
module MuxTf
|
6
7
|
module Tmux
|
@@ -23,6 +24,13 @@ module MuxTf
|
|
23
24
|
panes.find { |pane| pane[:name] == name }
|
24
25
|
end
|
25
26
|
|
27
|
+
def list_panes
|
28
|
+
`tmux list-panes -F "\#{pane_id},\#{pane_index},\#{pane_title}"`.strip.split("\n").map do |row|
|
29
|
+
x = row.split(",")
|
30
|
+
{ id: x[0], index: x[1], name: x[2] }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
26
34
|
def list_windows
|
27
35
|
`tmux list-windows -F "\#{window_id},\#{window_index},\#{window_name}"`.strip.split("\n").map do |row|
|
28
36
|
x = row.split(",")
|
@@ -30,8 +38,15 @@ module MuxTf
|
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
33
|
-
def new_session(name)
|
34
|
-
|
41
|
+
def new_session(name, cwd: nil, cmd: nil)
|
42
|
+
parts = [
|
43
|
+
"new-session",
|
44
|
+
"-s #{name.inspect}",
|
45
|
+
"-d",
|
46
|
+
cwd ? "-c #{cwd}" : nil,
|
47
|
+
cmd&.inspect
|
48
|
+
].compact
|
49
|
+
tmux parts.join(" ")
|
35
50
|
end
|
36
51
|
|
37
52
|
def select_pane(name)
|
@@ -50,8 +65,23 @@ module MuxTf
|
|
50
65
|
tmux "select-layout tiled"
|
51
66
|
end
|
52
67
|
|
53
|
-
def
|
54
|
-
|
68
|
+
def attach_control(name, on_line:, on_spawn:)
|
69
|
+
parts = [
|
70
|
+
"-C",
|
71
|
+
"attach",
|
72
|
+
"-t #{name.inspect}"
|
73
|
+
].compact
|
74
|
+
tmux parts.join(" "), raise_on_error: false, mode: :popen, on_line: on_line, on_spawn: on_spawn
|
75
|
+
end
|
76
|
+
|
77
|
+
def attach(name, cc: false, control: false)
|
78
|
+
parts = [
|
79
|
+
cc ? "-CC" : nil,
|
80
|
+
control ? "-C" : nil,
|
81
|
+
"attach",
|
82
|
+
"-t #{name.inspect}"
|
83
|
+
].compact
|
84
|
+
tmux parts.join(" "), raise_on_error: false
|
55
85
|
end
|
56
86
|
|
57
87
|
def kill_pane(pane_id)
|
@@ -75,7 +105,7 @@ module MuxTf
|
|
75
105
|
|
76
106
|
parts = [
|
77
107
|
"split-window",
|
78
|
-
cwd
|
108
|
+
cwd ? "-c #{cwd}" : nil,
|
79
109
|
mode_part,
|
80
110
|
"-t #{target_pane.inspect}",
|
81
111
|
cmd&.inspect
|
@@ -89,7 +119,7 @@ module MuxTf
|
|
89
119
|
@tmux_bin ||= `which tmux`.strip
|
90
120
|
end
|
91
121
|
|
92
|
-
def tmux(cmd, raise_on_error: true, mode: :system)
|
122
|
+
def tmux(cmd, raise_on_error: true, mode: :system, on_line: nil, on_spawn: nil)
|
93
123
|
case mode
|
94
124
|
when :system
|
95
125
|
# puts " => tmux #{cmd}"
|
@@ -102,6 +132,25 @@ module MuxTf
|
|
102
132
|
true
|
103
133
|
when :exec
|
104
134
|
exec tmux_bin, *Shellwords.shellwords(cmd)
|
135
|
+
when :popen
|
136
|
+
Open3.popen3(tmux_bin, *Shellwords.shellwords(cmd)) do |stdin, stdout, stderr, wait_thr|
|
137
|
+
on_spawn&.call(stdin, wait_thr)
|
138
|
+
Thread.new do
|
139
|
+
until stdout.closed? || stdout.eof?
|
140
|
+
line = stdout.gets
|
141
|
+
on_line&.call(:stdout, line)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
Thread.new do
|
145
|
+
until stderr.closed? || stderr.eof?
|
146
|
+
line = stderr.gets
|
147
|
+
on_line&.call(:stderr, line)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
# pid = wait_thr.pid
|
151
|
+
exit_status = wait_thr.value
|
152
|
+
fail_with("`tmux #{cmd}' failed with code: #{exit_status}") if raise_on_error && exit_status != 0
|
153
|
+
end
|
105
154
|
end
|
106
155
|
end
|
107
156
|
end
|
data/lib/mux_tf/version.rb
CHANGED
data/lib/mux_tf/yaml_cache.rb
CHANGED
@@ -3,46 +3,63 @@
|
|
3
3
|
require "yaml/store"
|
4
4
|
|
5
5
|
# Ruby 2.7's YAML doesn't have a :unsafe_load method .. so we skip all that
|
6
|
-
if YAML.singleton_methods.include?(:unsafe_load)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
6
|
+
# if YAML.singleton_methods.include?(:unsafe_load)
|
7
|
+
# module YAML
|
8
|
+
# # Explaination from @h4xnoodle:
|
9
|
+
# #
|
10
|
+
# # Since ruby 3+ and psych 4+, the yaml loading became extra safe so the
|
11
|
+
# # expired_at timestamp in the yaml cache is no longer parsing for whatever reason.
|
12
|
+
# #
|
13
|
+
# # Attempts were made with
|
14
|
+
# #
|
15
|
+
# # `@store = YAML::Store.new path`
|
16
|
+
# # =>
|
17
|
+
# # `@store = YAML::Store.new(path, { aliases: true, permitted_classes: [Time] })`
|
18
|
+
# # to get it to work but that didn't help, so decided to just bypass the safe
|
19
|
+
# # loading, since the file is controlled by us for the version checking.
|
20
|
+
# #
|
21
|
+
# # This is to override the way that psych seems to be loading YAML.
|
22
|
+
# # Instead of using 'load' which needs work to permit the 'Time' class
|
23
|
+
# # (which from above I tried that and it wasn't working so I decided to just
|
24
|
+
# # bypass and use what it was doing before).
|
25
|
+
# # This brings us back to the equivalent that was working before in that unsafe
|
26
|
+
# # load was used before the psych upgrade.
|
27
|
+
# #
|
28
|
+
# # This change: https://my.diffend.io/gems/psych/3.3.2/4.0.0
|
29
|
+
# # is the changes that 'cause the problem' and so I'm 'fixing it' by using the old equivalent.
|
30
|
+
# #
|
31
|
+
# # Maybe the yaml cache needs more work to have
|
32
|
+
# # `YAML::Store.new(path, { aliases: true, permitted_classes: [Time] }) work.`
|
33
|
+
# #
|
34
|
+
# class << self
|
35
|
+
# undef load # avoid a warning about the next line redefining load
|
36
|
+
# alias load unsafe_load
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
|
41
|
+
module MuxTf
|
42
|
+
class UnsafeYamlStore < YAML::Store
|
43
|
+
def initialize(*args)
|
44
|
+
super
|
45
|
+
@opt[:permitted_classes] ||= [Symbol]
|
46
|
+
end
|
47
|
+
|
48
|
+
# basically have to override the whole load method, since it doesn't allow customization of the allowed classes ..
|
49
|
+
def load(content)
|
50
|
+
table = YAML.safe_load(content, **@opt)
|
51
|
+
if [false, nil].include?(table)
|
52
|
+
{}
|
53
|
+
else
|
54
|
+
table
|
55
|
+
end
|
37
56
|
end
|
38
57
|
end
|
39
|
-
end
|
40
58
|
|
41
|
-
module MuxTf
|
42
59
|
class YamlCache
|
43
60
|
def initialize(path, default_ttl:)
|
44
61
|
@default_ttl = default_ttl
|
45
|
-
@store =
|
62
|
+
@store = UnsafeYamlStore.new path, { aliases: true, permitted_classes: [Symbol, Time] }
|
46
63
|
end
|
47
64
|
|
48
65
|
def set(key, value, ttl: @default_ttl)
|
data/lib/mux_tf.rb
CHANGED
@@ -26,19 +26,13 @@ require "diff/lcs"
|
|
26
26
|
require "diff/lcs/string"
|
27
27
|
require "diff/lcs/hunk"
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
require_relative "mux_tf/cli"
|
34
|
-
require_relative "mux_tf/tmux"
|
35
|
-
require_relative "mux_tf/terraform_helpers"
|
36
|
-
require_relative "mux_tf/plan_formatter"
|
37
|
-
require_relative "mux_tf/version_check"
|
38
|
-
require_relative "mux_tf/yaml_cache"
|
39
|
-
require_relative "mux_tf/plan_summary_handler"
|
40
|
-
require_relative "mux_tf/plan_utils"
|
29
|
+
require "zeitwerk"
|
30
|
+
loader = Zeitwerk::Loader.for_gem
|
31
|
+
loader.ignore("#{__dir__}/deps.rb")
|
32
|
+
loader.setup
|
41
33
|
|
42
34
|
module MuxTf
|
43
35
|
ROOT = File.expand_path(File.join(__dir__, ".."))
|
44
36
|
end
|
37
|
+
|
38
|
+
loader.eager_load
|
data/mux_tf.gemspec
CHANGED
@@ -29,14 +29,25 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
|
+
# below activesupport are deps which cause warnings in ruby 3.3
|
32
33
|
spec.add_dependency "activesupport", "< 7.0.0"
|
34
|
+
spec.add_dependency "base64"
|
35
|
+
spec.add_dependency "bigdecimal"
|
36
|
+
spec.add_dependency "mutex_m"
|
37
|
+
|
33
38
|
spec.add_dependency "awesome_print"
|
34
39
|
spec.add_dependency "diff-lcs"
|
35
40
|
spec.add_dependency "dotenv"
|
36
41
|
spec.add_dependency "hashdiff"
|
37
42
|
spec.add_dependency "pastel"
|
38
|
-
spec.add_dependency "piotrb_cli_utils", "~> 0.
|
43
|
+
spec.add_dependency "piotrb_cli_utils", "~> 0.2.0"
|
39
44
|
spec.add_dependency "stateful_parser", "~> 0.1.1"
|
40
45
|
spec.add_dependency "tty-prompt"
|
41
46
|
spec.add_dependency "tty-table"
|
47
|
+
spec.add_dependency "zeitwerk", "~> 2.6"
|
48
|
+
|
49
|
+
# stdlib suff
|
50
|
+
spec.add_dependency "benchmark"
|
51
|
+
spec.add_dependency "ostruct"
|
52
|
+
spec.add_dependency "pstore"
|
42
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mux_tf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Banasik
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-05-12 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activesupport
|
@@ -24,6 +23,48 @@ dependencies:
|
|
24
23
|
- - "<"
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: 7.0.0
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: base64
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: bigdecimal
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: mutex_m
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
27
68
|
- !ruby/object:Gem::Dependency
|
28
69
|
name: awesome_print
|
29
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +141,14 @@ dependencies:
|
|
100
141
|
requirements:
|
101
142
|
- - "~>"
|
102
143
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
144
|
+
version: 0.2.0
|
104
145
|
type: :runtime
|
105
146
|
prerelease: false
|
106
147
|
version_requirements: !ruby/object:Gem::Requirement
|
107
148
|
requirements:
|
108
149
|
- - "~>"
|
109
150
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
151
|
+
version: 0.2.0
|
111
152
|
- !ruby/object:Gem::Dependency
|
112
153
|
name: stateful_parser
|
113
154
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,7 +191,62 @@ dependencies:
|
|
150
191
|
- - ">="
|
151
192
|
- !ruby/object:Gem::Version
|
152
193
|
version: '0'
|
153
|
-
|
194
|
+
- !ruby/object:Gem::Dependency
|
195
|
+
name: zeitwerk
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - "~>"
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '2.6'
|
201
|
+
type: :runtime
|
202
|
+
prerelease: false
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - "~>"
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '2.6'
|
208
|
+
- !ruby/object:Gem::Dependency
|
209
|
+
name: benchmark
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
type: :runtime
|
216
|
+
prerelease: false
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - ">="
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: ostruct
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - ">="
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
type: :runtime
|
230
|
+
prerelease: false
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
- !ruby/object:Gem::Dependency
|
237
|
+
name: pstore
|
238
|
+
requirement: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - ">="
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: '0'
|
243
|
+
type: :runtime
|
244
|
+
prerelease: false
|
245
|
+
version_requirements: !ruby/object:Gem::Requirement
|
246
|
+
requirements:
|
247
|
+
- - ">="
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '0'
|
154
250
|
email:
|
155
251
|
- piotr@jane.app
|
156
252
|
executables:
|
@@ -167,14 +263,21 @@ files:
|
|
167
263
|
- lib/mux_tf.rb
|
168
264
|
- lib/mux_tf/cli.rb
|
169
265
|
- lib/mux_tf/cli/current.rb
|
266
|
+
- lib/mux_tf/cli/current/plan_command.rb
|
170
267
|
- lib/mux_tf/cli/mux.rb
|
171
268
|
- lib/mux_tf/cli/plan_summary.rb
|
172
269
|
- lib/mux_tf/coloring.rb
|
270
|
+
- lib/mux_tf/error_handling_methods.rb
|
271
|
+
- lib/mux_tf/formatter_common.rb
|
272
|
+
- lib/mux_tf/handlers.rb
|
273
|
+
- lib/mux_tf/handlers/plan_handler.rb
|
274
|
+
- lib/mux_tf/init_formatter.rb
|
173
275
|
- lib/mux_tf/plan_filename_generator.rb
|
174
276
|
- lib/mux_tf/plan_formatter.rb
|
175
277
|
- lib/mux_tf/plan_summary_handler.rb
|
176
278
|
- lib/mux_tf/plan_utils.rb
|
177
279
|
- lib/mux_tf/resource_tokenizer.rb
|
280
|
+
- lib/mux_tf/stderr_line_handler.rb
|
178
281
|
- lib/mux_tf/terraform_helpers.rb
|
179
282
|
- lib/mux_tf/tmux.rb
|
180
283
|
- lib/mux_tf/version.rb
|
@@ -188,7 +291,6 @@ metadata:
|
|
188
291
|
rubygems_mfa_required: 'true'
|
189
292
|
homepage_uri: https://github.com/piotrb/mux_tf
|
190
293
|
source_code_uri: https://github.com/piotrb/mux_tf
|
191
|
-
post_install_message:
|
192
294
|
rdoc_options: []
|
193
295
|
require_paths:
|
194
296
|
- lib
|
@@ -203,8 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
305
|
- !ruby/object:Gem::Version
|
204
306
|
version: '0'
|
205
307
|
requirements: []
|
206
|
-
rubygems_version: 3.2
|
207
|
-
signing_key:
|
308
|
+
rubygems_version: 3.6.2
|
208
309
|
specification_version: 4
|
209
310
|
summary: Terraform Multiplexing Scripts
|
210
311
|
test_files: []
|