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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43076f87b14007f06ce003584c7cbe366170e629
|
4
|
+
data.tar.gz: ea94ff0e8cd0384b234f6921411178d8bc781875
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64247802ae56cdd2c96294c402e8e6aaf7183362ef0a97fad35b5910b0640855005ad81e29d84e3c68d2345e9beb9f4d5c803b9b2d43de721381773366549b97
|
7
|
+
data.tar.gz: bb3b9642aef06a98c988b32504e82ee03f9c79d9e66b8e41dce35a2fbe5525669e17d267452e861a8a40cf89d98a7157cd5441e7a09b8a6b961b03abe769567d
|
data/lib/wip/runner/cli/help.rb
CHANGED
@@ -18,9 +18,9 @@ module WIP
|
|
18
18
|
|
19
19
|
def command_parser(params)
|
20
20
|
command = params.command
|
21
|
-
return CLI::Parser.new(@
|
21
|
+
return CLI::Parser.new(@ui) if command.nil?
|
22
22
|
|
23
|
-
Commands.locate(command).new(@
|
23
|
+
Commands.locate(command).new(@ui).parser
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -4,7 +4,9 @@ module WIP
|
|
4
4
|
overview 'Prints version information'
|
5
5
|
|
6
6
|
def execute(params, options)
|
7
|
-
@
|
7
|
+
@ui.out {
|
8
|
+
@ui.say("#{WIP::Runner::CLI.signature} version #{WIP::Runner::CLI.namespace::VERSION}")
|
9
|
+
}
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
data/lib/wip/runner/cli.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'highline'
|
2
|
-
|
3
1
|
module WIP
|
4
2
|
module Runner
|
5
3
|
class CLI
|
@@ -40,10 +38,9 @@ module WIP
|
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
43
|
-
def initialize(
|
44
|
-
@
|
45
|
-
@parser = Parser.new(
|
46
|
-
|
41
|
+
def initialize(ui = UI.new)
|
42
|
+
@ui = ui
|
43
|
+
@parser = Parser.new(ui)
|
47
44
|
trap('INT') { quit }
|
48
45
|
trap('TERM') { quit }
|
49
46
|
end
|
@@ -57,8 +54,10 @@ module WIP
|
|
57
54
|
recipient = (command(args) || @parser)
|
58
55
|
recipient.run(args)
|
59
56
|
rescue InvalidCommand => e
|
60
|
-
@
|
61
|
-
|
57
|
+
@ui.err {
|
58
|
+
@ui.say(e.message)
|
59
|
+
@ui.newline
|
60
|
+
}
|
62
61
|
@parser.help
|
63
62
|
end
|
64
63
|
|
@@ -66,12 +65,12 @@ module WIP
|
|
66
65
|
|
67
66
|
def command(args)
|
68
67
|
handler = Commands.locate(args.shift)
|
69
|
-
handler.nil? ? nil : handler.new(@
|
68
|
+
handler.nil? ? nil : handler.new(@ui)
|
70
69
|
end
|
71
70
|
|
72
71
|
class Parser
|
73
|
-
def initialize(
|
74
|
-
@
|
72
|
+
def initialize(ui)
|
73
|
+
@ui = ui
|
75
74
|
end
|
76
75
|
|
77
76
|
def run(args)
|
@@ -80,7 +79,9 @@ module WIP
|
|
80
79
|
end
|
81
80
|
|
82
81
|
def help
|
83
|
-
@
|
82
|
+
@ui.err {
|
83
|
+
@ui.say(options.help)
|
84
|
+
}
|
84
85
|
end
|
85
86
|
|
86
87
|
private
|
@@ -106,7 +107,9 @@ module WIP
|
|
106
107
|
parser.separator 'Options:'
|
107
108
|
|
108
109
|
parser.on_tail '-h', '--help', 'Prints help messages' do
|
109
|
-
@
|
110
|
+
@ui.err {
|
111
|
+
@ui.say(parser)
|
112
|
+
}
|
110
113
|
end
|
111
114
|
end
|
112
115
|
end
|
data/lib/wip/runner/command.rb
CHANGED
@@ -45,9 +45,9 @@ module WIP
|
|
45
45
|
|
46
46
|
attr_reader :parser # TODO(?)... :arguments, :options
|
47
47
|
|
48
|
-
def initialize(
|
49
|
-
@
|
50
|
-
@parser = WIP::Runner::Parser.new(@
|
48
|
+
def initialize(ui)
|
49
|
+
@ui = ui
|
50
|
+
@parser = WIP::Runner::Parser.new(@ui, self.class)
|
51
51
|
end
|
52
52
|
|
53
53
|
def run(argv = [])
|
@@ -82,7 +82,7 @@ module WIP
|
|
82
82
|
def validate!(arguments)
|
83
83
|
unless parser.arguments.empty? || parser.config.no_validate
|
84
84
|
missing = parser.arguments.keys.inject({}) do |memo, key|
|
85
|
-
memo[key] = nil if arguments[key].nil?
|
85
|
+
memo[key] = nil if arguments[key].nil? || arguments[key].empty?
|
86
86
|
memo
|
87
87
|
end
|
88
88
|
raise InvalidArguments, missing unless missing.empty?
|
@@ -92,13 +92,15 @@ module WIP
|
|
92
92
|
private
|
93
93
|
|
94
94
|
def delegate(command, argv)
|
95
|
-
target = Commands.locate(command, self.class).new(@
|
95
|
+
target = Commands.locate(command, self.class).new(@ui)
|
96
96
|
target.run(argv)
|
97
97
|
end
|
98
98
|
|
99
99
|
def print_error(e)
|
100
|
-
@
|
101
|
-
|
100
|
+
@ui.err {
|
101
|
+
@ui.say(e.message)
|
102
|
+
@ui.newline
|
103
|
+
}
|
102
104
|
parser.help
|
103
105
|
end
|
104
106
|
end
|
data/lib/wip/runner/options.rb
CHANGED
@@ -3,6 +3,10 @@ require 'ostruct'
|
|
3
3
|
module WIP
|
4
4
|
module Runner
|
5
5
|
class Options < OpenStruct
|
6
|
+
def to_hash
|
7
|
+
self.to_h
|
8
|
+
end
|
9
|
+
|
6
10
|
def each(&block)
|
7
11
|
self.to_h.each(&block)
|
8
12
|
end
|
@@ -14,6 +18,10 @@ module WIP
|
|
14
18
|
def values
|
15
19
|
self.to_h.values
|
16
20
|
end
|
21
|
+
|
22
|
+
def merge(other)
|
23
|
+
Options.new(self.to_h.merge(other.to_h))
|
24
|
+
end
|
17
25
|
end
|
18
26
|
end
|
19
27
|
end
|
data/lib/wip/runner/parser.rb
CHANGED
@@ -5,8 +5,8 @@ module WIP
|
|
5
5
|
class Parser
|
6
6
|
attr_reader :config
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(ui, command)
|
9
|
+
@ui = ui
|
10
10
|
@command = command
|
11
11
|
@config = WIP::Runner::Options.new
|
12
12
|
end
|
@@ -21,7 +21,12 @@ module WIP
|
|
21
21
|
|
22
22
|
@args = WIP::Runner::Options.new.tap do |opts|
|
23
23
|
arguments.keys.each_with_index do |key, index|
|
24
|
-
|
24
|
+
if arguments[key].multiple
|
25
|
+
opts[key] = remaining[index..-1]
|
26
|
+
break
|
27
|
+
else
|
28
|
+
opts[key] = remaining[index]
|
29
|
+
end
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
@@ -30,7 +35,9 @@ module WIP
|
|
30
35
|
end
|
31
36
|
|
32
37
|
def help
|
33
|
-
@
|
38
|
+
@ui.err {
|
39
|
+
@ui.say(options.help)
|
40
|
+
}
|
34
41
|
end
|
35
42
|
|
36
43
|
def options
|
@@ -87,6 +94,7 @@ module WIP
|
|
87
94
|
pairs.each do |name, definition|
|
88
95
|
padding = ' ' * (parser.summary_width - name.length + 1)
|
89
96
|
overview = definition[:overview]
|
97
|
+
overview << ' [multiple]' if definition[:multiple]
|
90
98
|
parser.separator [parser.summary_indent, name, padding, overview].join('')
|
91
99
|
end
|
92
100
|
end
|
@@ -10,8 +10,13 @@ module WIP
|
|
10
10
|
instance_exec(&block) if block_given?
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
13
|
+
def content(format = :text)
|
14
|
+
case format
|
15
|
+
when :markdown
|
16
|
+
"```\n#{@content}\n```"
|
17
|
+
else
|
18
|
+
@content
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
def execute(io, env, &block)
|
@@ -15,17 +15,8 @@ module WIP
|
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
when :markdown
|
21
|
-
"```\n#{@content}\n```"
|
22
|
-
else
|
23
|
-
@content
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def execute(io, env, &block)
|
28
|
-
prompts.empty? ? simplex!(io, env, &block) : complex!(io, env, &block)
|
18
|
+
def execute(ui, env, &block)
|
19
|
+
prompts.empty? ? simplex!(ui, env, &block) : complex!(ui, env, &block)
|
29
20
|
end
|
30
21
|
|
31
22
|
def name(value)
|
@@ -46,7 +37,7 @@ module WIP
|
|
46
37
|
([@name] + @args).join(' ')
|
47
38
|
end
|
48
39
|
|
49
|
-
def simplex!(
|
40
|
+
def simplex!(ui, env, &block)
|
50
41
|
Open3.popen2e(env, "#{executable} #{arguments}") do |stdin, stdoe, thread|
|
51
42
|
while line = stdoe.gets
|
52
43
|
block.call(line)
|
@@ -56,11 +47,11 @@ module WIP
|
|
56
47
|
end
|
57
48
|
end
|
58
49
|
|
59
|
-
def complex!(
|
50
|
+
def complex!(ui, env, &block)
|
60
51
|
Open3.popen2e(env, "#{executable} #{arguments}") do |stdin, stdoe, thread|
|
61
52
|
prompts.each do |term, options|
|
62
53
|
stdoe.expect(term) do |result|
|
63
|
-
stdin.puts
|
54
|
+
stdin.puts ui.ask(term) do |q|
|
64
55
|
options.each { |k, v| q.send(:"#{k}=", v) }
|
65
56
|
end
|
66
57
|
stdoe.gets
|
@@ -3,11 +3,6 @@ module WIP
|
|
3
3
|
module Shell
|
4
4
|
module Handlers
|
5
5
|
class System < Base
|
6
|
-
def description
|
7
|
-
# @description ||= "```\n#{@content}\n```"
|
8
|
-
@description ||= @content
|
9
|
-
end
|
10
|
-
|
11
6
|
def execute(io, env, &block)
|
12
7
|
IO.popen(env, executable, 'r') do |pipe|
|
13
8
|
pipe.each(&block)
|
@@ -6,150 +6,155 @@ module WIP
|
|
6
6
|
class Runner
|
7
7
|
attr_reader :arguments, :options
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
@
|
12
|
-
@env
|
13
|
-
@io.indent_size = 2
|
9
|
+
# TODO: enforce env keys as String OR Symbol
|
10
|
+
def initialize(ui, env = {})
|
11
|
+
@ui = ui
|
12
|
+
@env = env
|
14
13
|
end
|
15
14
|
|
16
|
-
|
15
|
+
# TODO: custom proc for UI???
|
16
|
+
def run(tasks, arguments, options, &block)
|
17
17
|
@arguments = arguments
|
18
|
-
@options = options
|
19
|
-
|
20
|
-
if markdown
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
@options = default(:options).merge(options)
|
19
|
+
|
20
|
+
if format == :markdown
|
21
|
+
raise 'TODO'
|
22
|
+
# @ui.out {
|
23
|
+
# @ui.indent do
|
24
|
+
# [tasks].flatted.each do |task|
|
25
|
+
# evaluate(task)
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# }
|
26
29
|
else
|
27
|
-
|
28
|
-
evaluate(task)
|
30
|
+
[tasks].flatten.each do |task|
|
31
|
+
evaluate(task, &block)
|
29
32
|
end
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
33
36
|
private
|
34
37
|
|
35
|
-
def
|
38
|
+
def default(setting)
|
39
|
+
@defaults ||= {
|
40
|
+
:options => Options.new({
|
41
|
+
:echo => true,
|
42
|
+
:format => :text,
|
43
|
+
:interactive => true,
|
44
|
+
:mode => :execute
|
45
|
+
}),
|
46
|
+
:procs => {
|
47
|
+
:execute => Proc.new { |line| @ui.out { @ui.say("> #{line.rstrip}") } },
|
48
|
+
:silent => Proc.new { |line| }
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
@defaults[setting]
|
53
|
+
end
|
54
|
+
|
55
|
+
def evaluate(task, &block)
|
36
56
|
task.build(arguments, options)
|
37
|
-
prefix = options.preview ? :preview : :execute
|
38
57
|
|
39
|
-
section(
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
58
|
+
section(task.heading) do
|
59
|
+
if interactive? && ! task.configs.empty?
|
60
|
+
task.configs.each do |term, options, b|
|
61
|
+
evaluate_config(term, options, &b)
|
62
|
+
end
|
63
|
+
@ui.err { @ui.newline }
|
44
64
|
end
|
45
|
-
# @io.say '```'
|
46
|
-
end unless task.configs.empty?
|
47
65
|
|
48
|
-
|
49
|
-
|
50
|
-
send(:"#{prefix}_shell", shell)
|
51
|
-
@io.newline
|
66
|
+
task.shells.each do |shell|
|
67
|
+
send(:"#{mode}_shell", shell, &block)
|
52
68
|
end
|
53
|
-
end
|
54
69
|
|
55
|
-
|
56
|
-
|
57
|
-
section('Task') do
|
58
|
-
evaluate(child)
|
70
|
+
task.steps.each do |step|
|
71
|
+
evaluate(step, &block)
|
59
72
|
end
|
60
73
|
end
|
61
74
|
end
|
62
75
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# class Preview
|
69
|
-
# end
|
76
|
+
def default_config(term, options = {})
|
77
|
+
options[:default] || @env[term] || ENV[term]
|
78
|
+
end
|
70
79
|
|
71
|
-
def
|
80
|
+
def evaluate_config(term, options = {})
|
72
81
|
query = options[:required] ? "#{term} (*)" : term
|
73
|
-
answer = @
|
74
|
-
|
75
|
-
|
76
|
-
|
82
|
+
answer = @ui.err do
|
83
|
+
@ui.ask("- #{query}: ") do |q|
|
84
|
+
q.default = default_config(term, options) unless options[:password]
|
85
|
+
q.echo = false if options[:password]
|
86
|
+
q.validate = /^.+$/ if options[:required]
|
87
|
+
end
|
77
88
|
end
|
78
|
-
@env[term] = answer unless answer.empty?
|
79
|
-
@env[term] ||= ENV[term]
|
80
|
-
end
|
81
|
-
|
82
|
-
def execute_shell(shell)
|
83
|
-
preview_shell(shell)
|
84
89
|
|
85
|
-
if
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
# @io.send((action || :say), line)
|
94
|
-
end
|
95
|
-
@io.newline
|
90
|
+
if block_given?
|
91
|
+
yield answer
|
92
|
+
else
|
93
|
+
@env[term] = answer unless answer.empty?
|
94
|
+
@env[term] ||= ENV[term]
|
95
|
+
end
|
96
|
+
end
|
96
97
|
|
97
|
-
|
98
|
-
|
98
|
+
def display_shell(shell, &block)
|
99
|
+
if block_given?
|
100
|
+
block.call(shell.content)
|
99
101
|
else
|
100
|
-
@
|
101
|
-
|
102
|
+
@ui.out {
|
103
|
+
@ui.say(shell.content)
|
104
|
+
}
|
102
105
|
end
|
103
106
|
end
|
104
107
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
+
def execute_shell(shell, &block)
|
109
|
+
display_shell(shell) unless (mode == :silent) || ! echo?
|
110
|
+
|
111
|
+
@ui.out {
|
112
|
+
if approved?
|
113
|
+
if block_given?
|
114
|
+
result = shell.execute(@ui, @env, &block)
|
115
|
+
else
|
116
|
+
@ui.newline
|
117
|
+
result = shell.execute(@ui, @env, &default(:procs)[mode])
|
118
|
+
@ui.newline
|
119
|
+
end
|
120
|
+
|
121
|
+
# TODO: raise instead of exit.
|
122
|
+
exit 1 unless result.success?
|
123
|
+
else
|
124
|
+
if block_given?
|
125
|
+
block.call('> (skipped)')
|
126
|
+
else
|
127
|
+
@ui.newline
|
128
|
+
@ui.say('> (skipped)')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
}
|
108
132
|
end
|
109
133
|
|
110
|
-
def
|
111
|
-
|
134
|
+
def silent_shell(shell)
|
135
|
+
execute_shell(shell)
|
112
136
|
end
|
113
137
|
|
114
138
|
# ---
|
115
139
|
|
116
140
|
def section(heading, &block)
|
117
|
-
if markdown
|
118
|
-
@
|
119
|
-
|
141
|
+
if format == :markdown
|
142
|
+
@ui.out {
|
143
|
+
@ui.say("- [ ] #{heading}")
|
144
|
+
@ui.indent(&block)
|
145
|
+
}
|
120
146
|
else
|
121
|
-
|
147
|
+
@ui.err {
|
148
|
+
if heading
|
149
|
+
@ui.say(heading)
|
150
|
+
@ui.newline
|
151
|
+
end
|
152
|
+
yield
|
153
|
+
@ui.newline
|
154
|
+
}
|
122
155
|
end
|
123
156
|
end
|
124
157
|
|
125
|
-
def format
|
126
|
-
@options.format ? @options.format.intern : :text
|
127
|
-
end
|
128
|
-
|
129
|
-
def markdown?
|
130
|
-
format == :markdown
|
131
|
-
end
|
132
|
-
|
133
|
-
# $ wip-runner x --format=markdown
|
134
|
-
# $ wip-runner x --log=out.md # log format determined by extension
|
135
|
-
#
|
136
|
-
# @formatter = Formatter::Markdown.new(@io)
|
137
|
-
#
|
138
|
-
# def item(text)
|
139
|
-
# formatter.item(text)
|
140
|
-
# end
|
141
|
-
#
|
142
|
-
# class Formatter::Markdown
|
143
|
-
# def item(text, check = true)
|
144
|
-
# @io.say check ? "- [ ] #{text}" : "- #{text}"
|
145
|
-
# end
|
146
|
-
# end
|
147
|
-
#
|
148
|
-
# class Formatter::Plain
|
149
|
-
# class Formatter::Color
|
150
|
-
# class Formatter::HTML
|
151
|
-
# class Formatter::JSON
|
152
|
-
|
153
158
|
# ---
|
154
159
|
|
155
160
|
def approved?
|
@@ -159,6 +164,22 @@ module WIP
|
|
159
164
|
# when 'yes'
|
160
165
|
# end
|
161
166
|
end
|
167
|
+
|
168
|
+
def echo?
|
169
|
+
!! options.echo
|
170
|
+
end
|
171
|
+
|
172
|
+
def format
|
173
|
+
options.format
|
174
|
+
end
|
175
|
+
|
176
|
+
def interactive?
|
177
|
+
options.interactive
|
178
|
+
end
|
179
|
+
|
180
|
+
def mode
|
181
|
+
options.mode
|
182
|
+
end
|
162
183
|
end
|
163
184
|
end
|
164
185
|
end
|
@@ -2,30 +2,35 @@ module WIP
|
|
2
2
|
module Runner
|
3
3
|
module Shell
|
4
4
|
class Task
|
5
|
-
attr_reader :configs, :shells, :
|
6
|
-
|
7
|
-
def initialize(command, &block)
|
8
|
-
@command
|
9
|
-
@configs
|
10
|
-
@shells
|
11
|
-
@
|
12
|
-
@
|
5
|
+
attr_reader :heading, :configs, :shells, :steps
|
6
|
+
|
7
|
+
def initialize(command, *args, &block)
|
8
|
+
@command = command
|
9
|
+
@configs = []
|
10
|
+
@shells = []
|
11
|
+
@steps = []
|
12
|
+
@heading = args.first unless args.empty?
|
13
|
+
@block = block
|
13
14
|
end
|
14
15
|
|
15
16
|
def build(arguments, options)
|
16
17
|
self.instance_exec(arguments, options, &@block) ; self
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
@
|
20
|
+
def heading?
|
21
|
+
!! @heading
|
22
|
+
end
|
23
|
+
|
24
|
+
def config(term, options = {}, &block)
|
25
|
+
@configs << [term.to_s, options, block] # Config.new(...)
|
21
26
|
end
|
22
27
|
|
23
28
|
def shell(handler, content, &block)
|
24
29
|
shells << Handlers.locate(handler).new(content, &block)
|
25
30
|
end
|
26
31
|
|
27
|
-
def task(&block)
|
28
|
-
|
32
|
+
def task(*args, &block)
|
33
|
+
steps << Task.new(@command, *args, &block)
|
29
34
|
end
|
30
35
|
|
31
36
|
protected
|
@@ -34,7 +39,6 @@ module WIP
|
|
34
39
|
if @command.respond_to?(method_name)
|
35
40
|
@command.send(method_name, *args, &block)
|
36
41
|
else
|
37
|
-
# super
|
38
42
|
@command.instance_eval {
|
39
43
|
method_missing(method_name, *args, &block)
|
40
44
|
}
|
@@ -13,7 +13,7 @@ module WIP
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def example_command(implementation)
|
16
|
-
ExampleCommands.const_get(implementation).new(
|
16
|
+
ExampleCommands.const_get(implementation).new(ui)
|
17
17
|
end
|
18
18
|
|
19
19
|
module ExampleCommands
|
@@ -56,7 +56,9 @@ module WIP
|
|
56
56
|
|
57
57
|
def execute(args, options)
|
58
58
|
super
|
59
|
-
@
|
59
|
+
@ui.out {
|
60
|
+
@ui.say('running nested command...')
|
61
|
+
}
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|