gloo-cli 1.8 → 2.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/cli_colorize.rb +11 -4
- data/lib/cli_confirm.rb +9 -14
- data/lib/command.rb +35 -24
- data/lib/prompt.rb +11 -17
- data/lib/select.rb +16 -14
- data/lib/shell.rb +33 -26
- data/lib/shell_runner.rb +41 -23
- metadata +70 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 26757505cf53f7adb80263e1e9eb6434b4296ddcde50f431b9100ad585c140b5
|
|
4
|
+
data.tar.gz: d8f910b22f8e47b082069d5fefedb90d16750eb507b10639ec157afc7e76a4c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0123e410939777c02628748c972d912ef508986d6c4d0e7f4501d7a888e245af572806f96099635ba3702c140491773e29f26e0fdf66671563824c2d23034324
|
|
7
|
+
data.tar.gz: 26abd327ed5bc25ecb7b608b80b315e044dbb0eb3f6e8a17b3bb28982cb93f8dfbcc183285d78496a803950748bd313d792b803031f797c6f24aa623e95438d5
|
data/lib/cli_colorize.rb
CHANGED
|
@@ -55,12 +55,19 @@ class CliColorize < Gloo::Core::Obj
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
#
|
|
58
|
-
# Run the colorize command.
|
|
58
|
+
# Run the colorize command: show the line and put it in it.
|
|
59
|
+
# A child whose name isn't a color is shown uncolored, with a warning.
|
|
59
60
|
#
|
|
60
61
|
def msg_run
|
|
61
62
|
msg = ''
|
|
62
63
|
children.each do |o|
|
|
63
|
-
|
|
64
|
+
color = o.name.to_sym
|
|
65
|
+
if ColorizedString.colors.include?( color )
|
|
66
|
+
msg += ColorizedString[ o.value_display ].colorize( color )
|
|
67
|
+
else
|
|
68
|
+
@engine.warn "Unknown color '#{o.name}' in colorize '#{name}'; shown uncolored."
|
|
69
|
+
msg += o.value_display.to_s
|
|
70
|
+
end
|
|
64
71
|
end
|
|
65
72
|
@engine.log.show msg
|
|
66
73
|
@engine.heap.it.set_to msg.to_s
|
|
@@ -82,10 +89,10 @@ class CliColorize < Gloo::Core::Obj
|
|
|
82
89
|
'strings, each one can have a different color as specified by ' \
|
|
83
90
|
'the names of the children.',
|
|
84
91
|
:children => [
|
|
85
|
-
'[color] (string) — The name of the child or children is the color. The string\'s value is what will be written out.'
|
|
92
|
+
'[color] (string) — The name of the child or children is the color. The string\'s value is what will be written out. A name that isn\'t a color is written uncolored, with a warning.'
|
|
86
93
|
],
|
|
87
94
|
:messages => [
|
|
88
|
-
'run — Output the string in the color specified.'
|
|
95
|
+
'run — Output the string in the color specified, and put the line in it.'
|
|
89
96
|
],
|
|
90
97
|
:examples => <<~EXAMPLES.strip
|
|
91
98
|
color [can] :
|
data/lib/cli_confirm.rb
CHANGED
|
@@ -27,24 +27,21 @@ class CliConfirm < Gloo::Core::Obj
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
#
|
|
30
|
-
# Get the
|
|
31
|
-
#
|
|
30
|
+
# Get the prompt from the child object.
|
|
31
|
+
# The default prompt if there is none.
|
|
32
32
|
#
|
|
33
33
|
def prompt_value
|
|
34
34
|
o = find_child PROMPT
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
return o.value
|
|
35
|
+
return o ? o.value : DEFAULT_PROMPT
|
|
38
36
|
end
|
|
39
37
|
|
|
40
38
|
#
|
|
41
|
-
# Set the result
|
|
39
|
+
# Set the result to the answer, and put it in it.
|
|
40
|
+
# The answer is kept even if there is no result child.
|
|
42
41
|
#
|
|
43
42
|
def set_result( data )
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
r.set_value data
|
|
43
|
+
find_child( RESULT )&.set_value data
|
|
44
|
+
@engine.heap.it.set_to data
|
|
48
45
|
end
|
|
49
46
|
|
|
50
47
|
# ---------------------------------------------------------------------
|
|
@@ -83,8 +80,6 @@ class CliConfirm < Gloo::Core::Obj
|
|
|
83
80
|
#
|
|
84
81
|
def msg_run
|
|
85
82
|
prompt = prompt_value
|
|
86
|
-
return unless prompt
|
|
87
|
-
|
|
88
83
|
result = @engine.platform.prompt.yes?( prompt )
|
|
89
84
|
set_result result
|
|
90
85
|
end
|
|
@@ -102,11 +97,11 @@ class CliConfirm < Gloo::Core::Obj
|
|
|
102
97
|
:shortcut => KEYWORD_SHORT,
|
|
103
98
|
:description => 'CLI confirmation prompt.',
|
|
104
99
|
:children => [
|
|
105
|
-
"prompt (string) — Default: '> '. The confirmation prompt.",
|
|
100
|
+
"prompt (string) — Default: '> '. The confirmation prompt; the default is used if there is no prompt child.",
|
|
106
101
|
'result (boolean) — The result of the prompt.'
|
|
107
102
|
],
|
|
108
103
|
:messages => [
|
|
109
|
-
'run — Prompt the user
|
|
104
|
+
'run — Prompt the user; the answer (true or false) is put in result and in it.'
|
|
110
105
|
],
|
|
111
106
|
:examples => <<~EXAMPLES.strip
|
|
112
107
|
confirm [confirm] :
|
data/lib/command.rb
CHANGED
|
@@ -17,7 +17,6 @@ class Command < Gloo::Core::Obj
|
|
|
17
17
|
CONTEXT = 'context'.freeze
|
|
18
18
|
OPTIONS = 'options'.freeze
|
|
19
19
|
OPTIONS_KEY = 'options_key'.freeze
|
|
20
|
-
ON_ERROR = 'on_error'.freeze
|
|
21
20
|
|
|
22
21
|
#
|
|
23
22
|
# The name of the object type.
|
|
@@ -120,18 +119,6 @@ class Command < Gloo::Core::Obj
|
|
|
120
119
|
Gloo::Exec::Dispatch.message( @engine, 'run', o )
|
|
121
120
|
end
|
|
122
121
|
|
|
123
|
-
#
|
|
124
|
-
# Run the on_error script if one exists.
|
|
125
|
-
# Returns true if the script was found and run, false otherwise.
|
|
126
|
-
#
|
|
127
|
-
def run_on_error
|
|
128
|
-
o = find_child ON_ERROR
|
|
129
|
-
return false unless o
|
|
130
|
-
|
|
131
|
-
Gloo::Exec::Dispatch.message( @engine, 'run', o )
|
|
132
|
-
return true
|
|
133
|
-
end
|
|
134
|
-
|
|
135
122
|
|
|
136
123
|
# ---------------------------------------------------------------------
|
|
137
124
|
# Children
|
|
@@ -171,21 +158,45 @@ class Command < Gloo::Core::Obj
|
|
|
171
158
|
end
|
|
172
159
|
|
|
173
160
|
#
|
|
174
|
-
# Register the command with the shell.
|
|
161
|
+
# Register the command with the shell given as the parameter.
|
|
175
162
|
#
|
|
176
163
|
def msg_register
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
end
|
|
164
|
+
shell = param_shell
|
|
165
|
+
return unless shell
|
|
166
|
+
|
|
167
|
+
shell.add_command( self, get_command_data )
|
|
168
|
+
|
|
169
|
+
# Are there options to add?
|
|
170
|
+
if options_key
|
|
171
|
+
shell.set_context( options_key, options )
|
|
186
172
|
end
|
|
187
173
|
end
|
|
188
174
|
|
|
175
|
+
#
|
|
176
|
+
# The shell named by the message's parameter. Otherwise report it
|
|
177
|
+
# (a syntax error if there's no parameter) and return nil.
|
|
178
|
+
#
|
|
179
|
+
def param_shell
|
|
180
|
+
unless @params&.token_count&.positive?
|
|
181
|
+
@engine.syntax_err "Missing the shell to register with! eg. tell #{name} to register (my.shell)"
|
|
182
|
+
return nil
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
pn = @params.first
|
|
186
|
+
shell = Gloo::Core::Pn.new( @engine, pn ).resolve
|
|
187
|
+
if shell.nil?
|
|
188
|
+
@engine.err Gloo::Core::NotFound.object( pn )
|
|
189
|
+
return nil
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
unless shell.is_a?( Shell )
|
|
193
|
+
@engine.err "'#{pn}' is not a shell."
|
|
194
|
+
return nil
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
return shell
|
|
198
|
+
end
|
|
199
|
+
|
|
189
200
|
|
|
190
201
|
# ---------------------------------------------------------------------
|
|
191
202
|
# Helpers
|
|
@@ -257,7 +268,7 @@ class Command < Gloo::Core::Obj
|
|
|
257
268
|
'options_key (string) — Optional. The shell context key that options gets registered under.'
|
|
258
269
|
],
|
|
259
270
|
:messages => [
|
|
260
|
-
'register ({shell.path}) — Register this command with the given shell object, adding it to that shell\'s command tree. A parameter is required: the path to the shell.'
|
|
271
|
+
'register ({shell.path}) — Register this command with the given shell object, adding it to that shell\'s command tree. A parameter is required: the path to the shell. It is an error if it doesn\'t exist or isn\'t a shell.'
|
|
261
272
|
],
|
|
262
273
|
:notes => 'No vault documentation exists for this object type — ' \
|
|
263
274
|
'this was authored directly from the code.'
|
data/lib/prompt.rb
CHANGED
|
@@ -11,6 +11,7 @@ class Prompt < Gloo::Core::Obj
|
|
|
11
11
|
PROMPT = 'prompt'.freeze
|
|
12
12
|
RESULT = 'result'.freeze
|
|
13
13
|
DEFAULT = 'default'.freeze
|
|
14
|
+
DEFAULT_PROMPT = '>'.freeze
|
|
14
15
|
|
|
15
16
|
#
|
|
16
17
|
# The name of the object type.
|
|
@@ -28,13 +29,11 @@ class Prompt < Gloo::Core::Obj
|
|
|
28
29
|
|
|
29
30
|
#
|
|
30
31
|
# Get the prompt from the child object.
|
|
31
|
-
#
|
|
32
|
+
# The default prompt if there is none.
|
|
32
33
|
#
|
|
33
34
|
def prompt_value
|
|
34
35
|
o = find_child PROMPT
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
return o.value
|
|
36
|
+
return o ? o.value : DEFAULT_PROMPT
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
#
|
|
@@ -51,13 +50,12 @@ class Prompt < Gloo::Core::Obj
|
|
|
51
50
|
end
|
|
52
51
|
|
|
53
52
|
#
|
|
54
|
-
# Set the result
|
|
53
|
+
# Set the result to the answer, and put it in it.
|
|
54
|
+
# The answer is kept even if there is no result child.
|
|
55
55
|
#
|
|
56
56
|
def set_result( data )
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
r.set_value data
|
|
57
|
+
find_child( RESULT )&.set_value data
|
|
58
|
+
@engine.heap.it.set_to data
|
|
61
59
|
end
|
|
62
60
|
|
|
63
61
|
|
|
@@ -81,7 +79,7 @@ class Prompt < Gloo::Core::Obj
|
|
|
81
79
|
#
|
|
82
80
|
def add_default_children
|
|
83
81
|
fac = @engine.factory
|
|
84
|
-
fac.create_string PROMPT,
|
|
82
|
+
fac.create_string PROMPT, DEFAULT_PROMPT, self
|
|
85
83
|
fac.create_string RESULT, nil, self
|
|
86
84
|
end
|
|
87
85
|
|
|
@@ -102,8 +100,6 @@ class Prompt < Gloo::Core::Obj
|
|
|
102
100
|
#
|
|
103
101
|
def msg_multiline
|
|
104
102
|
prompt = prompt_value
|
|
105
|
-
return unless prompt
|
|
106
|
-
|
|
107
103
|
result = @engine.platform.prompt.multiline( prompt )
|
|
108
104
|
set_result result.join
|
|
109
105
|
end
|
|
@@ -113,8 +109,6 @@ class Prompt < Gloo::Core::Obj
|
|
|
113
109
|
#
|
|
114
110
|
def msg_run
|
|
115
111
|
prompt = prompt_value
|
|
116
|
-
return unless prompt
|
|
117
|
-
|
|
118
112
|
result = @engine.platform.prompt.ask( prompt, default_value )
|
|
119
113
|
set_result result
|
|
120
114
|
end
|
|
@@ -132,12 +126,12 @@ class Prompt < Gloo::Core::Obj
|
|
|
132
126
|
:shortcut => KEYWORD_SHORT,
|
|
133
127
|
:description => 'CLI prompt for user input.',
|
|
134
128
|
:children => [
|
|
135
|
-
"prompt (string) — Default: '>'. The prompt displayed to the user.",
|
|
129
|
+
"prompt (string) — Default: '>'. The prompt displayed to the user; the default is used if there is no prompt child.",
|
|
136
130
|
"result (string) — The result with the user's input."
|
|
137
131
|
],
|
|
138
132
|
:messages => [
|
|
139
|
-
'run — Prompt the user
|
|
140
|
-
'multiline — Show a multiline prompt.'
|
|
133
|
+
'run — Prompt the user; the answer is put in result and in it.',
|
|
134
|
+
'multiline — Show a multiline prompt; the answer is put in result and in it.'
|
|
141
135
|
],
|
|
142
136
|
:examples => <<~EXAMPLES.strip
|
|
143
137
|
ask [ask] :
|
data/lib/select.rb
CHANGED
|
@@ -11,6 +11,7 @@ class Select < Gloo::Core::Obj
|
|
|
11
11
|
PROMPT = 'prompt'.freeze
|
|
12
12
|
OPTIONS = 'options'.freeze
|
|
13
13
|
RESULT = 'result'.freeze
|
|
14
|
+
DEFAULT_PROMPT = '>'.freeze
|
|
14
15
|
|
|
15
16
|
#
|
|
16
17
|
# The name of the object type.
|
|
@@ -28,13 +29,11 @@ class Select < Gloo::Core::Obj
|
|
|
28
29
|
|
|
29
30
|
#
|
|
30
31
|
# Get the prompt from the child object.
|
|
31
|
-
#
|
|
32
|
+
# The default prompt if there is none.
|
|
32
33
|
#
|
|
33
34
|
def prompt_value
|
|
34
35
|
o = find_child PROMPT
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
return o.value
|
|
36
|
+
return o ? o.value : DEFAULT_PROMPT
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
#
|
|
@@ -62,13 +61,12 @@ class Select < Gloo::Core::Obj
|
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
#
|
|
65
|
-
# Set the result
|
|
64
|
+
# Set the result to the answer, and put it in it.
|
|
65
|
+
# The answer is kept even if there is no result child.
|
|
66
66
|
#
|
|
67
67
|
def set_result( data )
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
r.set_value data
|
|
68
|
+
find_child( RESULT )&.set_value data
|
|
69
|
+
@engine.heap.it.set_to data
|
|
72
70
|
end
|
|
73
71
|
|
|
74
72
|
# ---------------------------------------------------------------------
|
|
@@ -91,7 +89,7 @@ class Select < Gloo::Core::Obj
|
|
|
91
89
|
#
|
|
92
90
|
def add_default_children
|
|
93
91
|
fac = @engine.factory
|
|
94
|
-
fac.create_string PROMPT,
|
|
92
|
+
fac.create_string PROMPT, DEFAULT_PROMPT, self
|
|
95
93
|
fac.create_can OPTIONS, self
|
|
96
94
|
fac.create_string RESULT, nil, self
|
|
97
95
|
end
|
|
@@ -111,9 +109,13 @@ class Select < Gloo::Core::Obj
|
|
|
111
109
|
# Show the prompt and get the user's selection.
|
|
112
110
|
#
|
|
113
111
|
def msg_run
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
if options.empty?
|
|
113
|
+
@engine.err "select '#{name}' has no options."
|
|
114
|
+
@engine.heap.it.set_to false
|
|
115
|
+
return
|
|
116
|
+
end
|
|
116
117
|
|
|
118
|
+
prompt = prompt_value
|
|
117
119
|
# Page size was part of the tty-prompt but not used now.
|
|
118
120
|
# per = Gloo::App::Settings.page_size( @engine )
|
|
119
121
|
result = @engine.platform.prompt.select( prompt, options )
|
|
@@ -133,12 +135,12 @@ class Select < Gloo::Core::Obj
|
|
|
133
135
|
:shortcut => KEYWORD_SHORT,
|
|
134
136
|
:description => 'Prompt for user to select from a list of options.',
|
|
135
137
|
:children => [
|
|
136
|
-
"prompt (string) — Default: '>
|
|
138
|
+
"prompt (string) — Default: '>'. The prompt displayed to the user; the default is used if there is no prompt child.",
|
|
137
139
|
'options (container) — The list of options for the selection list. The name of each option is presented to the user, but the value is put in the result.',
|
|
138
140
|
"result (string) — The result with the user's selection."
|
|
139
141
|
],
|
|
140
142
|
:messages => [
|
|
141
|
-
'run — Prompt the user for a selection
|
|
143
|
+
'run — Prompt the user for a selection; the chosen option\'s value is put in result and in it. It is an error if there are no options (it is false).'
|
|
142
144
|
],
|
|
143
145
|
:examples => <<~EXAMPLES.strip
|
|
144
146
|
select [select] :
|
data/lib/shell.rb
CHANGED
|
@@ -11,11 +11,11 @@ class Shell < Gloo::Core::Obj
|
|
|
11
11
|
PROMPT = 'prompt'.freeze
|
|
12
12
|
DEFAULT_ACTION = 'default_action'.freeze
|
|
13
13
|
INCLUDE_QUIT = 'include_quit'.freeze
|
|
14
|
-
ON_ERROR = 'on_error'.freeze
|
|
15
14
|
ON_UNKNOWN_CMD = 'on_unknown_command'.freeze
|
|
16
15
|
ON_EMPTY_CMD = 'on_empty_command'.freeze
|
|
17
16
|
BEFORE_ACTION = 'before_action'.freeze
|
|
18
17
|
AFTER_ACTION = 'after_action'.freeze
|
|
18
|
+
WITH_COMMAND = 'with_command'.freeze
|
|
19
19
|
|
|
20
20
|
#
|
|
21
21
|
# The name of the object type.
|
|
@@ -89,17 +89,37 @@ class Shell < Gloo::Core::Obj
|
|
|
89
89
|
return super + [ 'start', 'stop' ]
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
#
|
|
92
|
+
#
|
|
93
93
|
# Get the shell runner or initialize it if it doesn't exist.
|
|
94
|
+
# In App mode, any CLI parameter(s) after the app path become the
|
|
95
|
+
# runner's single command (see ShellRunner#single_command?) rather
|
|
96
|
+
# than files for gloo to load - @engine.args keeps those out of
|
|
97
|
+
# @engine.args.files for exactly this reason.
|
|
94
98
|
#
|
|
95
99
|
def get_runner
|
|
96
|
-
|
|
100
|
+
set_with_command
|
|
101
|
+
return @runner ||= ShellRunner.new( @engine, self, command: @engine.args.command_tokens )
|
|
97
102
|
end
|
|
98
|
-
|
|
103
|
+
|
|
104
|
+
#
|
|
105
|
+
# If the app was invoked with a supplied command, record it on a
|
|
106
|
+
# with_command child (creating it if the script hasn't declared one
|
|
107
|
+
# itself), so scripts can tell a one-shot run from an interactive
|
|
108
|
+
# session - even before the shell starts (e.g. to skip a banner or
|
|
109
|
+
# menu). Left untouched (and uncreated) when no command was given.
|
|
110
|
+
#
|
|
111
|
+
def set_with_command
|
|
112
|
+
tokens = @engine.args.command_tokens
|
|
113
|
+
return if tokens.empty?
|
|
114
|
+
|
|
115
|
+
o = find_child( WITH_COMMAND ) || @engine.factory.create_string( WITH_COMMAND, '', self )
|
|
116
|
+
o.set_value( tokens.join( ' ' ) )
|
|
117
|
+
end
|
|
118
|
+
|
|
99
119
|
#
|
|
100
120
|
# Start the shell.
|
|
101
|
-
# If
|
|
102
|
-
# Otherwise, enter the interactive REPL.
|
|
121
|
+
# If the app was invoked with extra command-line arguments, execute
|
|
122
|
+
# that one command and return. Otherwise, enter the interactive REPL.
|
|
103
123
|
#
|
|
104
124
|
def msg_start
|
|
105
125
|
runner = get_runner
|
|
@@ -107,12 +127,7 @@ class Shell < Gloo::Core::Obj
|
|
|
107
127
|
# add_test_commands
|
|
108
128
|
add_quit_command
|
|
109
129
|
|
|
110
|
-
|
|
111
|
-
if cmd_tokens.any?
|
|
112
|
-
runner.execute_once( cmd_tokens )
|
|
113
|
-
else
|
|
114
|
-
runner.start
|
|
115
|
-
end
|
|
130
|
+
runner.start
|
|
116
131
|
end
|
|
117
132
|
|
|
118
133
|
#
|
|
@@ -139,18 +154,6 @@ class Shell < Gloo::Core::Obj
|
|
|
139
154
|
@runner.set_context( key, value )
|
|
140
155
|
end
|
|
141
156
|
|
|
142
|
-
#
|
|
143
|
-
# Run the on_error script if one exists.
|
|
144
|
-
# Returns true if the script was found and run, false otherwise.
|
|
145
|
-
#
|
|
146
|
-
def run_on_error
|
|
147
|
-
o = find_child ON_ERROR
|
|
148
|
-
return false unless o
|
|
149
|
-
|
|
150
|
-
Gloo::Exec::Dispatch.message( @engine, 'run', o )
|
|
151
|
-
return true
|
|
152
|
-
end
|
|
153
|
-
|
|
154
157
|
#
|
|
155
158
|
# Run the on_unknown_cmd script if one exists.
|
|
156
159
|
# Returns true if the script was found and run, false otherwise.
|
|
@@ -233,11 +236,15 @@ class Shell < Gloo::Core::Obj
|
|
|
233
236
|
"prompt (string) — Default: '> '. The prompt shown at each turn of the REPL.",
|
|
234
237
|
'default_action (script) — Run when the user presses RETURN with no input.',
|
|
235
238
|
'include_quit (boolean) — Optional. If true, a built-in quit command is added automatically.',
|
|
236
|
-
'on_error (script) — Optional.
|
|
239
|
+
'on_error (script) — Optional. An ordinary on_error event script: like any on_error, it runs when an error is reported anywhere, including in a command. (A Ruby exception in a command is logged and runs on_exception; the shell carries on.)',
|
|
237
240
|
"on_unknown_command (script) — Optional. Run when the input doesn't match any known command; if absent, a default \"Unknown command\" message is shown instead.",
|
|
238
241
|
'on_empty_command (script) — Optional. Run when the user submits an empty line.',
|
|
239
242
|
'before_action (script) — Optional. Run before every command executes.',
|
|
240
|
-
'after_action (script) — Optional. Run after every command executes.'
|
|
243
|
+
'after_action (script) — Optional. Run after every command executes.',
|
|
244
|
+
'with_command (string) — Not present by default. Set (and created if the ' \
|
|
245
|
+
'script hasn\'t declared it) to the supplied command text whenever the app ' \
|
|
246
|
+
'was invoked with extra command-line arguments - check for it to tell a ' \
|
|
247
|
+
'one-shot run from an interactive session.'
|
|
241
248
|
],
|
|
242
249
|
:messages => [
|
|
243
250
|
'start — Start the shell. If the app was invoked with extra command-line arguments, execute that one command and return; otherwise enter the interactive REPL.',
|
data/lib/shell_runner.rb
CHANGED
|
@@ -11,14 +11,18 @@ class ShellRunner
|
|
|
11
11
|
DEFAULT_PROMPT = " -> "
|
|
12
12
|
UNKNOWN_COMMAND = "Unknown command".freeze
|
|
13
13
|
|
|
14
|
-
#
|
|
14
|
+
#
|
|
15
15
|
# Initialize the shell runner
|
|
16
|
-
#
|
|
16
|
+
#
|
|
17
17
|
# @param obj [Object] The shell obj.
|
|
18
|
-
#
|
|
19
|
-
|
|
18
|
+
# @param opts [Hash] :command (Array<String>) - tokens for a single
|
|
19
|
+
# command to run once, instead of entering the interactive REPL -
|
|
20
|
+
# see #single_command?.
|
|
21
|
+
#
|
|
22
|
+
def initialize( engine, obj, opts = {} )
|
|
20
23
|
@engine = engine
|
|
21
24
|
@obj = obj
|
|
25
|
+
@command = opts[ :command ]
|
|
22
26
|
@context = ShellContext.new
|
|
23
27
|
@root = CommandNode.new( nil )
|
|
24
28
|
end
|
|
@@ -27,12 +31,26 @@ class ShellRunner
|
|
|
27
31
|
# ---------------------------------------------------------------------
|
|
28
32
|
# Shell, control, start and stop
|
|
29
33
|
# ---------------------------------------------------------------------
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Were command tokens supplied at construction? When true, #start
|
|
37
|
+
# runs that one command via #execute_once and returns instead of
|
|
38
|
+
# entering the REPL.
|
|
39
|
+
#
|
|
40
|
+
def single_command?
|
|
41
|
+
return !( @command.nil? || @command.empty? )
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Start the shell: run the single supplied command and return,
|
|
46
|
+
# or enter the interactive REPL if none was supplied.
|
|
47
|
+
#
|
|
34
48
|
def start
|
|
35
|
-
|
|
49
|
+
if single_command?
|
|
50
|
+
execute_once( @command )
|
|
51
|
+
else
|
|
52
|
+
repl
|
|
53
|
+
end
|
|
36
54
|
end
|
|
37
55
|
|
|
38
56
|
#
|
|
@@ -91,11 +109,7 @@ class ShellRunner
|
|
|
91
109
|
pn = Gloo::Core::Pn.new( @engine, parent_node.obj )
|
|
92
110
|
command = pn.resolve
|
|
93
111
|
if command
|
|
94
|
-
|
|
95
|
-
command.run_action_with_context( cmd_node.name )
|
|
96
|
-
rescue => e
|
|
97
|
-
command.run_on_error || @obj.run_on_error
|
|
98
|
-
end
|
|
112
|
+
command.run_action_with_context( cmd_node.name )
|
|
99
113
|
end
|
|
100
114
|
end
|
|
101
115
|
end
|
|
@@ -189,6 +203,16 @@ class ShellRunner
|
|
|
189
203
|
# Used when a command is passed directly from the CLI.
|
|
190
204
|
#
|
|
191
205
|
def execute_once( tokens )
|
|
206
|
+
run_tokens( tokens )
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
#
|
|
210
|
+
# Find and run the command for the given tokens, with the before and
|
|
211
|
+
# after actions. An unexpected Ruby exception is handled (logged, and
|
|
212
|
+
# on_exception is run) and the shell carries on. Errors in a
|
|
213
|
+
# command's gloo script are reported where they happen (on_error).
|
|
214
|
+
#
|
|
215
|
+
def run_tokens( tokens )
|
|
192
216
|
result = traverse( @root, tokens )
|
|
193
217
|
if result[:node]
|
|
194
218
|
@obj.run_before_action
|
|
@@ -197,6 +221,8 @@ class ShellRunner
|
|
|
197
221
|
else
|
|
198
222
|
handle_unknown_command
|
|
199
223
|
end
|
|
224
|
+
rescue => e
|
|
225
|
+
@engine.handle_exception e
|
|
200
226
|
end
|
|
201
227
|
|
|
202
228
|
#
|
|
@@ -275,15 +301,7 @@ class ShellRunner
|
|
|
275
301
|
next
|
|
276
302
|
end
|
|
277
303
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if result[:node]
|
|
281
|
-
@obj.run_before_action
|
|
282
|
-
execute_command( result[:node], tokens, result[:parent] )
|
|
283
|
-
@obj.run_after_action
|
|
284
|
-
else
|
|
285
|
-
handle_unknown_command
|
|
286
|
-
end
|
|
304
|
+
run_tokens( tokens )
|
|
287
305
|
end
|
|
288
306
|
end
|
|
289
307
|
|
metadata
CHANGED
|
@@ -1,14 +1,82 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gloo-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '
|
|
4
|
+
version: '2.0'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Crane
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: gloo
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: bundler
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
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: minitest
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '5.1'
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: 5.14.2
|
|
50
|
+
type: :development
|
|
51
|
+
prerelease: false
|
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - "~>"
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '5.1'
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: 5.14.2
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: rake
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - "~>"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '13.0'
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 13.0.1
|
|
70
|
+
type: :development
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - "~>"
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '13.0'
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: 13.0.1
|
|
12
80
|
description: Adds CLI support to Gloo.
|
|
13
81
|
email:
|
|
14
82
|
- eric.crane@mac.com
|