cmdx 0.5.0 → 1.0.1
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/.DS_Store +0 -0
- data/.cursor/rules/cursor-instructions.mdc +6 -0
- data/.rubocop.yml +19 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +95 -28
- data/README.md +73 -25
- data/docs/ai_prompts.md +319 -0
- data/docs/basics/call.md +234 -14
- data/docs/basics/chain.md +280 -0
- data/docs/basics/context.md +241 -33
- data/docs/basics/setup.md +85 -12
- data/docs/callbacks.md +283 -0
- data/docs/configuration.md +155 -30
- data/docs/getting_started.md +145 -22
- data/docs/internationalization.md +148 -0
- data/docs/interruptions/exceptions.md +198 -11
- data/docs/interruptions/faults.md +196 -44
- data/docs/interruptions/halt.md +188 -35
- data/docs/logging.md +204 -53
- data/docs/middlewares.md +745 -0
- data/docs/outcomes/result.md +305 -10
- data/docs/outcomes/states.md +212 -31
- data/docs/outcomes/statuses.md +284 -30
- data/docs/parameters/coercions.md +411 -29
- data/docs/parameters/defaults.md +258 -25
- data/docs/parameters/definitions.md +247 -72
- data/docs/parameters/namespacing.md +259 -27
- data/docs/parameters/validations.md +173 -168
- data/docs/testing.md +560 -0
- data/docs/tips_and_tricks.md +103 -42
- data/docs/workflows.md +329 -0
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/callback.rb +69 -0
- data/lib/cmdx/callback_registry.rb +106 -0
- data/lib/cmdx/chain.rb +190 -0
- data/lib/cmdx/chain_inspector.rb +149 -0
- data/lib/cmdx/chain_serializer.rb +175 -0
- data/lib/cmdx/coercions/array.rb +37 -0
- data/lib/cmdx/coercions/big_decimal.rb +33 -0
- data/lib/cmdx/coercions/boolean.rb +41 -1
- data/lib/cmdx/coercions/complex.rb +31 -0
- data/lib/cmdx/coercions/date.rb +39 -0
- data/lib/cmdx/coercions/date_time.rb +39 -0
- data/lib/cmdx/coercions/float.rb +31 -0
- data/lib/cmdx/coercions/hash.rb +42 -0
- data/lib/cmdx/coercions/integer.rb +32 -0
- data/lib/cmdx/coercions/rational.rb +31 -0
- data/lib/cmdx/coercions/string.rb +31 -0
- data/lib/cmdx/coercions/time.rb +39 -0
- data/lib/cmdx/coercions/virtual.rb +31 -0
- data/lib/cmdx/configuration.rb +217 -9
- data/lib/cmdx/context.rb +173 -2
- data/lib/cmdx/core_ext/hash.rb +72 -0
- data/lib/cmdx/core_ext/module.rb +94 -0
- data/lib/cmdx/core_ext/object.rb +105 -0
- data/lib/cmdx/correlator.rb +217 -0
- data/lib/cmdx/error.rb +210 -8
- data/lib/cmdx/errors.rb +256 -1
- data/lib/cmdx/fault.rb +177 -2
- data/lib/cmdx/faults.rb +158 -2
- data/lib/cmdx/immutator.rb +121 -2
- data/lib/cmdx/lazy_struct.rb +261 -18
- data/lib/cmdx/log_formatters/json.rb +46 -0
- data/lib/cmdx/log_formatters/key_value.rb +46 -0
- data/lib/cmdx/log_formatters/line.rb +54 -0
- data/lib/cmdx/log_formatters/logstash.rb +64 -0
- data/lib/cmdx/log_formatters/pretty_json.rb +57 -0
- data/lib/cmdx/log_formatters/pretty_key_value.rb +51 -0
- data/lib/cmdx/log_formatters/pretty_line.rb +60 -0
- data/lib/cmdx/log_formatters/raw.rb +54 -0
- data/lib/cmdx/logger.rb +85 -0
- data/lib/cmdx/logger_ansi.rb +93 -7
- data/lib/cmdx/logger_serializer.rb +116 -0
- data/lib/cmdx/middleware.rb +74 -0
- data/lib/cmdx/middleware_registry.rb +106 -0
- data/lib/cmdx/middlewares/correlate.rb +266 -0
- data/lib/cmdx/middlewares/timeout.rb +232 -0
- data/lib/cmdx/parameter.rb +228 -1
- data/lib/cmdx/parameter_inspector.rb +61 -0
- data/lib/cmdx/parameter_registry.rb +125 -0
- data/lib/cmdx/parameter_serializer.rb +83 -0
- data/lib/cmdx/parameter_validator.rb +62 -0
- data/lib/cmdx/parameter_value.rb +109 -1
- data/lib/cmdx/parameters_inspector.rb +59 -0
- data/lib/cmdx/parameters_serializer.rb +102 -0
- data/lib/cmdx/railtie.rb +123 -3
- data/lib/cmdx/result.rb +367 -25
- data/lib/cmdx/result_ansi.rb +105 -9
- data/lib/cmdx/result_inspector.rb +76 -0
- data/lib/cmdx/result_logger.rb +90 -3
- data/lib/cmdx/result_serializer.rb +137 -0
- data/lib/cmdx/rspec/result_matchers.rb +917 -0
- data/lib/cmdx/rspec/task_matchers.rb +570 -0
- data/lib/cmdx/task.rb +405 -37
- data/lib/cmdx/task_serializer.rb +74 -2
- data/lib/cmdx/utils/ansi_color.rb +95 -0
- data/lib/cmdx/utils/log_timestamp.rb +48 -0
- data/lib/cmdx/utils/monotonic_runtime.rb +71 -4
- data/lib/cmdx/utils/name_affix.rb +78 -0
- data/lib/cmdx/validators/custom.rb +82 -0
- data/lib/cmdx/validators/exclusion.rb +94 -0
- data/lib/cmdx/validators/format.rb +102 -8
- data/lib/cmdx/validators/inclusion.rb +104 -0
- data/lib/cmdx/validators/length.rb +128 -0
- data/lib/cmdx/validators/numeric.rb +128 -0
- data/lib/cmdx/validators/presence.rb +93 -7
- data/lib/cmdx/version.rb +7 -1
- data/lib/cmdx/workflow.rb +394 -0
- data/lib/cmdx.rb +25 -64
- data/lib/generators/cmdx/install_generator.rb +37 -1
- data/lib/generators/cmdx/task_generator.rb +69 -1
- data/lib/generators/cmdx/templates/install.rb +43 -15
- data/lib/generators/cmdx/workflow_generator.rb +109 -0
- data/lib/locales/ar.yml +36 -0
- data/lib/locales/cs.yml +36 -0
- data/lib/locales/da.yml +36 -0
- data/lib/locales/de.yml +36 -0
- data/lib/locales/el.yml +36 -0
- data/lib/locales/en.yml +20 -20
- data/lib/locales/es.yml +20 -20
- data/lib/locales/fi.yml +36 -0
- data/lib/locales/fr.yml +36 -0
- data/lib/locales/he.yml +36 -0
- data/lib/locales/hi.yml +36 -0
- data/lib/locales/it.yml +36 -0
- data/lib/locales/ja.yml +36 -0
- data/lib/locales/ko.yml +36 -0
- data/lib/locales/nl.yml +36 -0
- data/lib/locales/no.yml +36 -0
- data/lib/locales/pl.yml +36 -0
- data/lib/locales/pt.yml +36 -0
- data/lib/locales/ru.yml +36 -0
- data/lib/locales/sv.yml +36 -0
- data/lib/locales/th.yml +36 -0
- data/lib/locales/tr.yml +36 -0
- data/lib/locales/vi.yml +36 -0
- data/lib/locales/zh.yml +36 -0
- metadata +77 -15
- data/docs/basics/run.md +0 -34
- data/docs/batch.md +0 -53
- data/docs/example.md +0 -82
- data/docs/hooks.md +0 -62
- data/lib/cmdx/batch.rb +0 -43
- data/lib/cmdx/parameters.rb +0 -35
- data/lib/cmdx/run.rb +0 -39
- data/lib/cmdx/run_inspector.rb +0 -26
- data/lib/cmdx/run_serializer.rb +0 -20
- data/lib/cmdx/task_hook.rb +0 -18
- data/lib/generators/cmdx/batch_generator.rb +0 -30
- /data/lib/generators/cmdx/templates/{batch.rb.tt → workflow.rb.tt} +0 -0
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmdx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Gomez
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bigdecimal
|
@@ -51,6 +51,20 @@ dependencies:
|
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: zeitwerk
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
54
68
|
- !ruby/object:Gem::Dependency
|
55
69
|
name: bundler
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,6 +79,20 @@ dependencies:
|
|
65
79
|
- - ">="
|
66
80
|
- !ruby/object:Gem::Version
|
67
81
|
version: '0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: ostruct
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
68
96
|
- !ruby/object:Gem::Dependency
|
69
97
|
name: rake
|
70
98
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,6 +186,7 @@ extensions: []
|
|
158
186
|
extra_rdoc_files: []
|
159
187
|
files:
|
160
188
|
- ".DS_Store"
|
189
|
+
- ".cursor/rules/cursor-instructions.mdc"
|
161
190
|
- ".rspec"
|
162
191
|
- ".rubocop.yml"
|
163
192
|
- ".ruby-version"
|
@@ -166,19 +195,20 @@ files:
|
|
166
195
|
- LICENSE.txt
|
167
196
|
- README.md
|
168
197
|
- Rakefile
|
198
|
+
- docs/ai_prompts.md
|
169
199
|
- docs/basics/call.md
|
200
|
+
- docs/basics/chain.md
|
170
201
|
- docs/basics/context.md
|
171
|
-
- docs/basics/run.md
|
172
202
|
- docs/basics/setup.md
|
173
|
-
- docs/
|
203
|
+
- docs/callbacks.md
|
174
204
|
- docs/configuration.md
|
175
|
-
- docs/example.md
|
176
205
|
- docs/getting_started.md
|
177
|
-
- docs/
|
206
|
+
- docs/internationalization.md
|
178
207
|
- docs/interruptions/exceptions.md
|
179
208
|
- docs/interruptions/faults.md
|
180
209
|
- docs/interruptions/halt.md
|
181
210
|
- docs/logging.md
|
211
|
+
- docs/middlewares.md
|
182
212
|
- docs/outcomes/result.md
|
183
213
|
- docs/outcomes/states.md
|
184
214
|
- docs/outcomes/statuses.md
|
@@ -187,10 +217,16 @@ files:
|
|
187
217
|
- docs/parameters/definitions.md
|
188
218
|
- docs/parameters/namespacing.md
|
189
219
|
- docs/parameters/validations.md
|
220
|
+
- docs/testing.md
|
190
221
|
- docs/tips_and_tricks.md
|
222
|
+
- docs/workflows.md
|
191
223
|
- lib/cmdx.rb
|
192
224
|
- lib/cmdx/.DS_Store
|
193
|
-
- lib/cmdx/
|
225
|
+
- lib/cmdx/callback.rb
|
226
|
+
- lib/cmdx/callback_registry.rb
|
227
|
+
- lib/cmdx/chain.rb
|
228
|
+
- lib/cmdx/chain_inspector.rb
|
229
|
+
- lib/cmdx/chain_serializer.rb
|
194
230
|
- lib/cmdx/coercions/array.rb
|
195
231
|
- lib/cmdx/coercions/big_decimal.rb
|
196
232
|
- lib/cmdx/coercions/boolean.rb
|
@@ -209,6 +245,7 @@ files:
|
|
209
245
|
- lib/cmdx/core_ext/hash.rb
|
210
246
|
- lib/cmdx/core_ext/module.rb
|
211
247
|
- lib/cmdx/core_ext/object.rb
|
248
|
+
- lib/cmdx/correlator.rb
|
212
249
|
- lib/cmdx/error.rb
|
213
250
|
- lib/cmdx/errors.rb
|
214
251
|
- lib/cmdx/fault.rb
|
@@ -226,12 +263,16 @@ files:
|
|
226
263
|
- lib/cmdx/logger.rb
|
227
264
|
- lib/cmdx/logger_ansi.rb
|
228
265
|
- lib/cmdx/logger_serializer.rb
|
266
|
+
- lib/cmdx/middleware.rb
|
267
|
+
- lib/cmdx/middleware_registry.rb
|
268
|
+
- lib/cmdx/middlewares/correlate.rb
|
269
|
+
- lib/cmdx/middlewares/timeout.rb
|
229
270
|
- lib/cmdx/parameter.rb
|
230
271
|
- lib/cmdx/parameter_inspector.rb
|
272
|
+
- lib/cmdx/parameter_registry.rb
|
231
273
|
- lib/cmdx/parameter_serializer.rb
|
232
274
|
- lib/cmdx/parameter_validator.rb
|
233
275
|
- lib/cmdx/parameter_value.rb
|
234
|
-
- lib/cmdx/parameters.rb
|
235
276
|
- lib/cmdx/parameters_inspector.rb
|
236
277
|
- lib/cmdx/parameters_serializer.rb
|
237
278
|
- lib/cmdx/railtie.rb
|
@@ -240,11 +281,9 @@ files:
|
|
240
281
|
- lib/cmdx/result_inspector.rb
|
241
282
|
- lib/cmdx/result_logger.rb
|
242
283
|
- lib/cmdx/result_serializer.rb
|
243
|
-
- lib/cmdx/
|
244
|
-
- lib/cmdx/
|
245
|
-
- lib/cmdx/run_serializer.rb
|
284
|
+
- lib/cmdx/rspec/result_matchers.rb
|
285
|
+
- lib/cmdx/rspec/task_matchers.rb
|
246
286
|
- lib/cmdx/task.rb
|
247
|
-
- lib/cmdx/task_hook.rb
|
248
287
|
- lib/cmdx/task_serializer.rb
|
249
288
|
- lib/cmdx/utils/ansi_color.rb
|
250
289
|
- lib/cmdx/utils/log_timestamp.rb
|
@@ -258,14 +297,37 @@ files:
|
|
258
297
|
- lib/cmdx/validators/numeric.rb
|
259
298
|
- lib/cmdx/validators/presence.rb
|
260
299
|
- lib/cmdx/version.rb
|
261
|
-
- lib/
|
300
|
+
- lib/cmdx/workflow.rb
|
262
301
|
- lib/generators/cmdx/install_generator.rb
|
263
302
|
- lib/generators/cmdx/task_generator.rb
|
264
|
-
- lib/generators/cmdx/templates/batch.rb.tt
|
265
303
|
- lib/generators/cmdx/templates/install.rb
|
266
304
|
- lib/generators/cmdx/templates/task.rb.tt
|
305
|
+
- lib/generators/cmdx/templates/workflow.rb.tt
|
306
|
+
- lib/generators/cmdx/workflow_generator.rb
|
307
|
+
- lib/locales/ar.yml
|
308
|
+
- lib/locales/cs.yml
|
309
|
+
- lib/locales/da.yml
|
310
|
+
- lib/locales/de.yml
|
311
|
+
- lib/locales/el.yml
|
267
312
|
- lib/locales/en.yml
|
268
313
|
- lib/locales/es.yml
|
314
|
+
- lib/locales/fi.yml
|
315
|
+
- lib/locales/fr.yml
|
316
|
+
- lib/locales/he.yml
|
317
|
+
- lib/locales/hi.yml
|
318
|
+
- lib/locales/it.yml
|
319
|
+
- lib/locales/ja.yml
|
320
|
+
- lib/locales/ko.yml
|
321
|
+
- lib/locales/nl.yml
|
322
|
+
- lib/locales/no.yml
|
323
|
+
- lib/locales/pl.yml
|
324
|
+
- lib/locales/pt.yml
|
325
|
+
- lib/locales/ru.yml
|
326
|
+
- lib/locales/sv.yml
|
327
|
+
- lib/locales/th.yml
|
328
|
+
- lib/locales/tr.yml
|
329
|
+
- lib/locales/vi.yml
|
330
|
+
- lib/locales/zh.yml
|
269
331
|
homepage: https://github.com/drexed/cmdx
|
270
332
|
licenses:
|
271
333
|
- MIT
|
@@ -290,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
290
352
|
- !ruby/object:Gem::Version
|
291
353
|
version: '0'
|
292
354
|
requirements: []
|
293
|
-
rubygems_version: 3.6.
|
355
|
+
rubygems_version: 3.6.9
|
294
356
|
specification_version: 4
|
295
357
|
summary: Command (aka service) objects with intent
|
296
358
|
test_files: []
|
data/docs/basics/run.md
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# Basics - Run
|
2
|
-
|
3
|
-
A run represents a group of tasks executed as part of collection.
|
4
|
-
|
5
|
-
When building complex tasks, it's best to pass the parents context to subtasks
|
6
|
-
(unless necessary or preventative) so that it gains automated indexing and the
|
7
|
-
parents `run_id`. This makes it easy to identify all tasks involved in one
|
8
|
-
execution from logging and stdout console calls.
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
class ProcessOrderTask < CMDx::Task
|
12
|
-
|
13
|
-
def call
|
14
|
-
# Subtasks inherit the ProcessOrderTask run_id:
|
15
|
-
SendEmailConfirmationTask.call(context)
|
16
|
-
NotifyPartnerWarehousesTask.call(context)
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
result = ProcessOrderTask.call
|
22
|
-
puts result.run.to_s
|
23
|
-
|
24
|
-
# Task name Index Run ID Task ID etc
|
25
|
-
# -----------------------------------------------------------------
|
26
|
-
#=> ProcessOrderTask 0 foobar123 abc123 ...
|
27
|
-
#=> SendEmailConfirmationTask 1 foobar123 def456 ...
|
28
|
-
#=> NotifyPartnerWarehousesTask 2 foobar123 ghi789 ...
|
29
|
-
```
|
30
|
-
|
31
|
-
---
|
32
|
-
|
33
|
-
- **Prev:** [Basics - Context](https://github.com/drexed/cmdx/blob/main/docs/basics/context.md)
|
34
|
-
- **Next:** [Interruptions - Halt](https://github.com/drexed/cmdx/blob/main/docs/interruptions/halt.md)
|
data/docs/batch.md
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# Batch
|
2
|
-
|
3
|
-
A CMDx::Batch is a task that calls other tasks in a linear fashion. The
|
4
|
-
context is passed down to each task, building on it knowledge with
|
5
|
-
each step. This is useful for composing multiple steps into one call.
|
6
|
-
|
7
|
-
> [!WARNING]
|
8
|
-
> Do **NOT** define a call method in this class. The batch class automatically
|
9
|
-
> defines the call logic.
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
class BatchProcessCheckout < CMDx::Batch
|
13
|
-
|
14
|
-
# Task level settings:
|
15
|
-
task_settings!(batch_halt: CMDx::Result::FAILED)
|
16
|
-
|
17
|
-
# Single declaration:
|
18
|
-
process FinalizeInvoiceTask
|
19
|
-
|
20
|
-
# Multiple declarations:
|
21
|
-
process SendConfirmationEmailTask, SendConfirmationTextTask
|
22
|
-
|
23
|
-
# With options (applies to all declared in that group):
|
24
|
-
process BatchNotifyPartnerWarehouses, batch_halt: [CMDx::Result::SKIPPED, CMDx::Result::FAILED]
|
25
|
-
process BatchNotifyUsaWarehouses, unless: proc { context.invoice.fulfilled_in_house? }
|
26
|
-
|
27
|
-
end
|
28
|
-
```
|
29
|
-
|
30
|
-
> [!IMPORTANT]
|
31
|
-
> Process steps are executed in the order they are declared (FIFO: first in, first out).
|
32
|
-
|
33
|
-
The `process` method support the following options:
|
34
|
-
|
35
|
-
| Option | Description |
|
36
|
-
| ------------- | ----------- |
|
37
|
-
| `:if` | Specifies a callable method, proc or string to determine if processing steps should occur. |
|
38
|
-
| `:unless` | Specifies a callable method, proc, or string to determine if processing steps should not occur. |
|
39
|
-
| `:batch_halt` | Sets which result statuses processing of further steps should be prevented. (default: `CMDx::Result::FAILED`) |
|
40
|
-
|
41
|
-
> [!NOTE]
|
42
|
-
> Batches stop execution on `failed` by default. This is due to the concept
|
43
|
-
> of `skipped` being a bypass mechanism, rather than a choke point in execution.
|
44
|
-
|
45
|
-
## Generator
|
46
|
-
|
47
|
-
Run `rails g cmdx:batch [NAME]` to create a batch task template file under `app/cmds`.
|
48
|
-
Tasks will inherit from `ApplicationBatch` if available or fall back to `CMDx::Batch`.
|
49
|
-
|
50
|
-
---
|
51
|
-
|
52
|
-
- **Prev:** [Hooks](https://github.com/drexed/cmdx/blob/main/docs/hooks.md)
|
53
|
-
- **Next:** [Logging](https://github.com/drexed/cmdx/blob/main/docs/logging.md)
|
data/docs/example.md
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
# Example
|
2
|
-
|
3
|
-
The following is a full example of task that is commonly implemented.
|
4
|
-
|
5
|
-
## Setup
|
6
|
-
|
7
|
-
```ruby
|
8
|
-
class ProcessOrderTask < CMDx::Task
|
9
|
-
|
10
|
-
required :order
|
11
|
-
required :billing_details, :shipping_details, from: :order
|
12
|
-
|
13
|
-
optional :package do
|
14
|
-
required :delivery_company, default: -> { Current.account.premium? ? "UPS" : "DHL" }
|
15
|
-
optional :weight, :volume, type: :float
|
16
|
-
end
|
17
|
-
|
18
|
-
after_execution :track_metrics
|
19
|
-
|
20
|
-
def call
|
21
|
-
if cart_abandoned?
|
22
|
-
skip!(reason: "Cart was abandoned due to 30 days of inactivity")
|
23
|
-
elsif cart_items_out_of_stock?
|
24
|
-
fail!(reason: "Items in the cart are out of stock", item: [123, 987])
|
25
|
-
else
|
26
|
-
charge_payment_method
|
27
|
-
ship_order_packages
|
28
|
-
send_confirmation_email
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def charge_payment_method
|
35
|
-
@charge_payment_method ||= ChargePaymentMethodTask.call(details: billing_details)
|
36
|
-
end
|
37
|
-
|
38
|
-
def ship_order_packages
|
39
|
-
@ship_order_packages ||= ShipOrderPackagesTask.call(details: shipping_details)
|
40
|
-
end
|
41
|
-
|
42
|
-
def send_confirmation_email
|
43
|
-
return if charge_payment_method.failed? || ship_order_packages.bad?
|
44
|
-
|
45
|
-
BatchSendConfirmationNotifications.call(context)
|
46
|
-
end
|
47
|
-
|
48
|
-
def track_metrics
|
49
|
-
if Rails.env.development?
|
50
|
-
logger.debug { "Sending metrics to collector" }
|
51
|
-
else
|
52
|
-
TrackMetricsTask.call(metric: :process_order, status: order.status)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
```
|
58
|
-
|
59
|
-
## Execution
|
60
|
-
|
61
|
-
```ruby
|
62
|
-
class OrdersController < ApplicationController
|
63
|
-
|
64
|
-
def create
|
65
|
-
task = ProcessOrderTask.call(order_params)
|
66
|
-
|
67
|
-
if task.success?
|
68
|
-
flash[:success] = "Order is on its way!"
|
69
|
-
redirect_to(my_orders_path)
|
70
|
-
else
|
71
|
-
flash[:error] = "Whoops something is wrong: #{task.metadata[:reason]}"
|
72
|
-
render(:new)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
```
|
78
|
-
|
79
|
-
---
|
80
|
-
|
81
|
-
- **Prev:** [Tips & Tricks](https://github.com/drexed/cmdx/blob/main/docs/tips_and_tricks.md)
|
82
|
-
- **Next:** [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md)
|
data/docs/hooks.md
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# Hooks
|
2
|
-
|
3
|
-
Hooks (callbacks) run logic at task transition points. Callable hooks have access
|
4
|
-
to all the same information as the `call` method.
|
5
|
-
|
6
|
-
> [!TIP]
|
7
|
-
> Hooks are inheritable which is handy for setting up global logic execution,
|
8
|
-
> eg: setting tracking markers, account plan checks, etc.
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
class ProcessOrderTask < CMDx::Task
|
12
|
-
|
13
|
-
# Symbol or string declaration:
|
14
|
-
after_validation :verify_message_starting_chars
|
15
|
-
|
16
|
-
# Proc or lambda declaration:
|
17
|
-
on_complete -> { send_telemetry_data }
|
18
|
-
|
19
|
-
# Multiple declarations:
|
20
|
-
on_success :increment_success_task_counter, :scrub_secret_message_data
|
21
|
-
|
22
|
-
# With options (applies to all declared in that group):
|
23
|
-
on_failure :increment_failure_task_counter, if: :worth_keep_track?
|
24
|
-
|
25
|
-
def call
|
26
|
-
# Do work...
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
```
|
31
|
-
|
32
|
-
The hook methods support the following options:
|
33
|
-
|
34
|
-
| Option | Description |
|
35
|
-
| ------------- | ----------- |
|
36
|
-
| `:if` | Specifies a callable method, proc or string to determine if hook processing should occur. |
|
37
|
-
| `:unless` | Specifies a callable method, proc, or string to determine if hook processing should not occur. |
|
38
|
-
|
39
|
-
## Order
|
40
|
-
|
41
|
-
Hook types are executed in the following order:
|
42
|
-
|
43
|
-
```ruby
|
44
|
-
0. before_execution
|
45
|
-
1. on_executing
|
46
|
-
2. before_validation
|
47
|
-
3. after_validation
|
48
|
-
4. on_[complete, interrupted]
|
49
|
-
5. on_executed
|
50
|
-
6. on_[success, skipped, failed]
|
51
|
-
7. on_good
|
52
|
-
8. on_bad
|
53
|
-
9. after_execution
|
54
|
-
```
|
55
|
-
|
56
|
-
> [!IMPORTANT]
|
57
|
-
> Callable hooks are executed in the order they are declared (FIFO: first in, first out).
|
58
|
-
|
59
|
-
---
|
60
|
-
|
61
|
-
- **Prev:** [Outcomes - States](https://github.com/drexed/cmdx/blob/main/docs/outcomes/states.md)
|
62
|
-
- **Next:** [Batch](https://github.com/drexed/cmdx/blob/main/docs/batch.md)
|
data/lib/cmdx/batch.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CMDx
|
4
|
-
class Batch < Task
|
5
|
-
|
6
|
-
Group = Struct.new(:tasks, :options)
|
7
|
-
|
8
|
-
class << self
|
9
|
-
|
10
|
-
def batch_groups
|
11
|
-
@batch_groups ||= []
|
12
|
-
end
|
13
|
-
|
14
|
-
def process(*tasks, **options)
|
15
|
-
batch_groups << Group.new(
|
16
|
-
tasks.flatten.map do |task|
|
17
|
-
next task if task <= Task
|
18
|
-
|
19
|
-
raise ArgumentError, "must be a Batch or Task"
|
20
|
-
end,
|
21
|
-
options
|
22
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def call
|
28
|
-
self.class.batch_groups.each do |group|
|
29
|
-
next unless __cmdx_eval(group.options)
|
30
|
-
|
31
|
-
batch_halt = group.options[:batch_halt] || task_setting(:batch_halt)
|
32
|
-
|
33
|
-
group.tasks.each do |task|
|
34
|
-
task_result = task.call(context)
|
35
|
-
next unless Array(batch_halt).include?(task_result.status)
|
36
|
-
|
37
|
-
throw!(task_result)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
data/lib/cmdx/parameters.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CMDx
|
4
|
-
class Parameters < Array
|
5
|
-
|
6
|
-
def invalid?
|
7
|
-
!valid?
|
8
|
-
end
|
9
|
-
|
10
|
-
def valid?
|
11
|
-
all?(&:valid?)
|
12
|
-
end
|
13
|
-
|
14
|
-
def validate!(task)
|
15
|
-
each { |p| recursive_validate!(task, p) }
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_h
|
19
|
-
ParametersSerializer.call(self)
|
20
|
-
end
|
21
|
-
alias to_a to_h
|
22
|
-
|
23
|
-
def to_s
|
24
|
-
ParametersInspector.call(self)
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def recursive_validate!(task, parameter)
|
30
|
-
task.send(parameter.method_name)
|
31
|
-
parameter.children.each { |cp| recursive_validate!(task, cp) }
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
data/lib/cmdx/run.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CMDx
|
4
|
-
class Run
|
5
|
-
|
6
|
-
__cmdx_attr_delegator :index, to: :results
|
7
|
-
__cmdx_attr_delegator :state, :status, :outcome, :runtime, to: :first_result
|
8
|
-
|
9
|
-
attr_reader :id, :results
|
10
|
-
|
11
|
-
def initialize(attributes = {})
|
12
|
-
@id = attributes[:id] || SecureRandom.uuid
|
13
|
-
@results = Array(attributes[:results])
|
14
|
-
end
|
15
|
-
|
16
|
-
def freeze
|
17
|
-
first_result
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_h
|
22
|
-
RunSerializer.call(self)
|
23
|
-
end
|
24
|
-
alias to_a to_h
|
25
|
-
|
26
|
-
def to_s
|
27
|
-
RunInspector.call(self)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def first_result
|
33
|
-
return @first_result if defined?(@first_result)
|
34
|
-
|
35
|
-
@first_result = @results.first
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
data/lib/cmdx/run_inspector.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CMDx
|
4
|
-
module RunInspector
|
5
|
-
|
6
|
-
FOOTER_KEYS = %i[
|
7
|
-
state status outcome runtime
|
8
|
-
].freeze
|
9
|
-
|
10
|
-
module_function
|
11
|
-
|
12
|
-
def call(run)
|
13
|
-
header = "\nrun: #{run.id}"
|
14
|
-
footer = FOOTER_KEYS.map { |key| "#{key}: #{run.send(key)}" }.join(" | ")
|
15
|
-
spacer = "=" * [header.size, footer.size].max
|
16
|
-
|
17
|
-
run
|
18
|
-
.results
|
19
|
-
.map { |r| r.to_h.except(:run_id).pretty_inspect }
|
20
|
-
.unshift(header, "#{spacer}\n")
|
21
|
-
.push(spacer, "#{footer}\n\n")
|
22
|
-
.join("\n")
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
data/lib/cmdx/run_serializer.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CMDx
|
4
|
-
module RunSerializer
|
5
|
-
|
6
|
-
module_function
|
7
|
-
|
8
|
-
def call(run)
|
9
|
-
{
|
10
|
-
id: run.id,
|
11
|
-
state: run.state,
|
12
|
-
status: run.status,
|
13
|
-
outcome: run.outcome,
|
14
|
-
runtime: run.runtime,
|
15
|
-
results: run.results.map(&:to_h)
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
data/lib/cmdx/task_hook.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CMDx
|
4
|
-
module TaskHook
|
5
|
-
|
6
|
-
module_function
|
7
|
-
|
8
|
-
def call(task, hook)
|
9
|
-
Array(task.class.cmd_hooks[hook]).each do |callables, options|
|
10
|
-
next unless task.__cmdx_eval(options)
|
11
|
-
|
12
|
-
hooks = Array(callables)
|
13
|
-
hooks.each { |h| task.__cmdx_try(h) }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Cmdx
|
4
|
-
class BatchGenerator < Rails::Generators::NamedBase
|
5
|
-
|
6
|
-
source_root File.expand_path("templates", __dir__)
|
7
|
-
check_class_collision prefix: "Batch"
|
8
|
-
|
9
|
-
desc "Generates a batch task with the given NAME (if one does not exist)."
|
10
|
-
|
11
|
-
def copy_files
|
12
|
-
name = file_name.sub(/^batch_?/i, "")
|
13
|
-
path = File.join("app/cmds", class_path, "batch_#{name}.rb")
|
14
|
-
template("batch.rb.tt", path)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def class_name
|
20
|
-
@class_name ||= super.delete_prefix("Batch")
|
21
|
-
end
|
22
|
-
|
23
|
-
def parent_class_name
|
24
|
-
ApplicationBatch
|
25
|
-
rescue StandardError
|
26
|
-
CMDx::Batch
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
File without changes
|