gloo-cli 1.3 → 1.5

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/lib/command.rb +18 -1
  3. data/lib/shell.rb +69 -45
  4. data/lib/shell_runner.rb +50 -8
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 055e863c3b9b427534255896f83ccbd28166c854ab083f8383342e76f787cb9d
4
- data.tar.gz: 914842fb1db12ed70efa03a48bd37c4074a431d7e03a5c001bb8ebddeddbf026
3
+ metadata.gz: 2a167c3410e526f3dec9aa9f07c430eefd8cd031c07820bd44afa9fccd90673e
4
+ data.tar.gz: 9addba3dafc9ce19639752a608051c58b9d0d521bf4105bfa5ed8272e92146cc
5
5
  SHA512:
6
- metadata.gz: bfa17e62d1e8e47477c7653ec2031e1886c651f5366a376ff8edd612d66efae74c4dfe19645f33ecb18ba458c293701fe28df26b2b4435999493fbe48d314daf
7
- data.tar.gz: 168d7997ac6136ee3d1a2cf2313276ae79ffb43fb14cc3a0ecb5f65cf92a9f3b7f968347e8f9ef25d6e04deeec68ecc4f3dfdddf7e1184aafc68940bc0edbd4d
6
+ metadata.gz: 266e4236bf6f3abd8d5baf20859262eacb7b109da6cce66789587d6d17e4b4b9aed2e7e70d5ebd4a69868868c8fa2636cbb5c68d1265668eb15dff63121c08f5
7
+ data.tar.gz: 4e47277e9afaf8b01a9cd00312d2ba8bd9b9457705db97acccc8ef323ff09a260aabe6668fdd235c4684d4bdfca48421c3ba32def50343c5f270c8c70987633a
data/lib/command.rb CHANGED
@@ -8,6 +8,7 @@ class Command < Gloo::Core::Obj
8
8
 
9
9
  KEYWORD = 'command'.freeze
10
10
  KEYWORD_SHORT = 'command'.freeze
11
+ NAME = 'name'.freeze
11
12
  DESCRIPTION = 'description'.freeze
12
13
  ACTION = 'action'.freeze
13
14
  DYNAMIC = 'dynamic'.freeze
@@ -16,6 +17,7 @@ class Command < Gloo::Core::Obj
16
17
  CONTEXT = 'context'.freeze
17
18
  OPTIONS = 'options'.freeze
18
19
  OPTIONS_KEY = 'options_key'.freeze
20
+ ON_ERROR = 'on_error'.freeze
19
21
 
20
22
  #
21
23
  # The name of the object type.
@@ -105,14 +107,29 @@ class Command < Gloo::Core::Obj
105
107
  Gloo::Exec::Dispatch.message( @engine, 'run', o )
106
108
  end
107
109
 
110
+ #
111
+ # Run the action script with context.
112
+ #
108
113
  def run_action_with_context( context )
109
114
  o = find_child ACTION
110
115
  return unless o
111
116
 
112
117
  ctx = find_child CONTEXT
113
118
  ctx.set_value( context ) if ctx
114
-
119
+
120
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
121
+ end
122
+
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
+
115
131
  Gloo::Exec::Dispatch.message( @engine, 'run', o )
132
+ return true
116
133
  end
117
134
 
118
135
 
data/lib/shell.rb CHANGED
@@ -11,6 +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
+ ON_UNKNOWN_CMD = 'on_unknown_command'.freeze
16
+ ON_EMPTY_CMD = 'on_empty_command'.freeze
17
+ BEFORE_ACTION = 'before_action'.freeze
18
+ AFTER_ACTION = 'after_action'.freeze
14
19
 
15
20
  #
16
21
  # The name of the object type.
@@ -93,6 +98,8 @@ class Shell < Gloo::Core::Obj
93
98
 
94
99
  #
95
100
  # Start the shell.
101
+ # If CLI args were passed, execute that command once and return.
102
+ # Otherwise, enter the interactive REPL.
96
103
  #
97
104
  def msg_start
98
105
  runner = get_runner
@@ -100,7 +107,12 @@ class Shell < Gloo::Core::Obj
100
107
  # add_test_commands
101
108
  add_quit_command
102
109
 
103
- runner.start
110
+ cmd_tokens = @engine.args.files
111
+ if cmd_tokens.any?
112
+ runner.execute_once( cmd_tokens )
113
+ else
114
+ runner.start
115
+ end
104
116
  end
105
117
 
106
118
  #
@@ -127,6 +139,62 @@ class Shell < Gloo::Core::Obj
127
139
  @runner.set_context( key, value )
128
140
  end
129
141
 
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
+ #
155
+ # Run the on_unknown_cmd script if one exists.
156
+ # Returns true if the script was found and run, false otherwise.
157
+ #
158
+ def run_on_unknown_cmd
159
+ o = find_child ON_UNKNOWN_CMD
160
+ return false unless o
161
+
162
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
163
+ return true
164
+ end
165
+
166
+ #
167
+ # Run the on_empty_command script if one exists.
168
+ # Returns true if the script was found and run, false otherwise.
169
+ #
170
+ def run_on_empty_cmd
171
+ o = find_child ON_EMPTY_CMD
172
+ return false unless o
173
+
174
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
175
+ return true
176
+ end
177
+
178
+ #
179
+ # Run the before_action script if one exists.
180
+ #
181
+ def run_before_action
182
+ o = find_child BEFORE_ACTION
183
+ return unless o
184
+
185
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
186
+ end
187
+
188
+ #
189
+ # Run the after_action script if one exists.
190
+ #
191
+ def run_after_action
192
+ o = find_child AFTER_ACTION
193
+ return unless o
194
+
195
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
196
+ end
197
+
130
198
 
