gloo 6.0 → 6.1.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/CLAUDE.md +9 -3
- data/README.md +38 -7
- data/docs/application.md +164 -0
- data/docs/getting_started.md +112 -0
- data/docs/iterators.md +294 -0
- data/docs/language_objects.md +190 -0
- data/docs/language_scripting.md +62 -0
- data/docs/language_syntax.md +307 -0
- data/docs/objects.md +77 -0
- data/docs/operators.md +62 -0
- data/docs/plugins.md +54 -0
- data/docs/verbs.md +64 -0
- data/gloo.gemspec +5 -3
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +14 -0
- data/lib/gloo/app/platform.rb +29 -2
- data/lib/gloo/app/settings.rb +1 -1
- data/lib/gloo/core/gloo_system.rb +52 -1
- data/lib/gloo/docs/doc_data.rb +160 -0
- data/lib/gloo/docs/help_shell.rb +285 -0
- data/lib/gloo/docs/markdown_renderer.rb +39 -0
- data/lib/gloo/objs/basic/alias.rb +53 -0
- data/lib/gloo/objs/basic/boolean.rb +30 -0
- data/lib/gloo/objs/basic/container.rb +38 -0
- data/lib/gloo/objs/basic/decimal.rb +30 -0
- data/lib/gloo/objs/basic/integer.rb +58 -0
- data/lib/gloo/objs/basic/script.rb +31 -0
- data/lib/gloo/objs/basic/string.rb +51 -4
- data/lib/gloo/objs/basic/string_msgs.rb +20 -0
- data/lib/gloo/objs/basic/text.rb +51 -4
- data/lib/gloo/objs/basic/untyped.rb +21 -0
- data/lib/gloo/objs/ctrl/each.rb +63 -1
- data/lib/gloo/objs/ctrl/function.rb +69 -0
- data/lib/gloo/objs/ctrl/repeat.rb +41 -0
- data/lib/gloo/objs/dt/date.rb +43 -0
- data/lib/gloo/objs/dt/datetime.rb +50 -0
- data/lib/gloo/objs/dt/time.rb +43 -0
- data/lib/gloo/objs/str_utils/cipher.rb +59 -0
- data/lib/gloo/objs/str_utils/outline.rb +65 -1
- data/lib/gloo/objs/str_utils/password.rb +56 -0
- data/lib/gloo/objs/system/erb.rb +39 -0
- data/lib/gloo/objs/system/file_handle.rb +56 -0
- data/lib/gloo/objs/system/system.rb +29 -0
- data/lib/gloo/objs/web/http_get.rb +35 -0
- data/lib/gloo/objs/web/http_post.rb +33 -0
- data/lib/gloo/objs/web/json.rb +40 -0
- data/lib/gloo/objs/web/uri.rb +40 -0
- data/lib/gloo/shell/command_node.rb +39 -0
- data/lib/gloo/shell/context.rb +93 -0
- data/lib/gloo/shell/runner.rb +315 -0
- data/lib/gloo/verbs/break.rb +32 -0
- data/lib/gloo/verbs/check.rb +49 -0
- data/lib/gloo/verbs/cls.rb +18 -0
- data/lib/gloo/verbs/context.rb +47 -0
- data/lib/gloo/verbs/create.rb +42 -0
- data/lib/gloo/verbs/eval.rb +27 -0
- data/lib/gloo/verbs/execute.rb +27 -0
- data/lib/gloo/verbs/exists.rb +54 -2
- data/lib/gloo/verbs/files.rb +22 -0
- data/lib/gloo/verbs/help.rb +43 -178
- data/lib/gloo/verbs/if.rb +52 -0
- data/lib/gloo/verbs/invoke.rb +62 -0
- data/lib/gloo/verbs/list.rb +32 -0
- data/lib/gloo/verbs/load.rb +55 -2
- data/lib/gloo/verbs/log.rb +44 -0
- data/lib/gloo/verbs/move.rb +36 -1
- data/lib/gloo/verbs/put.rb +35 -0
- data/lib/gloo/verbs/quit.rb +19 -0
- data/lib/gloo/verbs/redirect.rb +52 -2
- data/lib/gloo/verbs/reload.rb +27 -0
- data/lib/gloo/verbs/run.rb +39 -0
- data/lib/gloo/verbs/save.rb +26 -0
- data/lib/gloo/verbs/show.rb +54 -0
- data/lib/gloo/verbs/tell.rb +32 -0
- data/lib/gloo/verbs/throw.rb +29 -0
- data/lib/gloo/verbs/unless.rb +50 -0
- data/lib/gloo/verbs/unload.rb +23 -0
- data/lib/gloo/verbs/version.rb +37 -3
- data/lib/gloo/verbs/wait.rb +26 -0
- metadata +28 -20
|
@@ -159,6 +159,62 @@ module Gloo
|
|
|
159
159
|
@engine.heap.it.set_to result
|
|
160
160
|
end
|
|
161
161
|
|
|
162
|
+
# ---------------------------------------------------------------------
|
|
163
|
+
# Object Documentation
|
|
164
|
+
# ---------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
#
|
|
167
|
+
# Get the object's documentation data.
|
|
168
|
+
#
|
|
169
|
+
def self.doc_data
|
|
170
|
+
{
|
|
171
|
+
:name => KEYWORD,
|
|
172
|
+
:shortcut => KEYWORD_SHORT,
|
|
173
|
+
:description => 'A password object that can be generated, hashed, and compared.',
|
|
174
|
+
:children => [
|
|
175
|
+
'salt (string) — Optional salt to use when hashing and checking passwords.',
|
|
176
|
+
'password (string) — The password. generate puts a new random password here. Used in the hash and check messages.',
|
|
177
|
+
'hash (string) — The hashed value of the password. Created when the hash message is called, and compared when the check message is called.'
|
|
178
|
+
],
|
|
179
|
+
:messages => [
|
|
180
|
+
'generate ({len}) — Generate a new password, put in the password child object. The {len} parameter is optional; the length is 7 if not specified.',
|
|
181
|
+
'hash — Hash the password in the child object. Put it in the hash child object.',
|
|
182
|
+
'check — Check the password in the child object. Is it the same as the hash?'
|
|
183
|
+
],
|
|
184
|
+
:examples => <<~EXAMPLES.strip
|
|
185
|
+
#
|
|
186
|
+
# Password Hashing and checking.
|
|
187
|
+
#
|
|
188
|
+
password [can] :
|
|
189
|
+
|
|
190
|
+
pwd [password] :
|
|
191
|
+
salt [string] : MySalt
|
|
192
|
+
password [string] :
|
|
193
|
+
hash [string] :
|
|
194
|
+
|
|
195
|
+
on_load [script] :
|
|
196
|
+
show
|
|
197
|
+
show 'Generating a new password' (white)
|
|
198
|
+
tell ^.pwd to generate
|
|
199
|
+
show 'Password: ' + ^.pwd.password
|
|
200
|
+
show
|
|
201
|
+
show 'hashing the password' (white)
|
|
202
|
+
tell ^.pwd to hash
|
|
203
|
+
show ^.pwd.hash (red)
|
|
204
|
+
show
|
|
205
|
+
show 'checking with the correct password' (white)
|
|
206
|
+
tell ^.pwd to check
|
|
207
|
+
show 'Result of check: ' + it (green)
|
|
208
|
+
show
|
|
209
|
+
show 'checking with the wrong password' (white)
|
|
210
|
+
tell ^.pwd to generate(23)
|
|
211
|
+
tell ^.pwd to check
|
|
212
|
+
show 'Result of check: ' + it (red)
|
|
213
|
+
show
|
|
214
|
+
EXAMPLES
|
|
215
|
+
}
|
|
216
|
+
end
|
|
217
|
+
|
|
162
218
|
end
|
|
163
219
|
end
|
|
164
220
|
end
|
data/lib/gloo/objs/system/erb.rb
CHANGED
|
@@ -110,6 +110,45 @@ module Gloo
|
|
|
110
110
|
set_result render.result_with_hash( param_hash )
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
# ---------------------------------------------------------------------
|
|
114
|
+
# Object Documentation
|
|
115
|
+
# ---------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# Get the object's documentation data.
|
|
119
|
+
#
|
|
120
|
+
def self.doc_data
|
|
121
|
+
{
|
|
122
|
+
:name => KEYWORD,
|
|
123
|
+
:shortcut => KEYWORD_SHORT,
|
|
124
|
+
:description => 'Use the ERB templating system to generate ' \
|
|
125
|
+
'content. For example, you can use the ERB object for ' \
|
|
126
|
+
'string interpolation.',
|
|
127
|
+
:children => [
|
|
128
|
+
'template (text) — The template that will be used when the ERB object is run.',
|
|
129
|
+
'params (container) — The collection of children values used when the template is rendered.',
|
|
130
|
+
'result (text) — The result of the template rendering.'
|
|
131
|
+
],
|
|
132
|
+
:messages => [
|
|
133
|
+
'run — Render the result based on the template and the parameter values.'
|
|
134
|
+
],
|
|
135
|
+
:examples => <<~EXAMPLES.strip
|
|
136
|
+
e [can] :
|
|
137
|
+
erb [erb] :
|
|
138
|
+
template [text] : BEGIN
|
|
139
|
+
Hello <%= first %> <%= last %>!
|
|
140
|
+
END
|
|
141
|
+
params [container] :
|
|
142
|
+
first [string] : Eric
|
|
143
|
+
last [string] : Crane
|
|
144
|
+
result [text] :
|
|
145
|
+
on_load [script] :
|
|
146
|
+
run e.erb
|
|
147
|
+
show e.erb.result
|
|
148
|
+
EXAMPLES
|
|
149
|
+
}
|
|
150
|
+
end
|
|
151
|
+
|
|
113
152
|
end
|
|
114
153
|
end
|
|
115
154
|
end
|
|
@@ -239,6 +239,62 @@ module Gloo
|
|
|
239
239
|
return true
|
|
240
240
|
end
|
|
241
241
|
|
|
242
|
+
# ---------------------------------------------------------------------
|
|
243
|
+
# Object Documentation
|
|
244
|
+
# ---------------------------------------------------------------------
|
|
245
|
+
|
|
246
|
+
#
|
|
247
|
+
# Get the object's documentation data.
|
|
248
|
+
#
|
|
249
|
+
def self.doc_data
|
|
250
|
+
{
|
|
251
|
+
:name => KEYWORD,
|
|
252
|
+
:shortcut => KEYWORD_SHORT,
|
|
253
|
+
:description => 'Reference to a file or folder (directory) ' \
|
|
254
|
+
'on disk. The string value of the file object is the path ' \
|
|
255
|
+
'and name of the file.',
|
|
256
|
+
:messages => [
|
|
257
|
+
'read ({into.obj}) — Read the file and put the data in the specified object. If {into.obj} is not specified, the data will be in it.',
|
|
258
|
+
'write ({from.obj}) — Write the data in {from.obj} into the file.',
|
|
259
|
+
'append ({data}) — Append the given data to the file as a new line. Adds a leading newline first if the file doesn\'t already end with one.',
|
|
260
|
+
'delete — Delete the file.',
|
|
261
|
+
'get_name — Get the name of the file without path or extension. Put the name into it.',
|
|
262
|
+
'get_ext — Get the file extension. Put the extension into it.',
|
|
263
|
+
'get_parent — Get the file or folder path parent. Put the parent into it.',
|
|
264
|
+
'get_sha256 — Get the SHA256 hash of the contents of the file. Put the hash value into it.',
|
|
265
|
+
'show — Show the contents of the file.',
|
|
266
|
+
'page — Show the contents of the file, paginated.',
|
|
267
|
+
'open — Open the file with the default application for the type.',
|
|
268
|
+
'exists? — Check to see if the file exists. It will be true or false.',
|
|
269
|
+
'is_file? — Check to see if the file specified is a regular file. It will be true or false.',
|
|
270
|
+
'is_dir? — Check to see if the file specified is a directory. It will be true or false.',
|
|
271
|
+
'find_match — Look for the existence of a file matching the file\'s pattern. It will be true or false.',
|
|
272
|
+
'mkdir — Create the file\'s path as a directory, if it doesn\'t already exist.'
|
|
273
|
+
],
|
|
274
|
+
:examples => <<~EXAMPLES.strip
|
|
275
|
+
#
|
|
276
|
+
# Get elements of a file name.
|
|
277
|
+
#
|
|
278
|
+
file_name [can] :
|
|
279
|
+
|
|
280
|
+
# The full file path, name and extension.
|
|
281
|
+
f [file] : /Users/me/dev/gloo/gloo.gemspec
|
|
282
|
+
|
|
283
|
+
on_load [script] :
|
|
284
|
+
show "Full file name: " + ^.f
|
|
285
|
+
|
|
286
|
+
check ^.f for get_name
|
|
287
|
+
show "The file name alone: " and it
|
|
288
|
+
|
|
289
|
+
check ^.f for get_ext
|
|
290
|
+
show "The file extension: " and it
|
|
291
|
+
|
|
292
|
+
check ^.f for get_parent
|
|
293
|
+
show "The file path: " and it
|
|
294
|
+
EXAMPLES
|
|
295
|
+
}
|
|
296
|
+
end
|
|
297
|
+
|
|
242
298
|
end
|
|
243
299
|
end
|
|
244
300
|
end
|
|
@@ -125,6 +125,35 @@ module Gloo
|
|
|
125
125
|
set_result result
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
+
# ---------------------------------------------------------------------
|
|
129
|
+
# Object Documentation
|
|
130
|
+
# ---------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
# Get the object's documentation data.
|
|
134
|
+
#
|
|
135
|
+
def self.doc_data
|
|
136
|
+
{
|
|
137
|
+
:name => KEYWORD,
|
|
138
|
+
:shortcut => KEYWORD_SHORT,
|
|
139
|
+
:description => 'Execute a system command.',
|
|
140
|
+
:children => [
|
|
141
|
+
"command (string) — Default: '#{DEFAULT_CMD}'. The command that will be sent to the system.",
|
|
142
|
+
'get_output (boolean) — Default: true. Should executing the command get the output and put it in the result object?',
|
|
143
|
+
'result (string) — The result of running the command. Only set if get_output is true.'
|
|
144
|
+
],
|
|
145
|
+
:messages => [
|
|
146
|
+
'run — Run the system level command. Sets the result value to the output of the command if get_output is true.'
|
|
147
|
+
],
|
|
148
|
+
:examples => <<~EXAMPLES.strip
|
|
149
|
+
date [system] :
|
|
150
|
+
command [string] : date
|
|
151
|
+
get_output [bool] : true
|
|
152
|
+
result [string] :
|
|
153
|
+
EXAMPLES
|
|
154
|
+
}
|
|
155
|
+
end
|
|
156
|
+
|
|
128
157
|
end
|
|
129
158
|
end
|
|
130
159
|
end
|
|
@@ -148,6 +148,41 @@ module Gloo
|
|
|
148
148
|
return "#{uri_value}#{p}"
|
|
149
149
|
end
|
|
150
150
|
|
|
151
|
+
# ---------------------------------------------------------------------
|
|
152
|
+
# Object Documentation
|
|
153
|
+
# ---------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
#
|
|
156
|
+
# Get the object's documentation data.
|
|
157
|
+
#
|
|
158
|
+
def self.doc_data
|
|
159
|
+
{
|
|
160
|
+
:name => KEYWORD,
|
|
161
|
+
:shortcut => KEYWORD_SHORT,
|
|
162
|
+
:description => 'Perform an HTTP Get.',
|
|
163
|
+
:children => [
|
|
164
|
+
"uri (string) — Example: 'https://web.site/'. The URI for the HTTP Get request.",
|
|
165
|
+
'params (container) — Collection of parameters for the HTTP Get.',
|
|
166
|
+
'result (string) — The result of the request. Whatever was returned from the HTTP Get call.',
|
|
167
|
+
'skip_ssl_verify (boolean) — Optional. Skip the SSL verification as part of the request.'
|
|
168
|
+
],
|
|
169
|
+
:messages => [
|
|
170
|
+
'run — Run the HTTP Get and update the result.'
|
|
171
|
+
],
|
|
172
|
+
:examples => <<~EXAMPLES.strip
|
|
173
|
+
g [http_get] :
|
|
174
|
+
uri [string] : http://api.sunrise-sunset.org/json
|
|
175
|
+
params [container] :
|
|
176
|
+
lat [string] : 36.7201600
|
|
177
|
+
lng [string] : -4.4203400
|
|
178
|
+
date [string] : today
|
|
179
|
+
result [string] :
|
|
180
|
+
|
|
181
|
+
> run g
|
|
182
|
+
EXAMPLES
|
|
183
|
+
}
|
|
184
|
+
end
|
|
185
|
+
|
|
151
186
|
end
|
|
152
187
|
end
|
|
153
188
|
end
|
|
@@ -152,6 +152,39 @@ module Gloo
|
|
|
152
152
|
return find_child_value( SKIP_SSL_VERIFY ) || false
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
+
# ---------------------------------------------------------------------
|
|
156
|
+
# Object Documentation
|
|
157
|
+
# ---------------------------------------------------------------------
|
|
158
|
+
|
|
159
|
+
#
|
|
160
|
+
# Get the object's documentation data.
|
|
161
|
+
#
|
|
162
|
+
def self.doc_data
|
|
163
|
+
{
|
|
164
|
+
:name => KEYWORD,
|
|
165
|
+
:shortcut => KEYWORD_SHORT,
|
|
166
|
+
:description => 'Perform an HTTP Post.',
|
|
167
|
+
:children => [
|
|
168
|
+
"uri (string) — Example: 'https://web.site/'. The URI for the HTTP Post.",
|
|
169
|
+
'body (container) — Collection of parameters for the HTTP Post.',
|
|
170
|
+
'result (string) — The result of the request. Whatever was returned in the body of the HTTP POST.',
|
|
171
|
+
'skip_ssl_verify (boolean) — Optional. Skip the SSL verification as part of the request.'
|
|
172
|
+
],
|
|
173
|
+
:messages => [
|
|
174
|
+
'run — Run the HTTP Post, sending the body data to the endpoint specified in the URI.'
|
|
175
|
+
],
|
|
176
|
+
:examples => <<~EXAMPLES.strip
|
|
177
|
+
post [post] :
|
|
178
|
+
txt [str] : Message from gloo!
|
|
179
|
+
uri [str] : https://my.service.com/my-long-token
|
|
180
|
+
body [can] :
|
|
181
|
+
text [alias] : post.txt
|
|
182
|
+
username [str] : me
|
|
183
|
+
on_load [script] : run post
|
|
184
|
+
EXAMPLES
|
|
185
|
+
}
|
|
186
|
+
end
|
|
187
|
+
|
|
155
188
|
end
|
|
156
189
|
end
|
|
157
190
|
end
|
data/lib/gloo/objs/web/json.rb
CHANGED
|
@@ -202,6 +202,46 @@ module Gloo
|
|
|
202
202
|
return data
|
|
203
203
|
end
|
|
204
204
|
|
|
205
|
+
# ---------------------------------------------------------------------
|
|
206
|
+
# Object Documentation
|
|
207
|
+
# ---------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
#
|
|
210
|
+
# Get the object's documentation data.
|
|
211
|
+
#
|
|
212
|
+
def self.doc_data
|
|
213
|
+
{
|
|
214
|
+
:name => KEYWORD,
|
|
215
|
+
:shortcut => KEYWORD_SHORT,
|
|
216
|
+
:description => 'JSON data in a text string.',
|
|
217
|
+
:messages => [
|
|
218
|
+
'get ({path}) — Get a value from the JSON data. Example: tell myjson to get (\'title\'). The parameter is the path in JSON to the value we want. The value is put into it.',
|
|
219
|
+
'set ({obj.path}) — Convert an object to an approximate JSON value. Example: tell myjson to set (my.object). The parameter is the path to the object used as the source. Note this is an approximate conversion — a gloo object can have both a simple value and be a container for child objects, which JSON can\'t represent the same way.',
|
|
220
|
+
'parse ({dst.path}) — Parse the JSON data and put values in the object specified by the parameter. Example: tell myjson to parse (path.to.dst).',
|
|
221
|
+
'pretty — Make the JSON format pretty.'
|
|
222
|
+
],
|
|
223
|
+
:examples => <<~EXAMPLES.strip
|
|
224
|
+
#
|
|
225
|
+
# Get values from within a JSON object.
|
|
226
|
+
#
|
|
227
|
+
|
|
228
|
+
json_get [can] :
|
|
229
|
+
on_load [script] :
|
|
230
|
+
tell json_get.payload to get ('msg')
|
|
231
|
+
show it
|
|
232
|
+
tell json_get.payload to get ('sub.data')
|
|
233
|
+
show it
|
|
234
|
+
tell json_get.payload to get ('sub.child.msg')
|
|
235
|
+
show it
|
|
236
|
+
payload [json] : BEGIN
|
|
237
|
+
{ "msg":"The message from inside a JSON block",
|
|
238
|
+
"sub":{"data":"in sub-object",
|
|
239
|
+
"child":{"msg":"third level"}} }
|
|
240
|
+
END
|
|
241
|
+
EXAMPLES
|
|
242
|
+
}
|
|
243
|
+
end
|
|
244
|
+
|
|
205
245
|
end
|
|
206
246
|
end
|
|
207
247
|
end
|
data/lib/gloo/objs/web/uri.rb
CHANGED
|
@@ -169,6 +169,46 @@ module Gloo
|
|
|
169
169
|
end
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
+
# ---------------------------------------------------------------------
|
|
173
|
+
# Object Documentation
|
|
174
|
+
# ---------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
#
|
|
177
|
+
# Get the object's documentation data.
|
|
178
|
+
#
|
|
179
|
+
def self.doc_data
|
|
180
|
+
{
|
|
181
|
+
:name => KEYWORD,
|
|
182
|
+
:shortcut => KEYWORD_SHORT,
|
|
183
|
+
:description => 'A URI or URL.',
|
|
184
|
+
:messages => [
|
|
185
|
+
'open — Open the URL in the default browser.',
|
|
186
|
+
'get_scheme — Get the URI scheme; example: http.',
|
|
187
|
+
'get_host — Get the URI host; example: google.com.',
|
|
188
|
+
'get_path — Get the URI resource path; example: /post.',
|
|
189
|
+
'get_query — Get the URI query parameters; example: id=121.',
|
|
190
|
+
'get_fragment — Get the URI fragment.',
|
|
191
|
+
'get_cert_expires — Get the web site\'s certificate expiration date.'
|
|
192
|
+
],
|
|
193
|
+
:examples => <<~EXAMPLES.strip
|
|
194
|
+
url [can] :
|
|
195
|
+
on_load [script] :
|
|
196
|
+
tell url.u to get_scheme
|
|
197
|
+
show "scheme: " + it
|
|
198
|
+
|
|
199
|
+
tell url.u to get_host
|
|
200
|
+
show "host: " + it
|
|
201
|
+
|
|
202
|
+
tell url.u to get_path
|
|
203
|
+
show "path: " + it
|
|
204
|
+
|
|
205
|
+
show "opening URL: " + url.u
|
|
206
|
+
tell url.u to open
|
|
207
|
+
u [uri] : https://my.url/path/1234
|
|
208
|
+
EXAMPLES
|
|
209
|
+
}
|
|
210
|
+
end
|
|
211
|
+
|
|
172
212
|
end
|
|
173
213
|
end
|
|
174
214
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2026 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A node in a shell's command tree.
|
|
5
|
+
# Ported from gloo-cli's CommandNode, namespace only.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Shell
|
|
10
|
+
class CommandNode
|
|
11
|
+
|
|
12
|
+
attr_reader :name, :description, :method, :obj
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Initialize a command node.
|
|
16
|
+
# Children are supplied lazily via a block, evaluated
|
|
17
|
+
# with the shell's Context whenever they're needed.
|
|
18
|
+
#
|
|
19
|
+
def initialize( name, description: '', method: nil, obj: nil, &children_block )
|
|
20
|
+
@name = name
|
|
21
|
+
@description = description
|
|
22
|
+
@method = method
|
|
23
|
+
@obj = obj
|
|
24
|
+
@children_block = children_block
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Get this node's children, given the current shell context.
|
|
29
|
+
# Returns an empty array for leaf nodes.
|
|
30
|
+
#
|
|
31
|
+
def children( context )
|
|
32
|
+
return [] unless @children_block
|
|
33
|
+
|
|
34
|
+
@children_block.call( context )
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2026 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A shell context. Data associated with a running shell session.
|
|
5
|
+
# Ported from gloo-cli's ShellContext, namespace only.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module Gloo
|
|
9
|
+
module Shell
|
|
10
|
+
class Context
|
|
11
|
+
|
|
12
|
+
attr_accessor :done
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Initialize the shell context.
|
|
16
|
+
#
|
|
17
|
+
def initialize
|
|
18
|
+
@done = false
|
|
19
|
+
@properties = {}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# Get a property value.
|
|
24
|
+
# Returns an empty array if the property doesn't exist.
|
|
25
|
+
#
|
|
26
|
+
def get( key )
|
|
27
|
+
key = key.to_sym
|
|
28
|
+
return @properties[ key ] if @properties.key?( key )
|
|
29
|
+
|
|
30
|
+
return []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Set a property value.
|
|
35
|
+
#
|
|
36
|
+
def set( key, value )
|
|
37
|
+
@properties[ key.to_sym ] = value
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# Add an item to a property list.
|
|
42
|
+
#
|
|
43
|
+
def add_to_list( key, item )
|
|
44
|
+
key = key.to_sym
|
|
45
|
+
list = get( key )
|
|
46
|
+
list = [] unless list.is_a?( Array )
|
|
47
|
+
|
|
48
|
+
list << item
|
|
49
|
+
set( key, list )
|
|
50
|
+
|
|
51
|
+
return list
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Check if a property exists.
|
|
56
|
+
#
|
|
57
|
+
def has?( key )
|
|
58
|
+
return @properties.key?( key.to_sym )
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Get all property keys.
|
|
63
|
+
#
|
|
64
|
+
def keys
|
|
65
|
+
return @properties.keys
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# Dynamic method access to properties.
|
|
70
|
+
# e.g. context.verbs is the same as context.get(:verbs),
|
|
71
|
+
# context.verbs = [...] is the same as context.set(:verbs, [...]).
|
|
72
|
+
#
|
|
73
|
+
def method_missing( method_name, *args, &block )
|
|
74
|
+
if method_name.to_s.end_with?( '=' )
|
|
75
|
+
key = method_name.to_s.chomp( '=' ).to_sym
|
|
76
|
+
set( key, args.first )
|
|
77
|
+
else
|
|
78
|
+
key = method_name.to_sym
|
|
79
|
+
get( key )
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Respond to missing methods for property access.
|
|
85
|
+
#
|
|
86
|
+
def respond_to_missing?( method_name, include_private = false )
|
|
87
|
+
key = method_name.to_s.chomp( '=' ).to_sym
|
|
88
|
+
return has?( key ) || super
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|