wip-runner 0.3.4 → 0.4.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/wip/runner/cli/help.rb +2 -2
- data/lib/wip/runner/cli/version.rb +3 -1
- data/lib/wip/runner/cli.rb +16 -13
- data/lib/wip/runner/command.rb +9 -7
- data/lib/wip/runner/options.rb +8 -0
- data/lib/wip/runner/parser.rb +12 -4
- data/lib/wip/runner/shell/handlers/base.rb +7 -2
- data/lib/wip/runner/shell/handlers/script.rb +5 -14
- data/lib/wip/runner/shell/handlers/system.rb +0 -5
- data/lib/wip/runner/shell/runner.rb +125 -104
- data/lib/wip/runner/shell/task.rb +17 -13
- data/lib/wip/runner/spec/helpers/command_helpers.rb +4 -2
- data/lib/wip/runner/spec/helpers/matchers.rb +31 -29
- data/lib/wip/runner/spec/helpers/string_helpers.rb +1 -1
- data/lib/wip/runner/spec/helpers/ui_helpers.rb +93 -0
- data/lib/wip/runner/spec/helpers.rb +1 -1
- data/lib/wip/runner/ui.rb +65 -0
- data/lib/wip/runner/version.rb +1 -1
- data/lib/wip/runner/workflow/runner.rb +219 -195
- data/lib/wip/runner/workflow.rb +1 -1
- data/lib/wip/runner.rb +1 -0
- metadata +5 -4
- data/lib/wip/runner/spec/helpers/io_helpers.rb +0 -81
@@ -5,28 +5,24 @@ module WIP
|
|
5
5
|
module Runner
|
6
6
|
module Workflow
|
7
7
|
class Runner
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(ui, workflow)
|
9
|
+
@ui = ui
|
10
10
|
@workflow = workflow
|
11
11
|
end
|
12
12
|
|
13
13
|
def run(options)
|
14
|
-
indent_size = @io.indent_size
|
15
|
-
@io.indent_size = 2
|
16
14
|
@options = options
|
17
15
|
@context = []
|
18
16
|
@env = {}
|
19
17
|
|
20
18
|
process_overview
|
21
19
|
process_workflow unless @options.overview
|
22
|
-
|
23
|
-
@io.indent_size = indent_size
|
24
20
|
end
|
25
21
|
|
26
22
|
private
|
27
23
|
|
28
24
|
def stylize(text, style)
|
29
|
-
stylize? ? @
|
25
|
+
stylize? ? @ui.out { @ui.color(text, style) } : text
|
30
26
|
end
|
31
27
|
|
32
28
|
def stylize?
|
@@ -34,37 +30,41 @@ module WIP
|
|
34
30
|
end
|
35
31
|
|
36
32
|
def process_overview
|
37
|
-
@
|
38
|
-
|
39
|
-
@
|
40
|
-
|
41
|
-
|
42
|
-
@
|
43
|
-
|
44
|
-
|
33
|
+
@ui.out {
|
34
|
+
@ui.newline
|
35
|
+
@ui.indent do
|
36
|
+
@ui.say "# #{stylize(@workflow.heading, :underline)}"
|
37
|
+
|
38
|
+
unless @workflow.overview.nil?
|
39
|
+
@ui.newline
|
40
|
+
@ui.say @workflow.overview
|
41
|
+
end
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
unless @workflow.prologue.nil?
|
44
|
+
@ui.newline
|
45
|
+
@ui.say @workflow.prologue
|
46
|
+
end
|
49
47
|
end
|
50
|
-
|
48
|
+
}
|
51
49
|
end
|
52
50
|
|
53
51
|
def process_workflow
|
54
52
|
@context.push({ sources: [] })
|
55
53
|
|
56
|
-
@
|
57
|
-
|
58
|
-
|
54
|
+
@ui.out {
|
55
|
+
@ui.indent do
|
56
|
+
process_configs unless @options.preview
|
57
|
+
process_guards unless @options.preview
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
@workflow.shells.each do |mode, content|
|
60
|
+
process_shell(content, mode)
|
61
|
+
end
|
63
62
|
|
64
|
-
|
65
|
-
|
63
|
+
@workflow.tasks.each do |task|
|
64
|
+
process_task(task)
|
65
|
+
end
|
66
66
|
end
|
67
|
-
|
67
|
+
}
|
68
68
|
|
69
69
|
@context.pop
|
70
70
|
rescue GuardError, HaltSignal
|
@@ -74,8 +74,10 @@ module WIP
|
|
74
74
|
def process_task(task, overview = true)
|
75
75
|
process_block('##', task, overview, :underline) do
|
76
76
|
if overview && ! (task.shells.empty? && task.steps.empty?)
|
77
|
-
@
|
78
|
-
|
77
|
+
@ui.out {
|
78
|
+
@ui.newline
|
79
|
+
@ui.say 'Steps...'
|
80
|
+
}
|
79
81
|
end
|
80
82
|
|
81
83
|
if @options.preview
|
@@ -87,58 +89,62 @@ module WIP
|
|
87
89
|
process_step(step)
|
88
90
|
end
|
89
91
|
else
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
task.steps.each do |step|
|
98
|
-
@io.newline
|
99
|
-
@io.say("- [ ] #{step.heading}")
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
@io.newline
|
104
|
-
choice = @io.choose('yes', 'no', 'skip', 'step', 'preview') do |menu|
|
105
|
-
menu.header = 'Continue?'
|
106
|
-
menu.flow = :inline
|
107
|
-
menu.index = :none
|
108
|
-
end
|
92
|
+
@ui.out {
|
93
|
+
if overview
|
94
|
+
@options.preview = true
|
95
|
+
task.shells.each do |mode, content|
|
96
|
+
process_shell(content, mode)
|
97
|
+
end
|
98
|
+
@options.preview = false
|
109
99
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
raise HaltSignal
|
115
|
-
when 'skip'
|
116
|
-
@io.indent_level -= 1
|
117
|
-
return
|
118
|
-
when 'step'
|
119
|
-
@options.stepwise = true
|
120
|
-
task.shells.each do |mode, content|
|
121
|
-
process_shell(content, mode)
|
100
|
+
task.steps.each do |step|
|
101
|
+
@ui.newline
|
102
|
+
@ui.say("- [ ] #{step.heading}")
|
103
|
+
end
|
122
104
|
end
|
123
105
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
process_shell(content, mode)
|
132
|
-
end
|
133
|
-
task.steps.each do |step|
|
134
|
-
process_step(step)
|
135
|
-
end
|
136
|
-
@options.preview = false
|
106
|
+
@ui.newline
|
107
|
+
@ui.err {
|
108
|
+
choice = @ui.choose('yes', 'no', 'skip', 'step', 'preview') do |menu|
|
109
|
+
menu.header = 'Continue?'
|
110
|
+
menu.flow = :inline
|
111
|
+
menu.index = :none
|
112
|
+
end
|
137
113
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
114
|
+
case choice
|
115
|
+
when 'yes'
|
116
|
+
proceed_with_task(task)
|
117
|
+
when 'no'
|
118
|
+
raise HaltSignal
|
119
|
+
when 'skip'
|
120
|
+
@ui.indent_level -= 1
|
121
|
+
return
|
122
|
+
when 'step'
|
123
|
+
@options.stepwise = true
|
124
|
+
task.shells.each do |mode, content|
|
125
|
+
process_shell(content, mode)
|
126
|
+
end
|
127
|
+
|
128
|
+
task.steps.each do |step|
|
129
|
+
process_step(step)
|
130
|
+
end
|
131
|
+
@options.stepwise = false
|
132
|
+
when 'preview'
|
133
|
+
@options.preview = true
|
134
|
+
task.shells.each do |mode, content|
|
135
|
+
process_shell(content, mode)
|
136
|
+
end
|
137
|
+
task.steps.each do |step|
|
138
|
+
process_step(step)
|
139
|
+
end
|
140
|
+
@options.preview = false
|
141
|
+
|
142
|
+
@ui.indent(-1) do
|
143
|
+
process_task(task, false)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
}
|
147
|
+
}
|
142
148
|
end
|
143
149
|
end
|
144
150
|
end
|
@@ -157,24 +163,24 @@ module WIP
|
|
157
163
|
end
|
158
164
|
@options.preview = false
|
159
165
|
|
160
|
-
@
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
case choice
|
168
|
-
when 'yes'
|
169
|
-
proceed_with_step(step)
|
170
|
-
when 'no'
|
171
|
-
raise HaltSignal
|
172
|
-
when 'skip'
|
173
|
-
@io.indent_level -= 1
|
174
|
-
return
|
175
|
-
end
|
176
|
-
|
166
|
+
@ui.err {
|
167
|
+
@ui.newline
|
168
|
+
choice = @ui.choose('yes', 'no', 'skip') do |menu|
|
169
|
+
menu.header = 'Continue?'
|
170
|
+
menu.flow = :inline
|
171
|
+
menu.index = :none
|
172
|
+
end
|
177
173
|
|
174
|
+
case choice
|
175
|
+
when 'yes'
|
176
|
+
proceed_with_step(step)
|
177
|
+
when 'no'
|
178
|
+
raise HaltSignal
|
179
|
+
when 'skip'
|
180
|
+
@ui.indent_level -= 1
|
181
|
+
return
|
182
|
+
end
|
183
|
+
}
|
178
184
|
else
|
179
185
|
proceed_with_step(step)
|
180
186
|
end
|
@@ -184,23 +190,25 @@ module WIP
|
|
184
190
|
|
185
191
|
def process_configs
|
186
192
|
unless @workflow.configs.empty?
|
187
|
-
@
|
188
|
-
|
189
|
-
|
190
|
-
@
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
193
|
+
@ui.err {
|
194
|
+
@ui.newline
|
195
|
+
@ui.say "## #{stylize('Configuration', :underline)}"
|
196
|
+
@ui.indent do
|
197
|
+
@ui.newline
|
198
|
+
@ui.say 'Please provide values for the following...'
|
199
|
+
|
200
|
+
@workflow.configs.each do |key, options|
|
201
|
+
answer = @ui.ask("- #{key}: ") do |q|
|
202
|
+
q.default = (options[:default] || ENV[key])
|
203
|
+
if options[:required]
|
204
|
+
# q.validate = Proc.new { |a| ! a.empty? }
|
205
|
+
q.validate = /^.+$/
|
206
|
+
end
|
199
207
|
end
|
208
|
+
@env[key] = answer unless answer.empty?
|
200
209
|
end
|
201
|
-
@env[key] = answer unless answer.empty?
|
202
210
|
end
|
203
|
-
|
211
|
+
}
|
204
212
|
end
|
205
213
|
end
|
206
214
|
|
@@ -233,23 +241,25 @@ module WIP
|
|
233
241
|
end
|
234
242
|
|
235
243
|
def process_block(prefix, component, overview = true, style = nil)
|
236
|
-
@
|
244
|
+
@ui.out {
|
245
|
+
@context.push({ sources: [] })
|
237
246
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
247
|
+
if overview
|
248
|
+
@ui.newline
|
249
|
+
@ui.say("#{prefix} #{stylize(component.heading, style)}")
|
250
|
+
end
|
242
251
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
252
|
+
@ui.indent do
|
253
|
+
unless component.prologue.nil?
|
254
|
+
@ui.newline
|
255
|
+
@ui.say component.prologue
|
256
|
+
end if overview
|
248
257
|
|
249
|
-
|
250
|
-
|
258
|
+
yield if block_given?
|
259
|
+
end
|
251
260
|
|
252
|
-
|
261
|
+
@context.pop
|
262
|
+
}
|
253
263
|
end
|
254
264
|
|
255
265
|
def process_shell(content, mode)
|
@@ -270,14 +280,16 @@ module WIP
|
|
270
280
|
prefix = '→ '
|
271
281
|
end
|
272
282
|
|
273
|
-
@
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
283
|
+
@ui.out {
|
284
|
+
@ui.newline
|
285
|
+
content.split("\n").each do |action|
|
286
|
+
if action.empty?
|
287
|
+
@ui.newline
|
288
|
+
else
|
289
|
+
@ui.say("#{prefix}#{stylize(action, :bold)}")
|
290
|
+
end
|
279
291
|
end
|
280
|
-
|
292
|
+
}
|
281
293
|
end
|
282
294
|
|
283
295
|
# ---
|
@@ -327,22 +339,24 @@ module WIP
|
|
327
339
|
preview(content, :script)
|
328
340
|
|
329
341
|
if @options.stepwise
|
330
|
-
@
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
342
|
+
@ui.err {
|
343
|
+
@ui.newline
|
344
|
+
choice = @ui.choose('yes', 'no', 'skip') do |menu|
|
345
|
+
menu.header = 'Continue?'
|
346
|
+
menu.flow = :inline
|
347
|
+
menu.index = :none
|
348
|
+
end
|
336
349
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
350
|
+
case choice
|
351
|
+
when 'yes'
|
352
|
+
@ui.newline
|
353
|
+
proceed_with_script(content)
|
354
|
+
when 'no'
|
355
|
+
raise HaltSignal
|
356
|
+
when 'skip'
|
357
|
+
@ui.newline
|
358
|
+
end
|
359
|
+
}
|
346
360
|
else
|
347
361
|
proceed_with_script(content)
|
348
362
|
end
|
@@ -354,24 +368,26 @@ module WIP
|
|
354
368
|
preview(action, :lines)
|
355
369
|
|
356
370
|
if @options.stepwise
|
357
|
-
@
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
371
|
+
@ui.err {
|
372
|
+
@ui.newline
|
373
|
+
choice = @ui.choose('yes', 'no', 'skip') do |menu|
|
374
|
+
menu.header = 'Continue?'
|
375
|
+
menu.flow = :inline
|
376
|
+
menu.index = :none
|
377
|
+
end
|
363
378
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
379
|
+
case choice
|
380
|
+
when 'yes'
|
381
|
+
@ui.newline
|
382
|
+
proceed_with_line(action)
|
383
|
+
next
|
384
|
+
when 'no'
|
385
|
+
raise HaltSignal
|
386
|
+
when 'skip'
|
387
|
+
@ui.newline
|
388
|
+
next
|
389
|
+
end
|
390
|
+
}
|
375
391
|
else
|
376
392
|
proceed_with_line(action)
|
377
393
|
end
|
@@ -389,11 +405,13 @@ module WIP
|
|
389
405
|
command = %Q{bash -c "#{command} 2>&1"}
|
390
406
|
|
391
407
|
IO.popen(@env, command) do |pipe|
|
392
|
-
@
|
393
|
-
|
394
|
-
|
408
|
+
@ui.out {
|
409
|
+
@ui.indent do
|
410
|
+
pipe.each do |line|
|
411
|
+
@ui.say(line)
|
412
|
+
end
|
395
413
|
end
|
396
|
-
|
414
|
+
}
|
397
415
|
end
|
398
416
|
|
399
417
|
exit 1 unless $?.success?
|
@@ -431,13 +449,15 @@ module WIP
|
|
431
449
|
Open3.popen2e(@env, script) do |stdin, stdoe, wait_thread|
|
432
450
|
status = wait_thread.value
|
433
451
|
|
434
|
-
@
|
435
|
-
|
436
|
-
|
452
|
+
@ui.out {
|
453
|
+
@ui.indent do
|
454
|
+
while line = stdoe.gets
|
455
|
+
@ui.say("⫶ #{line}")
|
456
|
+
end
|
437
457
|
end
|
438
|
-
end
|
439
458
|
|
440
|
-
|
459
|
+
exit 1 unless status.success?
|
460
|
+
}
|
441
461
|
end
|
442
462
|
end
|
443
463
|
|
@@ -449,13 +469,15 @@ module WIP
|
|
449
469
|
Open3.popen2e(@env, command) do |stdin, stdoe, wait_thread|
|
450
470
|
status = wait_thread.value
|
451
471
|
|
452
|
-
@
|
453
|
-
|
454
|
-
|
472
|
+
@ui.out {
|
473
|
+
@ui.indent do
|
474
|
+
while line = stdoe.gets
|
475
|
+
@ui.say("⫶ #{line}")
|
476
|
+
end
|
455
477
|
end
|
456
|
-
end
|
457
478
|
|
458
|
-
|
479
|
+
exit 1 unless status.success?
|
480
|
+
}
|
459
481
|
end
|
460
482
|
end
|
461
483
|
|
@@ -473,7 +495,7 @@ module WIP
|
|
473
495
|
end
|
474
496
|
|
475
497
|
def error(message)
|
476
|
-
@
|
498
|
+
@ui.err { @ui.say stylize(message, :red) }
|
477
499
|
end
|
478
500
|
|
479
501
|
def guard_error(description, command, check, actual)
|
@@ -486,29 +508,31 @@ module WIP
|
|
486
508
|
message = ['Output did not match expected', check.inspect, actual]
|
487
509
|
end
|
488
510
|
|
489
|
-
@
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
511
|
+
@ui.err {
|
512
|
+
@ui.newline
|
513
|
+
error "Guard failed: '#{description}'"
|
514
|
+
@ui.indent do
|
515
|
+
error "→ #{command}"
|
516
|
+
end
|
494
517
|
|
495
|
-
|
496
|
-
|
518
|
+
if message.is_a?(Array)
|
519
|
+
error message[0]
|
497
520
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
521
|
+
@ui.newline
|
522
|
+
@ui.say stylize('Expected:', :bold)
|
523
|
+
@ui.indent do
|
524
|
+
@ui.say message[1]
|
525
|
+
end
|
503
526
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
527
|
+
@ui.newline
|
528
|
+
@ui.say stylize('Actual:', :bold)
|
529
|
+
@ui.indent do
|
530
|
+
@ui.say message[2]
|
531
|
+
end
|
532
|
+
else
|
533
|
+
error message
|
508
534
|
end
|
509
|
-
|
510
|
-
error message
|
511
|
-
end
|
535
|
+
}
|
512
536
|
|
513
537
|
raise GuardError, message[0]
|
514
538
|
end
|
data/lib/wip/runner/workflow.rb
CHANGED
data/lib/wip/runner.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wip-runner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Corey Innis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -110,9 +110,10 @@ files:
|
|
110
110
|
- lib/wip/runner/shell/task.rb
|
111
111
|
- lib/wip/runner/spec/helpers.rb
|
112
112
|
- lib/wip/runner/spec/helpers/command_helpers.rb
|
113
|
-
- lib/wip/runner/spec/helpers/io_helpers.rb
|
114
113
|
- lib/wip/runner/spec/helpers/matchers.rb
|
115
114
|
- lib/wip/runner/spec/helpers/string_helpers.rb
|
115
|
+
- lib/wip/runner/spec/helpers/ui_helpers.rb
|
116
|
+
- lib/wip/runner/ui.rb
|
116
117
|
- lib/wip/runner/version.rb
|
117
118
|
- lib/wip/runner/workflow.rb
|
118
119
|
- lib/wip/runner/workflow/builder.rb
|
@@ -143,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
144
|
version: '0'
|
144
145
|
requirements: []
|
145
146
|
rubyforge_project:
|
146
|
-
rubygems_version: 2.2.
|
147
|
+
rubygems_version: 2.2.2
|
147
148
|
signing_key:
|
148
149
|
specification_version: 4
|
149
150
|
summary: wip-runner is a generic CLI stand-alone and library.
|