131
199
  # ---------------------------------------------------------------------
132
200
  # Commands
@@ -145,48 +213,4 @@ class Shell < Gloo::Core::Obj
145
213
  })
146
214
  end
147
215
 
148
- # def add_test_commands
149
- # @runner.add_command_node({
150
- # name: "add",
151
- # description: "add a project",
152
- # method: "cmd_add"
153
- # })
154
-
155
- # @runner.add_command_node({
156
- # name: "show",
157
- # description: "show a resource",
158
- # children: [
159
- # {
160
- # name: "project",
161
- # description: "show a project",
162
- # dynamic: true,
163
- # source: "projects"
164
- # },
165
- # {
166
- # name: "task",
167
- # description: "show a task",
168
- # dynamic: true,
169
- # source: "tasks"
170
- # }
171
- # ]
172
- # })
173
-
174
- # @runner.add_command_node({
175
- # name: "list",
176
- # description: "list resources",
177
- # children: [
178
- # {
179
- # name: "projects",
180
- # description: "list projects",
181
- # method: "cmd_projects"
182
- # },
183
- # {
184
- # name: "tasks",
185
- # description: "list tasks",
186
- # method: "cmd_tasks"
187
- # }
188
- # ]
189
- # })
190
- # end
191
-
192
216
  end
data/lib/shell_runner.rb CHANGED
@@ -9,6 +9,8 @@ require "readline"
9
9
  class ShellRunner
10
10
 
11
11
  DEFAULT_PROMPT = " -> "
12
+ UNKNOWN_COMMAND = "Unknown command".freeze
13
+
12
14
  #
13
15
  # Initialize the shell runner
14
16
  #
@@ -48,9 +50,23 @@ class ShellRunner
48
50
  return p ? p + ' ' : DEFAULT_PROMPT
49
51
  end
50
52
 
51
- #
53
+ #
54
+ # Handle an empty command — run on_empty_command if defined, otherwise do nothing.
55
+ #
56
+ def handle_empty_command
57
+ @obj.run_on_empty_cmd
58
+ end
59
+
60
+ #
61
+ # Handle an unknown command — run on_unknown_cmd if defined, otherwise show default message.
62
+ #
63
+ def handle_unknown_command
64
+ @obj.run_on_unknown_cmd || puts( UNKNOWN_COMMAND )
65
+ end
66
+
67
+ #
52
68
  # Quit the shell.
53
- #
69
+ #
54
70
  def cmd_quit( obj, context )
55
71
  puts "Quitting…"
56
72
  context.done = true
@@ -67,15 +83,21 @@ class ShellRunner
67
83
  end
68
84
  end
69
85
 
70
- def cmd_obj_action_with_context( cmd_node, parent_node = nil )
86
+ #
87
+ # Run an action on an object with context.
88
+ #
89
+ def cmd_obj_action_with_context( cmd_node, parent_node = nil )
71
90
  if parent_node
72
91
  pn = Gloo::Core::Pn.new( @engine, parent_node.obj )
73
92
  command = pn.resolve
74
93
  if command
75
- command.run_action_with_context( cmd_node.name )
94
+ begin
95
+ command.run_action_with_context( cmd_node.name )
96
+ rescue => e
97
+ command.run_on_error || @obj.run_on_error
98
+ end
76
99
  end
77
100
  end
78
-
79
101
  end
80
102
 
81
103
 
@@ -162,7 +184,22 @@ class ShellRunner
162
184
  # REPL
163
185
  # ---------------------------------------------------------------------
164
186
 
165
- #
187
+ #
188
+ # Execute a single command from the given tokens and return.
189
+ # Used when a command is passed directly from the CLI.
190
+ #
191
+ def execute_once( tokens )
192
+ result = traverse( @root, tokens )
193
+ if result[:node]
194
+ @obj.run_before_action
195
+ execute_command( result[:node], tokens, result[:parent] )
196
+ @obj.run_after_action
197
+ else
198
+ handle_unknown_command
199
+ end
200
+ end
201
+
202
+ #
166
203
  # Traverse the command tree to find the matching node
167
204
  #
168
205
  # @param node [CommandNode] The current node
@@ -228,14 +265,19 @@ class ShellRunner
228
265
 
229
266
  while ( ! @context.done && (line = Readline.readline(prompt, true)) )
230
267
  tokens = line.strip.split(" ")
231
- next if tokens.empty?
268
+ if tokens.empty?
269
+ handle_empty_command
270
+ next
271
+ end
232
272
 
233
273
  result = traverse( @root, tokens )
234
274
 
235
275
  if result[:node]
276
+ @obj.run_before_action
236
277
  execute_command( result[:node], tokens, result[:parent] )
278
+ @obj.run_after_action
237
279
  else
238
- puts "Unknown command"
280
+ handle_unknown_command
239
281
  end
240
282
  end
241
283
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gloo-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.3'
4
+ version: '1.5'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Crane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-01 00:00:00.000000000 Z
11
+ date: 2026-06-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Adds CLI support to Gloo.
14
14
  email: