mux_tf 0.8.4 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/tf_current +1 -1
- data/exe/tf_mux +1 -1
- data/exe/tf_plan_summary +1 -1
- data/lib/deps.rb +2 -0
- data/lib/mux_tf/cli/current.rb +27 -27
- data/lib/mux_tf/cli/mux.rb +2 -2
- data/lib/mux_tf/cli/plan_summary.rb +7 -13
- data/lib/mux_tf/once_helper.rb +9 -11
- data/lib/mux_tf/plan_filename_generator.rb +12 -0
- data/lib/mux_tf/plan_formatter.rb +44 -41
- data/lib/mux_tf/plan_summary_handler.rb +116 -121
- data/lib/mux_tf/resource_tokenizer.rb +59 -55
- data/lib/mux_tf/terraform_helpers.rb +17 -15
- data/lib/mux_tf/tmux.rb +4 -6
- data/lib/mux_tf/version.rb +1 -1
- data/lib/mux_tf/version_check.rb +4 -2
- data/lib/mux_tf/yaml_cache.rb +41 -36
- data/lib/mux_tf.rb +3 -0
- data/mux_tf.gemspec +2 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b79dc73fcdc056b82b415b35dbb624b69e70edf3bc6db7852d8e2ea06f95c1ce
|
4
|
+
data.tar.gz: 119261f6a5f86ff78319cf411d1f24ff35f2c13262a427d3dd3ec990bd4fbd09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dce2287920bef8ea5eafd6b8565b7c2a7b6799ceb4514739a3aa7d7dc5fe0bcb840275824faf824294309b929a40698dc6203ed2755071238ed9008409865277
|
7
|
+
data.tar.gz: 92da3b7540fee9234c8d2b9ecc2cb6b8a4027c8644549777417aff862a3babdb5f66deeb1bd815f7ef43abf256305f26602efe4c93308176a7023d92845125f2
|
data/exe/tf_current
CHANGED
data/exe/tf_mux
CHANGED
data/exe/tf_plan_summary
CHANGED
data/lib/deps.rb
CHANGED
data/lib/mux_tf/cli/current.rb
CHANGED
@@ -10,8 +10,6 @@ module MuxTf
|
|
10
10
|
extend PiotrbCliUtils::CriCommandSupport
|
11
11
|
extend PiotrbCliUtils::CmdLoop
|
12
12
|
|
13
|
-
PLAN_FILENAME = "foo.tfplan"
|
14
|
-
|
15
13
|
class << self
|
16
14
|
def run(args)
|
17
15
|
version_check
|
@@ -30,11 +28,11 @@ module MuxTf
|
|
30
28
|
return launch_cmd_loop(:error) unless run_validate
|
31
29
|
|
32
30
|
if ENV["TF_UPGRADE"]
|
33
|
-
upgrade_status,
|
31
|
+
upgrade_status, _upgrade_meta = run_upgrade
|
34
32
|
return launch_cmd_loop(:error) unless upgrade_status == :ok
|
35
33
|
end
|
36
34
|
|
37
|
-
plan_status, @plan_meta = create_plan(
|
35
|
+
plan_status, @plan_meta = create_plan(plan_filename)
|
38
36
|
|
39
37
|
case plan_status
|
40
38
|
when :ok
|
@@ -44,7 +42,7 @@ module MuxTf
|
|
44
42
|
launch_cmd_loop(plan_status)
|
45
43
|
when :changes
|
46
44
|
log "Printing Plan Summary ...", depth: 1
|
47
|
-
pretty_plan_summary(
|
45
|
+
pretty_plan_summary(plan_filename)
|
48
46
|
launch_cmd_loop(plan_status)
|
49
47
|
when :unknown
|
50
48
|
launch_cmd_loop(plan_status)
|
@@ -59,17 +57,21 @@ module MuxTf
|
|
59
57
|
exit 1
|
60
58
|
end
|
61
59
|
|
60
|
+
def plan_filename
|
61
|
+
PlanFilenameGenerator.for_path
|
62
|
+
end
|
63
|
+
|
62
64
|
private
|
63
65
|
|
64
66
|
def version_check
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
return unless VersionCheck.has_updates?
|
68
|
+
|
69
|
+
log Paint["=" * 80, :yellow]
|
70
|
+
log "New version of #{Paint['mux_tf', :cyan]} is available!"
|
71
|
+
log "You are currently on version: #{Paint[VersionCheck.current_gem_version, :yellow]}"
|
72
|
+
log "Latest version found is: #{Paint[VersionCheck.latest_gem_version, :green]}"
|
73
|
+
log "Run `#{Paint['gem install mux_tf', :green]}` to update!"
|
74
|
+
log Paint["=" * 80, :yellow]
|
73
75
|
end
|
74
76
|
|
75
77
|
def run_validate
|
@@ -176,7 +178,7 @@ module MuxTf
|
|
176
178
|
|
177
179
|
def apply_cmd
|
178
180
|
define_cmd("apply", summary: "Apply the current plan") do |_opts, _args, _cmd|
|
179
|
-
status = tf_apply(filename:
|
181
|
+
status = tf_apply(filename: plan_filename)
|
180
182
|
if status.success?
|
181
183
|
plan_status = run_plan
|
182
184
|
throw :stop, :done if plan_status == :ok
|
@@ -190,7 +192,7 @@ module MuxTf
|
|
190
192
|
define_cmd("shell", summary: "Open your default terminal in the current folder") do |_opts, _args, _cmd|
|
191
193
|
log Paint["Launching shell ...", :yellow]
|
192
194
|
log Paint["When it exits you will be back at this prompt.", :yellow]
|
193
|
-
system ENV
|
195
|
+
system ENV.fetch("SHELL")
|
194
196
|
end
|
195
197
|
end
|
196
198
|
|
@@ -208,11 +210,11 @@ module MuxTf
|
|
208
210
|
|
209
211
|
if @plan_meta && @plan_meta["error"] == "lock"
|
210
212
|
done = catch(:abort) {
|
211
|
-
if @plan_meta["Operation"] != "OperationTypePlan"
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
213
|
+
if @plan_meta["Operation"] != "OperationTypePlan" && !prompt.yes?(
|
214
|
+
"Are you sure you want to force unlock a lock for operation: #{@plan_meta['Operation']}",
|
215
|
+
default: false
|
216
|
+
)
|
217
|
+
throw :abort
|
216
218
|
end
|
217
219
|
|
218
220
|
throw :abort unless prompt.yes?(
|
@@ -259,17 +261,15 @@ module MuxTf
|
|
259
261
|
|
260
262
|
def interactive_cmd
|
261
263
|
define_cmd("interactive", summary: "Apply interactively") do |_opts, _args, _cmd|
|
262
|
-
plan = PlanSummaryHandler.from_file(
|
264
|
+
plan = PlanSummaryHandler.from_file(plan_filename)
|
263
265
|
begin
|
264
|
-
abort_message = catch
|
265
|
-
plan.run_interactive
|
266
|
-
end
|
266
|
+
abort_message = catch(:abort) { plan.run_interactive }
|
267
267
|
if abort_message
|
268
268
|
log Paint["Aborted: #{abort_message}", :red]
|
269
269
|
else
|
270
270
|
run_plan
|
271
271
|
end
|
272
|
-
rescue Exception => e
|
272
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
273
273
|
log e.full_message
|
274
274
|
log "Interactive Apply Failed!"
|
275
275
|
end
|
@@ -277,7 +277,7 @@ module MuxTf
|
|
277
277
|
end
|
278
278
|
|
279
279
|
def run_plan(targets: [])
|
280
|
-
plan_status, @plan_meta = create_plan(
|
280
|
+
plan_status, @plan_meta = create_plan(plan_filename, targets: targets)
|
281
281
|
|
282
282
|
case plan_status
|
283
283
|
when :ok
|
@@ -286,7 +286,7 @@ module MuxTf
|
|
286
286
|
log "something went wrong", depth: 1
|
287
287
|
when :changes
|
288
288
|
log "Printing Plan Summary ...", depth: 1
|
289
|
-
pretty_plan_summary(
|
289
|
+
pretty_plan_summary(plan_filename)
|
290
290
|
when :unknown
|
291
291
|
# nothing
|
292
292
|
end
|
data/lib/mux_tf/cli/mux.rb
CHANGED
@@ -13,7 +13,7 @@ module MuxTf
|
|
13
13
|
backup = {}
|
14
14
|
Bundler.with_original_env do
|
15
15
|
ENV.keys.grep(/^(RBENV_|RUBYLIB)/).each do |key|
|
16
|
-
backup[key] = ENV
|
16
|
+
backup[key] = ENV.fetch(key)
|
17
17
|
ENV.delete(key)
|
18
18
|
end
|
19
19
|
yield
|
@@ -104,7 +104,7 @@ module MuxTf
|
|
104
104
|
ignored += ENV["MUX_IGNORE"].split(",") if ENV["MUX_IGNORE"]
|
105
105
|
|
106
106
|
dirs = Dir["**/.terraform.lock.hcl"].map { |f| File.dirname(f) }
|
107
|
-
dirs.reject!
|
107
|
+
dirs.reject! do |d| d.in?(ignored) end
|
108
108
|
|
109
109
|
dirs
|
110
110
|
end
|
@@ -23,23 +23,17 @@ module MuxTf
|
|
23
23
|
end
|
24
24
|
}.parse!(args)
|
25
25
|
|
26
|
-
if options[:interactive]
|
27
|
-
raise "must specify plan file in interactive mode" if args[0].blank?
|
28
|
-
end
|
26
|
+
raise "must specify plan file in interactive mode" if options[:interactive] && args[0].blank?
|
29
27
|
|
30
28
|
plan = if args[0]
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
PlanSummaryHandler.from_file(args[0])
|
30
|
+
else
|
31
|
+
PlanSummaryHandler.from_data(JSON.parse($stdin.read))
|
32
|
+
end
|
35
33
|
|
36
34
|
if options[:interactive]
|
37
|
-
abort_message = catch
|
38
|
-
|
39
|
-
end
|
40
|
-
if abort_message
|
41
|
-
log Paint["Aborted: #{abort_message}", :red]
|
42
|
-
end
|
35
|
+
abort_message = catch(:abort) { plan.run_interactive }
|
36
|
+
log Paint["Aborted: #{abort_message}", :red] if abort_message
|
43
37
|
else
|
44
38
|
if options[:hierarchy]
|
45
39
|
plan.nested_summary.each do |line|
|
data/lib/mux_tf/once_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MuxTf
|
2
4
|
class OnceHelper
|
3
5
|
# once = OnceHelper.new
|
@@ -5,25 +7,21 @@ module MuxTf
|
|
5
7
|
|
6
8
|
class StateEvaluator
|
7
9
|
def initialize(once_helper, new_state)
|
8
|
-
if once_helper.state
|
10
|
+
if once_helper.state == new_state
|
11
|
+
@path = :otherwise
|
12
|
+
else
|
9
13
|
once_helper.state = new_state
|
10
14
|
@path = :once
|
11
|
-
else
|
12
|
-
@path = :otherwise
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
def once
|
17
|
-
if @path == :then
|
18
|
-
yield
|
19
|
-
end
|
18
|
+
def once
|
19
|
+
yield if @path == :then
|
20
20
|
self
|
21
21
|
end
|
22
22
|
|
23
|
-
def otherwise
|
24
|
-
if @path == :otherwise
|
25
|
-
yield
|
26
|
-
end
|
23
|
+
def otherwise
|
24
|
+
yield if @path == :otherwise
|
27
25
|
self
|
28
26
|
end
|
29
27
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MuxTf
|
4
|
+
class PlanFilenameGenerator
|
5
|
+
def self.for_path(path = Dir.getwd)
|
6
|
+
folder_name = File.basename(path)
|
7
|
+
temp_dir = Dir.tmpdir
|
8
|
+
hash = Digest::MD5.hexdigest(path)
|
9
|
+
"#{temp_dir}/#{folder_name}-#{hash}.tfplan"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -6,7 +6,7 @@ module MuxTf
|
|
6
6
|
extend PiotrbCliUtils::Util
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def pretty_plan(filename, targets: [])
|
9
|
+
def pretty_plan(filename, targets: []) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
10
10
|
pastel = Pastel.new
|
11
11
|
|
12
12
|
once = OnceHelper.new
|
@@ -15,11 +15,12 @@ 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|Error:)/,
|
19
|
-
parser.state(:reading, /: (Reading...|Read complete after)/,
|
18
|
+
parser.state(:error, /(╷|Error locking state|Error:)/, [:none, :blank, :info, :reading])
|
19
|
+
parser.state(:reading, /: (Reading...|Read complete after)/, [:none, :info, :reading])
|
20
20
|
parser.state(:none, /^$/, [:reading])
|
21
|
-
parser.state(:refreshing, /^.+: Refreshing state... \[id=/,
|
22
|
-
parser.state(:refreshing, /Refreshing Terraform state in-memory prior to plan.../,
|
21
|
+
parser.state(:refreshing, /^.+: Refreshing state... \[id=/, [:none, :info, :reading])
|
22
|
+
parser.state(:refreshing, /Refreshing Terraform state in-memory prior to plan.../,
|
23
|
+
[:none, :blank, :info, :reading])
|
23
24
|
parser.state(:refresh_done, /^----------+$/, [:refreshing])
|
24
25
|
parser.state(:refresh_done, /^$/, [:refreshing])
|
25
26
|
parser.state(:plan_info, /Terraform will perform the following actions:/, [:refresh_done, :none])
|
@@ -31,7 +32,7 @@ module MuxTf
|
|
31
32
|
parser.state(:error_lock_info, /Lock Info/, [:error])
|
32
33
|
parser.state(:error, /^$/, [:error_lock_info])
|
33
34
|
|
34
|
-
parser.state(:plan_error, /^╷|Error: /,
|
35
|
+
parser.state(:plan_error, /^╷|Error: /, [:refreshing, :refresh_done])
|
35
36
|
|
36
37
|
status = tf_plan(out: filename, detailed_exitcode: true, compact_warnings: true, targets: targets) { |raw_line|
|
37
38
|
parser.parse(raw_line.rstrip) do |state, line|
|
@@ -65,13 +66,11 @@ module MuxTf
|
|
65
66
|
meta["error"] = "lock"
|
66
67
|
log Paint[line, :red], depth: 2
|
67
68
|
when :plan_error
|
68
|
-
once.for(state).once
|
69
|
+
once.for(state).once do puts end
|
69
70
|
meta["error"] = "refresh"
|
70
71
|
log Paint[line, :red], depth: 2
|
71
72
|
when :error_lock_info
|
72
|
-
if line =~ /([A-Z]
|
73
|
-
meta[$LAST_MATCH_INFO[1]] = $LAST_MATCH_INFO[2]
|
74
|
-
end
|
73
|
+
meta[$LAST_MATCH_INFO[1]] = $LAST_MATCH_INFO[2] if line =~ /([A-Z]+\S+)+:\s+(.+)$/
|
75
74
|
log Paint[line, :red], depth: 2
|
76
75
|
when :refreshing
|
77
76
|
once.for(state).once {
|
@@ -80,16 +79,16 @@ module MuxTf
|
|
80
79
|
print "."
|
81
80
|
}
|
82
81
|
when :plan_legend
|
83
|
-
once.for(state).once
|
82
|
+
once.for(state).once do puts end
|
84
83
|
log line, depth: 2
|
85
84
|
when :refresh_done
|
86
85
|
once.for(state).once {
|
87
86
|
puts
|
88
87
|
}.otherwise {
|
89
|
-
#nothing
|
88
|
+
# nothing
|
90
89
|
}
|
91
|
-
when :plan_info
|
92
|
-
once.for(state).once
|
90
|
+
when :plan_info # rubocop:disable Lint/DuplicateBranch
|
91
|
+
once.for(state).once do puts end
|
93
92
|
log line, depth: 2
|
94
93
|
when :plan_summary
|
95
94
|
log line, depth: 2
|
@@ -114,7 +113,7 @@ module MuxTf
|
|
114
113
|
remedies
|
115
114
|
end
|
116
115
|
|
117
|
-
def run_tf_init(upgrade: nil, reconfigure: nil)
|
116
|
+
def run_tf_init(upgrade: nil, reconfigure: nil) # rubocop:disable Metrics/MethodLength
|
118
117
|
pastel = Pastel.new
|
119
118
|
|
120
119
|
phase = :init
|
@@ -145,7 +144,7 @@ module MuxTf
|
|
145
144
|
case stripped_line
|
146
145
|
when /^Downloading (?<repo>[^ ]+) (?<version>[^ ]+) for (?<module>[^ ]+)\.\.\./
|
147
146
|
print "D"
|
148
|
-
when /^Downloading (?<repo>[^ ]+) for (?<module>[^ ]+)\.\.\./
|
147
|
+
when /^Downloading (?<repo>[^ ]+) for (?<module>[^ ]+)\.\.\./ # rubocop:disable Lint/DuplicateBranch
|
149
148
|
print "D"
|
150
149
|
when /^- (?<module>[^ ]+) in (?<path>.+)$/
|
151
150
|
print "."
|
@@ -166,7 +165,7 @@ module MuxTf
|
|
166
165
|
print "."
|
167
166
|
when /^Downloading (?<repo>[^ ]+) (?<version>[^ ]+) for (?<module>[^ ]+)\.\.\./
|
168
167
|
print "D"
|
169
|
-
when /^Downloading (?<repo>[^ ]+) for (?<module>[^ ]+)\.\.\./
|
168
|
+
when /^Downloading (?<repo>[^ ]+) for (?<module>[^ ]+)\.\.\./ # rubocop:disable Lint/DuplicateBranch
|
170
169
|
print "D"
|
171
170
|
when ""
|
172
171
|
puts
|
@@ -183,7 +182,7 @@ module MuxTf
|
|
183
182
|
case stripped_line
|
184
183
|
when /^Successfully configured/
|
185
184
|
log line, depth: 2
|
186
|
-
when /unless the backend/
|
185
|
+
when /unless the backend/ # rubocop:disable Lint/DuplicateBranch
|
187
186
|
log line, depth: 2
|
188
187
|
when ""
|
189
188
|
puts
|
@@ -205,28 +204,28 @@ module MuxTf
|
|
205
204
|
case stripped_line
|
206
205
|
when /^- Reusing previous version of (?<module>.+) from the dependency lock file$/
|
207
206
|
info = $LAST_MATCH_INFO.named_captures
|
208
|
-
log "- [FROM-LOCK] #{info[
|
207
|
+
log "- [FROM-LOCK] #{info['module']}", depth: 2
|
209
208
|
when /^- (?<module>.+) is built in to Terraform$/
|
210
209
|
info = $LAST_MATCH_INFO.named_captures
|
211
|
-
log "- [BUILTIN] #{info[
|
210
|
+
log "- [BUILTIN] #{info['module']}", depth: 2
|
212
211
|
when /^- Finding (?<module>[^ ]+) versions matching "(?<version>.+)"\.\.\./
|
213
212
|
info = $LAST_MATCH_INFO.named_captures
|
214
|
-
log "- [FIND] #{info[
|
213
|
+
log "- [FIND] #{info['module']} matching #{info['version'].inspect}", depth: 2
|
215
214
|
when /^- Finding latest version of (?<module>.+)\.\.\.$/
|
216
215
|
info = $LAST_MATCH_INFO.named_captures
|
217
|
-
log "- [FIND] #{info[
|
216
|
+
log "- [FIND] #{info['module']}", depth: 2
|
218
217
|
when /^- Installing (?<module>[^ ]+) v(?<version>.+)\.\.\.$/
|
219
218
|
info = $LAST_MATCH_INFO.named_captures
|
220
|
-
log "- [INSTALLING] #{info[
|
221
|
-
when /^- Installed (?<module>[^ ]+) v(?<version>.+) \(signed by( a)? (?<signed>.+)\)$/
|
219
|
+
log "- [INSTALLING] #{info['module']} v#{info['version']}", depth: 2
|
220
|
+
when /^- Installed (?<module>[^ ]+) v(?<version>.+) \(signed by(?: a)? (?<signed>.+)\)$/
|
222
221
|
info = $LAST_MATCH_INFO.named_captures
|
223
|
-
log "- [INSTALLED] #{info[
|
222
|
+
log "- [INSTALLED] #{info['module']} v#{info['version']} (#{info['signed']})", depth: 2
|
224
223
|
when /^- Using previously-installed (?<module>[^ ]+) v(?<version>.+)$/
|
225
224
|
info = $LAST_MATCH_INFO.named_captures
|
226
|
-
log "- [USING] #{info[
|
225
|
+
log "- [USING] #{info['module']} v#{info['version']}", depth: 2
|
227
226
|
when /^- Downloading plugin for provider "(?<provider>[^"]+)" \((?<provider_path>[^)]+)\) (?<version>.+)\.\.\.$/
|
228
227
|
info = $LAST_MATCH_INFO.named_captures
|
229
|
-
log "- #{info[
|
228
|
+
log "- #{info['provider']} #{info['version']}", depth: 2
|
230
229
|
when "- Checking for available provider plugins..."
|
231
230
|
# noop
|
232
231
|
else
|
@@ -242,6 +241,7 @@ module MuxTf
|
|
242
241
|
log Paint[line, :yellow], depth: 1
|
243
242
|
when :none
|
244
243
|
next if line == ""
|
244
|
+
|
245
245
|
p [state, line]
|
246
246
|
else
|
247
247
|
p [state, line]
|
@@ -252,23 +252,21 @@ module MuxTf
|
|
252
252
|
[status.status, meta]
|
253
253
|
end
|
254
254
|
|
255
|
-
def process_validation(info)
|
255
|
+
def process_validation(info) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
256
256
|
remedies = Set.new
|
257
257
|
|
258
|
-
if info["error_count"]
|
259
|
-
log "Encountered #{Paint[info[
|
258
|
+
if (info["error_count"]).positive? || (info["warning_count"]).positive?
|
259
|
+
log "Encountered #{Paint[info['error_count'], :red]} Errors and #{Paint[info['warning_count'], :yellow]} Warnings!", depth: 2
|
260
260
|
info["diagnostics"].each do |dinfo|
|
261
261
|
color = dinfo["severity"] == "error" ? :red : :yellow
|
262
|
-
log "#{Paint[dinfo[
|
262
|
+
log "#{Paint[dinfo['severity'].capitalize, color]}: #{dinfo['summary']}", depth: 3
|
263
263
|
if dinfo["detail"]&.include?("terraform init")
|
264
264
|
remedies << :init
|
265
|
-
elsif /there is no package for .+ cached in/.match?(dinfo["summary"])
|
265
|
+
elsif /there is no package for .+ cached in/.match?(dinfo["summary"]) # rubocop:disable Lint/DuplicateBranch
|
266
266
|
remedies << :init
|
267
267
|
else
|
268
268
|
log dinfo["detail"], depth: 4 if dinfo["detail"]
|
269
|
-
if dinfo["range"]
|
270
|
-
log format_validation_range(dinfo["range"], color), depth: 4
|
271
|
-
end
|
269
|
+
log format_validation_range(dinfo["range"], color), depth: 4 if dinfo["range"]
|
272
270
|
|
273
271
|
remedies << :unknown if dinfo["severity"] == "error"
|
274
272
|
end
|
@@ -280,7 +278,7 @@ module MuxTf
|
|
280
278
|
|
281
279
|
private
|
282
280
|
|
283
|
-
def format_validation_range(range, color)
|
281
|
+
def format_validation_range(range, color) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
284
282
|
# filename: "../../../modules/pods/jane_pod/main.tf"
|
285
283
|
# start:
|
286
284
|
# line: 151
|
@@ -299,12 +297,17 @@ module MuxTf
|
|
299
297
|
# on ../../../modules/pods/jane_pod/main.tf line 151, in module "jane":
|
300
298
|
# 151: jane_resources_preset = var.jane_resources_presetx
|
301
299
|
output = []
|
302
|
-
lines_info = lines.size == 1
|
303
|
-
|
300
|
+
lines_info = if lines.size == 1
|
301
|
+
"#{lines.first}:#{columns.first}"
|
302
|
+
else
|
303
|
+
"#{lines.first}:#{columns.first} to #{lines.last}:#{columns.last}"
|
304
|
+
end
|
305
|
+
output << "on: #{range['filename']} line#{lines.size > 1 ? 's' : ''}: #{lines_info}"
|
304
306
|
|
305
307
|
if File.exist?(range["filename"])
|
306
308
|
file_lines = File.read(range["filename"]).split("\n")
|
307
|
-
extract_range = ([lines.first - context_lines,
|
309
|
+
extract_range = (([lines.first - context_lines,
|
310
|
+
0].max)..([lines.last + context_lines, file_lines.length - 1].min))
|
308
311
|
file_lines.each_with_index do |line, index|
|
309
312
|
if extract_range.cover?(index + 1)
|
310
313
|
if lines.cover?(index + 1)
|
@@ -316,7 +319,7 @@ module MuxTf
|
|
316
319
|
start_col = columns.last
|
317
320
|
end
|
318
321
|
painted_line = paint_line(line, color, start_col: start_col, end_col: end_col)
|
319
|
-
output << "#{Paint[
|
322
|
+
output << "#{Paint['>', color]} #{index + 1}: #{painted_line}"
|
320
323
|
else
|
321
324
|
output << " #{index + 1}: #{line}"
|
322
325
|
end
|
@@ -330,7 +333,7 @@ module MuxTf
|
|
330
333
|
def paint_line(line, *paint_options, start_col: 1, end_col: :max)
|
331
334
|
end_col = line.length if end_col == :max
|
332
335
|
prefix = line[0, start_col - 1]
|
333
|
-
suffix = line[end_col
|
336
|
+
suffix = line[end_col..]
|
334
337
|
middle = line[start_col - 1..end_col - 1]
|
335
338
|
"#{prefix}#{Paint[middle, *paint_options]}#{suffix}"
|
336
339
|
end
|