cmdx 1.6.1 → 1.7.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/.cursor/rules/cursor-instructions.mdc +2 -2
- data/CHANGELOG.md +16 -1
- data/LLM.md +168 -2
- data/docs/attributes/coercions.md +2 -0
- data/docs/attributes/validations.md +2 -0
- data/docs/callbacks.md +2 -0
- data/docs/getting_started.md +8 -0
- data/docs/internationalization.md +106 -2
- data/docs/middlewares.md +2 -0
- data/docs/workflows.md +48 -0
- data/lib/cmdx/pipeline.rb +43 -11
- data/lib/cmdx/railtie.rb +2 -2
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx.rb +2 -0
- data/lib/generators/cmdx/locale_generator.rb +39 -0
- data/lib/generators/cmdx/templates/install.rb +7 -0
- data/lib/generators/cmdx/templates/workflow.rb.tt +8 -0
- data/lib/generators/cmdx/workflow_generator.rb +57 -0
- data/lib/locales/af.yml +49 -0
- data/lib/locales/ar.yml +49 -0
- data/lib/locales/az.yml +49 -0
- data/lib/locales/be.yml +49 -0
- data/lib/locales/bg.yml +49 -0
- data/lib/locales/bn.yml +49 -0
- data/lib/locales/bs.yml +49 -0
- data/lib/locales/ca.yml +49 -0
- data/lib/locales/cnr.yml +49 -0
- data/lib/locales/cs.yml +49 -0
- data/lib/locales/cy.yml +49 -0
- data/lib/locales/da.yml +49 -0
- data/lib/locales/de.yml +49 -0
- data/lib/locales/dz.yml +49 -0
- data/lib/locales/el.yml +49 -0
- data/lib/locales/eo.yml +49 -0
- data/lib/locales/es.yml +49 -0
- data/lib/locales/et.yml +49 -0
- data/lib/locales/eu.yml +49 -0
- data/lib/locales/fa.yml +49 -0
- data/lib/locales/fi.yml +49 -0
- data/lib/locales/fr.yml +49 -0
- data/lib/locales/fy.yml +49 -0
- data/lib/locales/gd.yml +49 -0
- data/lib/locales/gl.yml +49 -0
- data/lib/locales/he.yml +49 -0
- data/lib/locales/hi.yml +49 -0
- data/lib/locales/hr.yml +49 -0
- data/lib/locales/hu.yml +49 -0
- data/lib/locales/hy.yml +49 -0
- data/lib/locales/id.yml +49 -0
- data/lib/locales/is.yml +49 -0
- data/lib/locales/it.yml +49 -0
- data/lib/locales/ja.yml +49 -0
- data/lib/locales/ka.yml +49 -0
- data/lib/locales/kk.yml +49 -0
- data/lib/locales/km.yml +49 -0
- data/lib/locales/kn.yml +49 -0
- data/lib/locales/ko.yml +49 -0
- data/lib/locales/lb.yml +49 -0
- data/lib/locales/lo.yml +49 -0
- data/lib/locales/lt.yml +49 -0
- data/lib/locales/lv.yml +49 -0
- data/lib/locales/mg.yml +49 -0
- data/lib/locales/mk.yml +49 -0
- data/lib/locales/ml.yml +49 -0
- data/lib/locales/mn.yml +49 -0
- data/lib/locales/mr-IN.yml +49 -0
- data/lib/locales/ms.yml +49 -0
- data/lib/locales/nb.yml +49 -0
- data/lib/locales/ne.yml +49 -0
- data/lib/locales/nl.yml +49 -0
- data/lib/locales/nn.yml +49 -0
- data/lib/locales/oc.yml +49 -0
- data/lib/locales/or.yml +49 -0
- data/lib/locales/pa.yml +49 -0
- data/lib/locales/pl.yml +49 -0
- data/lib/locales/pt.yml +49 -0
- data/lib/locales/rm.yml +49 -0
- data/lib/locales/ro.yml +49 -0
- data/lib/locales/ru.yml +49 -0
- data/lib/locales/sc.yml +49 -0
- data/lib/locales/sk.yml +49 -0
- data/lib/locales/sl.yml +49 -0
- data/lib/locales/sq.yml +49 -0
- data/lib/locales/sr.yml +49 -0
- data/lib/locales/st.yml +49 -0
- data/lib/locales/sv.yml +49 -0
- data/lib/locales/sw.yml +49 -0
- data/lib/locales/ta.yml +49 -0
- data/lib/locales/te.yml +49 -0
- data/lib/locales/th.yml +49 -0
- data/lib/locales/tl.yml +49 -0
- data/lib/locales/tr.yml +49 -0
- data/lib/locales/tt.yml +49 -0
- data/lib/locales/ug.yml +49 -0
- data/lib/locales/uk.yml +49 -0
- data/lib/locales/ur.yml +49 -0
- data/lib/locales/uz.yml +49 -0
- data/lib/locales/vi.yml +49 -0
- data/lib/locales/wo.yml +49 -0
- data/lib/locales/zh-CN.yml +49 -0
- data/lib/locales/zh-HK.yml +49 -0
- data/lib/locales/zh-TW.yml +49 -0
- data/lib/locales/zh-YUE.yml +49 -0
- metadata +117 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8483d78b67a6dfffa6721b39e623ac08d57d443b499287891bfb9c6e06422c89
|
4
|
+
data.tar.gz: 02cb722299d6a97fb4e2d07a84880c7374a8c17b691f42bee995bd4f3ea698ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6600b6d617c11a3ec3b66367a7fa309e191bd2d1f20a3fb1a538565a0c2b45e05f8093f2c3e07edbb155e308e6c90c486f069db171aac68e8658bbe85bd4b34
|
7
|
+
data.tar.gz: 6ad4a1348066d3aa4d0ed2733fc88f94af293835cc970be5986f3c002cf3b3615f474bff774a2b48f7e043920ca01b5f278cd26850b5b4827a70d2a4b0e6ab50
|
@@ -10,8 +10,8 @@ Follow the official Ruby gem guides for best practices.
|
|
10
10
|
Reference the guides outlined in https://guides.rubygems.org
|
11
11
|
|
12
12
|
## Project Context
|
13
|
-
CMDx provides a framework for designing and executing complex
|
14
|
-
|
13
|
+
CMDx provides a framework for designing and executing complex business logic within service/command objects.
|
14
|
+
Reference the CMDx documentation in https://github.com/drexed/cmdx/blob/main/LLM.md
|
15
15
|
|
16
16
|
## Technology Stack
|
17
17
|
- Ruby 3.4+
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
|
7
7
|
## [TODO]
|
8
8
|
|
9
|
+
## [1.7.0] - 2025-08-25
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- Workflow generator
|
13
|
+
|
14
|
+
### Changes
|
15
|
+
- Port over `cmdx-parallel` changes
|
16
|
+
- Port over `cmdx-i18n` changes
|
17
|
+
|
18
|
+
## [1.6.2] - 2025-08-24
|
19
|
+
|
20
|
+
### Changes
|
21
|
+
- Prefix railtie I18n with `::` to play nice with `CMDx::I18n`
|
22
|
+
- Use `cmdx-rspec` for matchers support
|
23
|
+
|
9
24
|
## [1.6.1] - 2025-08-23
|
10
25
|
|
11
26
|
### Changes
|
@@ -27,7 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
27
42
|
## [1.5.1] - 2025-08-21
|
28
43
|
|
29
44
|
### Changes
|
30
|
-
- Prefix I18n with `::` to play nice with `CMDx::I18n`
|
45
|
+
- Prefix locale I18n with `::` to play nice with `CMDx::I18n`
|
31
46
|
- Safe navigate length and numeric validators
|
32
47
|
- Update railtie file path points to correct directory
|
33
48
|
|
data/LLM.md
CHANGED
@@ -72,6 +72,8 @@ end
|
|
72
72
|
|
73
73
|
### Middlewares
|
74
74
|
|
75
|
+
See the [Middelwares](#https://github.com/drexed/cmdx/blob/main/docs/middlewares.md#declarations) docs for task level configurations.
|
76
|
+
|
75
77
|
```ruby
|
76
78
|
CMDx.configure do |config|
|
77
79
|
# Via callable (must respond to `call(task, options)`)
|
@@ -99,6 +101,8 @@ end
|
|
99
101
|
|
100
102
|
### Callbacks
|
101
103
|
|
104
|
+
See the [Callbacks](#https://github.com/drexed/cmdx/blob/main/docs/callbacks.md#declarations) docs for task level configurations.
|
105
|
+
|
102
106
|
```ruby
|
103
107
|
CMDx.configure do |config|
|
104
108
|
# Via method
|
@@ -123,6 +127,8 @@ end
|
|
123
127
|
|
124
128
|
### Coercions
|
125
129
|
|
130
|
+
See the [Attributes - Coercions](#https://github.com/drexed/cmdx/blob/main/docs/attributes/coercions.md#declarations) docs for task level configurations.
|
131
|
+
|
126
132
|
```ruby
|
127
133
|
CMDx.configure do |config|
|
128
134
|
# Via callable (must respond to `call(value, options)`)
|
@@ -147,6 +153,8 @@ end
|
|
147
153
|
|
148
154
|
### Validators
|
149
155
|
|
156
|
+
See the [Attributes - Validations](#https://github.com/drexed/cmdx/blob/main/docs/attributes/validations.md#declarations) docs for task level configurations.
|
157
|
+
|
150
158
|
```ruby
|
151
159
|
CMDx.configure do |config|
|
152
160
|
# Via callable (must respond to `call(value, options)`)
|
@@ -907,6 +915,7 @@ fail!("Unsupported")
|
|
907
915
|
# Bad: Default, cannot determine reason
|
908
916
|
skip! #=> "no reason given"
|
909
917
|
fail! #=> "no reason given"
|
918
|
+
```
|
910
919
|
|
911
920
|
---
|
912
921
|
|
@@ -1727,6 +1736,7 @@ result.metadata #=> {
|
|
1727
1736
|
# port: ["is required"]
|
1728
1737
|
# }
|
1729
1738
|
# }
|
1739
|
+
```
|
1730
1740
|
|
1731
1741
|
---
|
1732
1742
|
|
@@ -1810,6 +1820,8 @@ url: https://github.com/drexed/cmdx/blob/main/docs/attributes/coercions.md
|
|
1810
1820
|
|
1811
1821
|
Attribute coercions automatically convert task arguments to expected types, ensuring type safety while providing flexible input handling. Coercions transform raw input values into the specified types, supporting simple conversions like string-to-integer and complex operations like JSON parsing.
|
1812
1822
|
|
1823
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#coercions) docs for global configuration.
|
1824
|
+
|
1813
1825
|
## Usage
|
1814
1826
|
|
1815
1827
|
Define attribute types to enable automatic coercion:
|
@@ -1952,6 +1964,7 @@ result.metadata #=> {
|
|
1952
1964
|
# score: ["could not coerce into one of: float, big_decimal"]
|
1953
1965
|
# }
|
1954
1966
|
# }
|
1967
|
+
```
|
1955
1968
|
|
1956
1969
|
---
|
1957
1970
|
|
@@ -1962,6 +1975,8 @@ url: https://github.com/drexed/cmdx/blob/main/docs/attributes/validations.md
|
|
1962
1975
|
|
1963
1976
|
Attribute validations ensure task arguments meet specified requirements before execution begins. Validations run after coercions and provide declarative rules for data integrity, supporting both built-in validators and custom validation logic.
|
1964
1977
|
|
1978
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#validations) docs for global configuration.
|
1979
|
+
|
1965
1980
|
## Usage
|
1966
1981
|
|
1967
1982
|
Define validation rules on attributes to enforce data requirements:
|
@@ -2338,6 +2353,8 @@ url: https://github.com/drexed/cmdx/blob/main/docs/callbacks.md
|
|
2338
2353
|
|
2339
2354
|
Callbacks provide precise control over task execution lifecycle, running custom logic at specific transition points. Callback callables have access to the same context and result information as the `execute` method, enabling rich integration patterns.
|
2340
2355
|
|
2356
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#callbacks) docs for global configuration.
|
2357
|
+
|
2341
2358
|
> [!IMPORTANT]
|
2342
2359
|
> Callbacks execute in the order they are declared within each hook type. Multiple callbacks of the same type execute in declaration order (FIFO: first in, first out).
|
2343
2360
|
|
@@ -2497,6 +2514,8 @@ url: https://github.com/drexed/cmdx/blob/main/docs/middlewares.md
|
|
2497
2514
|
|
2498
2515
|
Middleware provides Rack-style wrappers around task execution for cross-cutting concerns like authentication, logging, caching, and error handling.
|
2499
2516
|
|
2517
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#middlewares) docs for global configuration.
|
2518
|
+
|
2500
2519
|
## Order
|
2501
2520
|
|
2502
2521
|
Middleware executes in a nested fashion, creating an onion-like execution pattern:
|
@@ -2811,8 +2830,109 @@ I18n.with_locale(:fr) do
|
|
2811
2830
|
end
|
2812
2831
|
```
|
2813
2832
|
|
2814
|
-
|
2815
|
-
|
2833
|
+
## Configuration
|
2834
|
+
|
2835
|
+
Localization is handled by the `I18n` gem. In Rails applications, locales are loaded automatically and managed via the `I18n.available_locales` setting.
|
2836
|
+
|
2837
|
+
### Local Copies
|
2838
|
+
|
2839
|
+
Execute the following command to copy any locale into the Rails applications `config/locales` directory:
|
2840
|
+
|
2841
|
+
```bash
|
2842
|
+
rails generate cmdx:locale [LOCALE]
|
2843
|
+
|
2844
|
+
# Eg: generate french locale
|
2845
|
+
rails generate cmdx:locale fr
|
2846
|
+
```
|
2847
|
+
|
2848
|
+
### Available Locales
|
2849
|
+
|
2850
|
+
- af - Afrikaans
|
2851
|
+
- ar - Arabic
|
2852
|
+
- az - Azerbaijani
|
2853
|
+
- be - Belarusian
|
2854
|
+
- bg - Bulgarian
|
2855
|
+
- bn - Bengali
|
2856
|
+
- bs - Bosnian
|
2857
|
+
- ca - Catalan
|
2858
|
+
- cnr - Montenegrin
|
2859
|
+
- cs - Czech
|
2860
|
+
- cy - Welsh
|
2861
|
+
- da - Danish
|
2862
|
+
- de - German
|
2863
|
+
- dz - Dzongkha
|
2864
|
+
- el - Greek
|
2865
|
+
- en - English
|
2866
|
+
- eo - Esperanto
|
2867
|
+
- es - Spanish
|
2868
|
+
- et - Estonian
|
2869
|
+
- eu - Basque
|
2870
|
+
- fa - Persian
|
2871
|
+
- fi - Finnish
|
2872
|
+
- fr - French
|
2873
|
+
- fy - Western Frisian
|
2874
|
+
- gd - Scottish Gaelic
|
2875
|
+
- gl - Galician
|
2876
|
+
- he - Hebrew
|
2877
|
+
- hi - Hindi
|
2878
|
+
- hr - Croatian
|
2879
|
+
- hu - Hungarian
|
2880
|
+
- hy - Armenian
|
2881
|
+
- id - Indonesian
|
2882
|
+
- is - Icelandic
|
2883
|
+
- it - Italian
|
2884
|
+
- ja - Japanese
|
2885
|
+
- ka - Georgian
|
2886
|
+
- kk - Kazakh
|
2887
|
+
- km - Khmer
|
2888
|
+
- kn - Kannada
|
2889
|
+
- ko - Korean
|
2890
|
+
- lb - Luxembourgish
|
2891
|
+
- lo - Lao
|
2892
|
+
- lt - Lithuanian
|
2893
|
+
- lv - Latvian
|
2894
|
+
- mg - Malagasy
|
2895
|
+
- mk - Macedonian
|
2896
|
+
- ml - Malayalam
|
2897
|
+
- mn - Mongolian
|
2898
|
+
- mr-IN - Marathi (India)
|
2899
|
+
- ms - Malay
|
2900
|
+
- nb - Norwegian Bokmål
|
2901
|
+
- ne - Nepali
|
2902
|
+
- nl - Dutch
|
2903
|
+
- nn - Norwegian Nynorsk
|
2904
|
+
- oc - Occitan
|
2905
|
+
- or - Odia
|
2906
|
+
- pa - Punjabi
|
2907
|
+
- pl - Polish
|
2908
|
+
- pt - Portuguese
|
2909
|
+
- rm - Romansh
|
2910
|
+
- ro - Romanian
|
2911
|
+
- ru - Russian
|
2912
|
+
- sc - Sardinian
|
2913
|
+
- sk - Slovak
|
2914
|
+
- sl - Slovenian
|
2915
|
+
- sq - Albanian
|
2916
|
+
- sr - Serbian
|
2917
|
+
- st - Southern Sotho
|
2918
|
+
- sv - Swedish
|
2919
|
+
- sw - Swahili
|
2920
|
+
- ta - Tamil
|
2921
|
+
- te - Telugu
|
2922
|
+
- th - Thai
|
2923
|
+
- tl - Tagalog
|
2924
|
+
- tr - Turkish
|
2925
|
+
- tt - Tatar
|
2926
|
+
- ug - Uyghur
|
2927
|
+
- uk - Ukrainian
|
2928
|
+
- ur - Urdu
|
2929
|
+
- uz - Uzbek
|
2930
|
+
- vi - Vietnamese
|
2931
|
+
- wo - Wolof
|
2932
|
+
- zh-CN - Chinese (Simplified)
|
2933
|
+
- zh-HK - Chinese (Hong Kong)
|
2934
|
+
- zh-TW - Chinese (Traditional)
|
2935
|
+
- zh-YUE - Chinese (Yue)
|
2816
2936
|
|
2817
2937
|
---
|
2818
2938
|
|
@@ -3147,6 +3267,52 @@ class CompleteEmailWorkflow < CMDx::Task
|
|
3147
3267
|
end
|
3148
3268
|
```
|
3149
3269
|
|
3270
|
+
## Parallel Execution
|
3271
|
+
|
3272
|
+
Parallel task execution leverages the [Parallel](https://github.com/grosser/parallel) gem, which automatically detects the number of available processors to maximize concurrent task execution.
|
3273
|
+
|
3274
|
+
> [!IMPORTANT]
|
3275
|
+
> Context cannot be modified during parallel execution. Ensure that all required data is preloaded into the context before parallelization begins.
|
3276
|
+
|
3277
|
+
```ruby
|
3278
|
+
class SendWelcomeNotifications < CMDx::Task
|
3279
|
+
include CMDx::Workflow
|
3280
|
+
|
3281
|
+
# Default options (dynamically calculated to available processors)
|
3282
|
+
tasks SendWelcomeEmail, SendWelcomeSms, SendWelcomePush, strategy: :parallel
|
3283
|
+
|
3284
|
+
# Fix number of threads
|
3285
|
+
tasks SendWelcomeEmail, SendWelcomeSms, SendWelcomePush, strategy: :parallel, in_threads: 2
|
3286
|
+
|
3287
|
+
# Fix number of forked processes
|
3288
|
+
tasks SendWelcomeEmail, SendWelcomeSms, SendWelcomePush, strategy: :parallel, in_processes: 2
|
3289
|
+
|
3290
|
+
# NOTE: Reactors are not supported
|
3291
|
+
end
|
3292
|
+
```
|
3293
|
+
|
3294
|
+
## Task Generator
|
3295
|
+
|
3296
|
+
Generate new CMDx workflow tasks quickly using the built-in generator:
|
3297
|
+
|
3298
|
+
```bash
|
3299
|
+
rails generate cmdx:workflow SendNotifications
|
3300
|
+
```
|
3301
|
+
|
3302
|
+
This creates a new workflow task file with the basic structure:
|
3303
|
+
|
3304
|
+
```ruby
|
3305
|
+
# app/tasks/send_notifications.rb
|
3306
|
+
class SendNotifications < CMDx::Task
|
3307
|
+
include CMDx::Workflow
|
3308
|
+
|
3309
|
+
tasks Task1, Task2
|
3310
|
+
end
|
3311
|
+
```
|
3312
|
+
|
3313
|
+
> [!TIP]
|
3314
|
+
> Use **present tense verbs + pluralized noun** for workflow task names, eg: `SendNotifications`, `DownloadFiles`, `ValidateDocuments`
|
3315
|
+
|
3150
3316
|
---
|
3151
3317
|
|
3152
3318
|
url: https://github.com/drexed/cmdx/blob/main/docs/tips_and_tricks.md
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Attribute coercions automatically convert task arguments to expected types, ensuring type safety while providing flexible input handling. Coercions transform raw input values into the specified types, supporting simple conversions like string-to-integer and complex operations like JSON parsing.
|
4
4
|
|
5
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#coercions) docs for global configuration.
|
6
|
+
|
5
7
|
## Table of Contents
|
6
8
|
|
7
9
|
- [Usage](#usage)
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Attribute validations ensure task arguments meet specified requirements before execution begins. Validations run after coercions and provide declarative rules for data integrity, supporting both built-in validators and custom validation logic.
|
4
4
|
|
5
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#validations) docs for global configuration.
|
6
|
+
|
5
7
|
## Table of Contents
|
6
8
|
|
7
9
|
- [Usage](#usage)
|
data/docs/callbacks.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Callbacks provide precise control over task execution lifecycle, running custom logic at specific transition points. Callback callables have access to the same context and result information as the `execute` method, enabling rich integration patterns.
|
4
4
|
|
5
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#callbacks) docs for global configuration.
|
6
|
+
|
5
7
|
> [!IMPORTANT]
|
6
8
|
> Callbacks execute in the order they are declared within each hook type. Multiple callbacks of the same type execute in declaration order (FIFO: first in, first out).
|
7
9
|
|
data/docs/getting_started.md
CHANGED
@@ -82,6 +82,8 @@ end
|
|
82
82
|
|
83
83
|
### Middlewares
|
84
84
|
|
85
|
+
See the [Middelwares](#https://github.com/drexed/cmdx/blob/main/docs/middlewares.md#declarations) docs for task level configurations.
|
86
|
+
|
85
87
|
```ruby
|
86
88
|
CMDx.configure do |config|
|
87
89
|
# Via callable (must respond to `call(task, options)`)
|
@@ -109,6 +111,8 @@ end
|
|
109
111
|
|
110
112
|
### Callbacks
|
111
113
|
|
114
|
+
See the [Callbacks](#https://github.com/drexed/cmdx/blob/main/docs/callbacks.md#declarations) docs for task level configurations.
|
115
|
+
|
112
116
|
```ruby
|
113
117
|
CMDx.configure do |config|
|
114
118
|
# Via method
|
@@ -133,6 +137,8 @@ end
|
|
133
137
|
|
134
138
|
### Coercions
|
135
139
|
|
140
|
+
See the [Attributes - Coercions](#https://github.com/drexed/cmdx/blob/main/docs/attributes/coercions.md#declarations) docs for task level configurations.
|
141
|
+
|
136
142
|
```ruby
|
137
143
|
CMDx.configure do |config|
|
138
144
|
# Via callable (must respond to `call(value, options)`)
|
@@ -157,6 +163,8 @@ end
|
|
157
163
|
|
158
164
|
### Validators
|
159
165
|
|
166
|
+
See the [Attributes - Validations](#https://github.com/drexed/cmdx/blob/main/docs/attributes/validations.md#declarations) docs for task level configurations.
|
167
|
+
|
160
168
|
```ruby
|
161
169
|
CMDx.configure do |config|
|
162
170
|
# Via callable (must respond to `call(value, options)`)
|
@@ -5,6 +5,9 @@ CMDx provides comprehensive internationalization support for all error messages,
|
|
5
5
|
## Table of Contents
|
6
6
|
|
7
7
|
- [Localization](#localization)
|
8
|
+
- [Configuration](#configuration)
|
9
|
+
- [Local Copies](#local-copies)
|
10
|
+
- [Available Locales](#available-locales)
|
8
11
|
|
9
12
|
## Localization
|
10
13
|
|
@@ -25,8 +28,109 @@ I18n.with_locale(:fr) do
|
|
25
28
|
end
|
26
29
|
```
|
27
30
|
|
28
|
-
|
29
|
-
|
31
|
+
## Configuration
|
32
|
+
|
33
|
+
Localization is handled by the `I18n` gem. In Rails applications, locales are loaded automatically and managed via the `I18n.available_locales` setting.
|
34
|
+
|
35
|
+
### Local Copies
|
36
|
+
|
37
|
+
Execute the following command to copy any locale into the Rails applications `config/locales` directory:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
rails generate cmdx:locale [LOCALE]
|
41
|
+
|
42
|
+
# Eg: generate french locale
|
43
|
+
rails generate cmdx:locale fr
|
44
|
+
```
|
45
|
+
|
46
|
+
### Available Locales
|
47
|
+
|
48
|
+
- af - Afrikaans
|
49
|
+
- ar - Arabic
|
50
|
+
- az - Azerbaijani
|
51
|
+
- be - Belarusian
|
52
|
+
- bg - Bulgarian
|
53
|
+
- bn - Bengali
|
54
|
+
- bs - Bosnian
|
55
|
+
- ca - Catalan
|
56
|
+
- cnr - Montenegrin
|
57
|
+
- cs - Czech
|
58
|
+
- cy - Welsh
|
59
|
+
- da - Danish
|
60
|
+
- de - German
|
61
|
+
- dz - Dzongkha
|
62
|
+
- el - Greek
|
63
|
+
- en - English
|
64
|
+
- eo - Esperanto
|
65
|
+
- es - Spanish
|
66
|
+
- et - Estonian
|
67
|
+
- eu - Basque
|
68
|
+
- fa - Persian
|
69
|
+
- fi - Finnish
|
70
|
+
- fr - French
|
71
|
+
- fy - Western Frisian
|
72
|
+
- gd - Scottish Gaelic
|
73
|
+
- gl - Galician
|
74
|
+
- he - Hebrew
|
75
|
+
- hi - Hindi
|
76
|
+
- hr - Croatian
|
77
|
+
- hu - Hungarian
|
78
|
+
- hy - Armenian
|
79
|
+
- id - Indonesian
|
80
|
+
- is - Icelandic
|
81
|
+
- it - Italian
|
82
|
+
- ja - Japanese
|
83
|
+
- ka - Georgian
|
84
|
+
- kk - Kazakh
|
85
|
+
- km - Khmer
|
86
|
+
- kn - Kannada
|
87
|
+
- ko - Korean
|
88
|
+
- lb - Luxembourgish
|
89
|
+
- lo - Lao
|
90
|
+
- lt - Lithuanian
|
91
|
+
- lv - Latvian
|
92
|
+
- mg - Malagasy
|
93
|
+
- mk - Macedonian
|
94
|
+
- ml - Malayalam
|
95
|
+
- mn - Mongolian
|
96
|
+
- mr-IN - Marathi (India)
|
97
|
+
- ms - Malay
|
98
|
+
- nb - Norwegian Bokmål
|
99
|
+
- ne - Nepali
|
100
|
+
- nl - Dutch
|
101
|
+
- nn - Norwegian Nynorsk
|
102
|
+
- oc - Occitan
|
103
|
+
- or - Odia
|
104
|
+
- pa - Punjabi
|
105
|
+
- pl - Polish
|
106
|
+
- pt - Portuguese
|
107
|
+
- rm - Romansh
|
108
|
+
- ro - Romanian
|
109
|
+
- ru - Russian
|
110
|
+
- sc - Sardinian
|
111
|
+
- sk - Slovak
|
112
|
+
- sl - Slovenian
|
113
|
+
- sq - Albanian
|
114
|
+
- sr - Serbian
|
115
|
+
- st - Southern Sotho
|
116
|
+
- sv - Swedish
|
117
|
+
- sw - Swahili
|
118
|
+
- ta - Tamil
|
119
|
+
- te - Telugu
|
120
|
+
- th - Thai
|
121
|
+
- tl - Tagalog
|
122
|
+
- tr - Turkish
|
123
|
+
- tt - Tatar
|
124
|
+
- ug - Uyghur
|
125
|
+
- uk - Ukrainian
|
126
|
+
- ur - Urdu
|
127
|
+
- uz - Uzbek
|
128
|
+
- vi - Vietnamese
|
129
|
+
- wo - Wolof
|
130
|
+
- zh-CN - Chinese (Simplified)
|
131
|
+
- zh-HK - Chinese (Hong Kong)
|
132
|
+
- zh-TW - Chinese (Traditional)
|
133
|
+
- zh-YUE - Chinese (Yue)
|
30
134
|
|
31
135
|
---
|
32
136
|
|
data/docs/middlewares.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Middleware provides Rack-style wrappers around task execution for cross-cutting concerns like authentication, logging, caching, and error handling.
|
4
4
|
|
5
|
+
Check out the [Getting Started](https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#middlewares) docs for global configuration.
|
6
|
+
|
5
7
|
## Table of Contents
|
6
8
|
|
7
9
|
- [Order](#order)
|
data/docs/workflows.md
CHANGED
@@ -12,6 +12,8 @@ Workflow orchestrates sequential execution of multiple tasks in a linear pipelin
|
|
12
12
|
- [Task Configuration](#task-configuration)
|
13
13
|
- [Group Configuration](#group-configuration)
|
14
14
|
- [Nested Workflows](#nested-workflows)
|
15
|
+
- [Parallel Execution](#parallel-execution)
|
16
|
+
- [Task Generator](#task-generator)
|
15
17
|
|
16
18
|
## Declarations
|
17
19
|
|
@@ -187,6 +189,52 @@ class CompleteEmailWorkflow < CMDx::Task
|
|
187
189
|
end
|
188
190
|
```
|
189
191
|
|
192
|
+
## Parallel Execution
|
193
|
+
|
194
|
+
Parallel task execution leverages the [Parallel](https://github.com/grosser/parallel) gem, which automatically detects the number of available processors to maximize concurrent task execution.
|
195
|
+
|
196
|
+
> [!IMPORTANT]
|
197
|
+
> Context cannot be modified during parallel execution. Ensure that all required data is preloaded into the context before parallelization begins.
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
class SendWelcomeNotifications < CMDx::Task
|
201
|
+
include CMDx::Workflow
|
202
|
+
|
203
|
+
# Default options (dynamically calculated to available processors)
|
204
|
+
tasks SendWelcomeEmail, SendWelcomeSms, SendWelcomePush, strategy: :parallel
|
205
|
+
|
206
|
+
# Fix number of threads
|
207
|
+
tasks SendWelcomeEmail, SendWelcomeSms, SendWelcomePush, strategy: :parallel, in_threads: 2
|
208
|
+
|
209
|
+
# Fix number of forked processes
|
210
|
+
tasks SendWelcomeEmail, SendWelcomeSms, SendWelcomePush, strategy: :parallel, in_processes: 2
|
211
|
+
|
212
|
+
# NOTE: Reactors are not supported
|
213
|
+
end
|
214
|
+
```
|
215
|
+
|
216
|
+
## Task Generator
|
217
|
+
|
218
|
+
Generate new CMDx workflow tasks quickly using the built-in generator:
|
219
|
+
|
220
|
+
```bash
|
221
|
+
rails generate cmdx:workflow SendNotifications
|
222
|
+
```
|
223
|
+
|
224
|
+
This creates a new workflow task file with the basic structure:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
# app/tasks/send_notifications.rb
|
228
|
+
class SendNotifications < CMDx::Task
|
229
|
+
include CMDx::Workflow
|
230
|
+
|
231
|
+
tasks Task1, Task2
|
232
|
+
end
|
233
|
+
```
|
234
|
+
|
235
|
+
> [!TIP]
|
236
|
+
> Use **present tense verbs + pluralized noun** for workflow task names, eg: `SendNotifications`, `DownloadFiles`, `ValidateDocuments`
|
237
|
+
|
190
238
|
---
|
191
239
|
|
192
240
|
- **Prev:** [Deprecation](deprecation.md)
|
data/lib/cmdx/pipeline.rb
CHANGED
@@ -55,23 +55,22 @@ module CMDx
|
|
55
55
|
|
56
56
|
private
|
57
57
|
|
58
|
-
# Executes
|
59
|
-
# Override this method to implement custom execution strategies like parallel
|
60
|
-
# processing or conditional task execution.
|
58
|
+
# Executes a group of tasks using the specified execution strategy.
|
61
59
|
#
|
62
|
-
# @param group [
|
63
|
-
# @param breakpoints [Array<
|
60
|
+
# @param group [CMDx::Group] The task group to execute
|
61
|
+
# @param breakpoints [Array<Symbol>] Status values that trigger execution breaks
|
62
|
+
# @option group.options [Symbol, String] :strategy Execution strategy (:sequential, :parallel, or nil for default)
|
64
63
|
#
|
65
64
|
# @return [void]
|
66
65
|
#
|
67
66
|
# @example
|
68
|
-
#
|
69
|
-
# # Custom parallel execution strategy
|
70
|
-
# group.tasks.map { |task| Thread.new { task.execute(workflow.context) } }
|
71
|
-
# end
|
67
|
+
# execute_group_tasks(group, ["failed", "skipped"])
|
72
68
|
def execute_group_tasks(group, breakpoints)
|
73
|
-
|
74
|
-
execute_tasks_in_sequence(group, breakpoints)
|
69
|
+
case strategy = group.options[:strategy]
|
70
|
+
when NilClass, /sequential/ then execute_tasks_in_sequence(group, breakpoints)
|
71
|
+
when /parallel/ then execute_tasks_in_parallel(group, breakpoints)
|
72
|
+
else raise "unknown execution strategy #{strategy.inspect}"
|
73
|
+
end
|
75
74
|
end
|
76
75
|
|
77
76
|
# Executes tasks sequentially within a group, checking breakpoints after each task.
|
@@ -95,5 +94,38 @@ module CMDx
|
|
95
94
|
end
|
96
95
|
end
|
97
96
|
|
97
|
+
# Executes tasks in parallel using the parallel gem.
|
98
|
+
#
|
99
|
+
# @param group [CMDx::Group] The task group to execute in parallel
|
100
|
+
# @param breakpoints [Array<Symbol>] Status values that trigger execution breaks
|
101
|
+
# @option group.options [Integer] :in_threads Number of threads to use
|
102
|
+
# @option group.options [Integer] :in_processes Number of processes to use
|
103
|
+
#
|
104
|
+
# @return [void]
|
105
|
+
#
|
106
|
+
# @raise [HaltError] When a task result status matches a breakpoint
|
107
|
+
#
|
108
|
+
# @example
|
109
|
+
# execute_tasks_in_parallel(group, ["failed"])
|
110
|
+
def execute_tasks_in_parallel(group, breakpoints)
|
111
|
+
raise "install the `parallel` gem to use this feature" unless defined?(::Parallel)
|
112
|
+
|
113
|
+
parallel_options = group.options.slice(:in_threads, :in_processes)
|
114
|
+
throwable_result = nil
|
115
|
+
|
116
|
+
::Parallel.each(group.tasks, **parallel_options) do |task|
|
117
|
+
Chain.current = workflow.chain
|
118
|
+
|
119
|
+
task_result = task.execute(workflow.context)
|
120
|
+
next unless breakpoints.include?(task_result.status)
|
121
|
+
|
122
|
+
raise ::Parallel::Break, throwable_result = task_result
|
123
|
+
end
|
124
|
+
|
125
|
+
return if throwable_result.nil?
|
126
|
+
|
127
|
+
workflow.throw!(throwable_result)
|
128
|
+
end
|
129
|
+
|
98
130
|
end
|
99
131
|
end
|
data/lib/cmdx/railtie.rb
CHANGED
data/lib/cmdx/version.rb
CHANGED
data/lib/cmdx.rb
CHANGED
@@ -48,7 +48,9 @@ require_relative "cmdx/faults"
|
|
48
48
|
# Conditionally load Rails components if Rails is available
|
49
49
|
if defined?(Rails::Generators)
|
50
50
|
require_relative "generators/cmdx/install_generator"
|
51
|
+
require_relative "generators/cmdx/locale_generator"
|
51
52
|
require_relative "generators/cmdx/task_generator"
|
53
|
+
require_relative "generators/cmdx/workflow_generator"
|
52
54
|
end
|
53
55
|
|
54
56
|
# Load the Railtie last after everything else is required so we don't
|