cmdx 1.6.2 → 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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/LLM.md +149 -2
  4. data/docs/internationalization.md +106 -2
  5. data/docs/workflows.md +48 -0
  6. data/lib/cmdx/pipeline.rb +43 -11
  7. data/lib/cmdx/version.rb +1 -1
  8. data/lib/cmdx.rb +2 -0
  9. data/lib/generators/cmdx/locale_generator.rb +39 -0
  10. data/lib/generators/cmdx/templates/workflow.rb.tt +8 -0
  11. data/lib/generators/cmdx/workflow_generator.rb +57 -0
  12. data/lib/locales/af.yml +49 -0
  13. data/lib/locales/ar.yml +49 -0
  14. data/lib/locales/az.yml +49 -0
  15. data/lib/locales/be.yml +49 -0
  16. data/lib/locales/bg.yml +49 -0
  17. data/lib/locales/bn.yml +49 -0
  18. data/lib/locales/bs.yml +49 -0
  19. data/lib/locales/ca.yml +49 -0
  20. data/lib/locales/cnr.yml +49 -0
  21. data/lib/locales/cs.yml +49 -0
  22. data/lib/locales/cy.yml +49 -0
  23. data/lib/locales/da.yml +49 -0
  24. data/lib/locales/de.yml +49 -0
  25. data/lib/locales/dz.yml +49 -0
  26. data/lib/locales/el.yml +49 -0
  27. data/lib/locales/eo.yml +49 -0
  28. data/lib/locales/es.yml +49 -0
  29. data/lib/locales/et.yml +49 -0
  30. data/lib/locales/eu.yml +49 -0
  31. data/lib/locales/fa.yml +49 -0
  32. data/lib/locales/fi.yml +49 -0
  33. data/lib/locales/fr.yml +49 -0
  34. data/lib/locales/fy.yml +49 -0
  35. data/lib/locales/gd.yml +49 -0
  36. data/lib/locales/gl.yml +49 -0
  37. data/lib/locales/he.yml +49 -0
  38. data/lib/locales/hi.yml +49 -0
  39. data/lib/locales/hr.yml +49 -0
  40. data/lib/locales/hu.yml +49 -0
  41. data/lib/locales/hy.yml +49 -0
  42. data/lib/locales/id.yml +49 -0
  43. data/lib/locales/is.yml +49 -0
  44. data/lib/locales/it.yml +49 -0
  45. data/lib/locales/ja.yml +49 -0
  46. data/lib/locales/ka.yml +49 -0
  47. data/lib/locales/kk.yml +49 -0
  48. data/lib/locales/km.yml +49 -0
  49. data/lib/locales/kn.yml +49 -0
  50. data/lib/locales/ko.yml +49 -0
  51. data/lib/locales/lb.yml +49 -0
  52. data/lib/locales/lo.yml +49 -0
  53. data/lib/locales/lt.yml +49 -0
  54. data/lib/locales/lv.yml +49 -0
  55. data/lib/locales/mg.yml +49 -0
  56. data/lib/locales/mk.yml +49 -0
  57. data/lib/locales/ml.yml +49 -0
  58. data/lib/locales/mn.yml +49 -0
  59. data/lib/locales/mr-IN.yml +49 -0
  60. data/lib/locales/ms.yml +49 -0
  61. data/lib/locales/nb.yml +49 -0
  62. data/lib/locales/ne.yml +49 -0
  63. data/lib/locales/nl.yml +49 -0
  64. data/lib/locales/nn.yml +49 -0
  65. data/lib/locales/oc.yml +49 -0
  66. data/lib/locales/or.yml +49 -0
  67. data/lib/locales/pa.yml +49 -0
  68. data/lib/locales/pl.yml +49 -0
  69. data/lib/locales/pt.yml +49 -0
  70. data/lib/locales/rm.yml +49 -0
  71. data/lib/locales/ro.yml +49 -0
  72. data/lib/locales/ru.yml +49 -0
  73. data/lib/locales/sc.yml +49 -0
  74. data/lib/locales/sk.yml +49 -0
  75. data/lib/locales/sl.yml +49 -0
  76. data/lib/locales/sq.yml +49 -0
  77. data/lib/locales/sr.yml +49 -0
  78. data/lib/locales/st.yml +49 -0
  79. data/lib/locales/sv.yml +49 -0
  80. data/lib/locales/sw.yml +49 -0
  81. data/lib/locales/ta.yml +49 -0
  82. data/lib/locales/te.yml +49 -0
  83. data/lib/locales/th.yml +49 -0
  84. data/lib/locales/tl.yml +49 -0
  85. data/lib/locales/tr.yml +49 -0
  86. data/lib/locales/tt.yml +49 -0
  87. data/lib/locales/ug.yml +49 -0
  88. data/lib/locales/uk.yml +49 -0
  89. data/lib/locales/ur.yml +49 -0
  90. data/lib/locales/uz.yml +49 -0
  91. data/lib/locales/vi.yml +49 -0
  92. data/lib/locales/wo.yml +49 -0
  93. data/lib/locales/zh-CN.yml +49 -0
  94. data/lib/locales/zh-HK.yml +49 -0
  95. data/lib/locales/zh-TW.yml +49 -0
  96. data/lib/locales/zh-YUE.yml +49 -0
  97. metadata +103 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8b62e944f3c8fdb0f69dba9e33e3aad9f62d90b6a7487b18e9c0104392c4a8d
4
- data.tar.gz: a032133acd6f0e6d5999d8336a179df495fd4460fbf632385a8dbcd4ee31fd66
3
+ metadata.gz: 8483d78b67a6dfffa6721b39e623ac08d57d443b499287891bfb9c6e06422c89
4
+ data.tar.gz: 02cb722299d6a97fb4e2d07a84880c7374a8c17b691f42bee995bd4f3ea698ab
5
5
  SHA512:
6
- metadata.gz: 05a82e75e96e364df809f158a791a015ce22cff03b10f1ae255ba2e116d602fadd741d0a82638c5feabcbbdf96e3e61e9a9ae54be8c3220253d542f0d8a303d5
7
- data.tar.gz: 881fe8149e8a029fbb79a1164faced4406f4f28d1e206659e09ee460129d9246a9a074aef76a61cbd94a38ed4f1a39612753a6842460e3a3827b3bd1c5301cc1
6
+ metadata.gz: b6600b6d617c11a3ec3b66367a7fa309e191bd2d1f20a3fb1a538565a0c2b45e05f8093f2c3e07edbb155e308e6c90c486f069db171aac68e8658bbe85bd4b34
7
+ data.tar.gz: 6ad4a1348066d3aa4d0ed2733fc88f94af293835cc970be5986f3c002cf3b3615f474bff774a2b48f7e043920ca01b5f278cd26850b5b4827a70d2a4b0e6ab50
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ 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
+
9
18
  ## [1.6.2] - 2025-08-24
10
19
 
11
20
  ### Changes
data/LLM.md CHANGED
@@ -2830,8 +2830,109 @@ I18n.with_locale(:fr) do
2830
2830
  end
2831
2831
  ```
2832
2832
 
2833
- > [!TIP]
2834
- > CMDx supports 85+ locales via the [cmdx-i18n](https://github.com/drexed/cmdx-i18n) gem.
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)
2835
2936
 
2836
2937
  ---
2837
2938
 
@@ -3166,6 +3267,52 @@ class CompleteEmailWorkflow < CMDx::Task
3166
3267
  end
3167
3268
  ```
3168
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
+
3169
3316
  ---
3170
3317
 
3171
3318
  url: https://github.com/drexed/cmdx/blob/main/docs/tips_and_tricks.md
@@ -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
- > [!TIP]
29
- > CMDx supports 85+ locales via the [cmdx-i18n](https://github.com/drexed/cmdx-i18n) gem.
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/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 tasks within a group using the configured execution strategy.
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 [ExecutionGroup] The group of tasks to execute
63
- # @param breakpoints [Array<String>] Breakpoint statuses that trigger workflow interruption
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
- # def execute_group_tasks(group, breakpoints)
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
- # NOTE: Override this method to introduce alternative execution strategies
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/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CMDx
4
4
 
5
- VERSION = "1.6.2"
5
+ VERSION = "1.7.0"
6
6
 
7
7
  end
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
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmdx
4
+ # Generates CMDx locale files for Rails applications
5
+ #
6
+ # Rails generator that copies CMDx locale files into the application's
7
+ # config/locales directory. This allows applications to customize and extend
8
+ # the default CMDx locale files.
9
+ class LocaleGenerator < Rails::Generators::Base
10
+
11
+ source_root File.expand_path("../../locales", __dir__)
12
+
13
+ desc "Copies the locale with the given alpha-2 code"
14
+
15
+ argument :locale, type: :string, default: "en", banner: "locale: en, es, fr, etc"
16
+
17
+ # Copies the locale template to the Rails application
18
+ #
19
+ # Copies the specified locale file from the gem's locales directory to the
20
+ # application's config/locales directory. If the locale file doesn't exist
21
+ # in the gem, the generator will fail gracefully.
22
+ #
23
+ # @return [void]
24
+ #
25
+ # @example
26
+ # # Copy default (English) locale file
27
+ # rails generate cmdx:locale
28
+ # # => Creates config/locales/en.yml
29
+ #
30
+ # # Copy Spanish locale file
31
+ # rails generate cmdx:locale es
32
+ # # => Creates config/locales/es.yml
33
+ #
34
+ def copy_locale_files
35
+ copy_file("#{locale}.yml", "config/locales/#{locale}.yml")
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %> < <%= parent_class_name %>
3
+ include CMDx::Workflow
4
+
5
+ tasks Task1, Task2
6
+ # Docs: https://github.com/drexed/cmdx/docs/workflows.md
7
+ end
8
+ <% end -%>
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmdx
4
+ # Generates CMDx workflow files for Rails applications
5
+ #
6
+ # This generator creates task classes that inherit from either ApplicationTask
7
+ # (if defined) or CMDx::Task. It generates the task file in the standard
8
+ # Rails tasks directory structure.
9
+ class WorkflowGenerator < Rails::Generators::NamedBase
10
+
11
+ source_root File.expand_path("templates", __dir__)
12
+
13
+ desc "Creates a workflow with the given NAME"
14
+
15
+ # Copies the task template to the Rails application
16
+ #
17
+ # Creates a new task file at `app/tasks/[class_path]/[file_name].rb` using
18
+ # the task template. The file is placed in the standard Rails tasks directory
19
+ # structure, maintaining proper namespacing if the task is nested.
20
+ #
21
+ # @return [void]
22
+ #
23
+ # @example Basic usage
24
+ # rails generate cmdx:workflow SendNotifications
25
+ # # => Creates app/tasks/send_notifications.rb
26
+ #
27
+ # @example Nested task
28
+ # rails generate cmdx:workflow Admin::SendNotifications
29
+ # # => Creates app/tasks/admin/send_notifications.rb
30
+ def copy_files
31
+ path = File.join("app/tasks", class_path, "#{file_name}.rb")
32
+ template("workflow.rb.tt", path)
33
+ end
34
+
35
+ private
36
+
37
+ # Determines the appropriate parent class name for the generated task
38
+ #
39
+ # Attempts to use ApplicationTask if it exists in the application, otherwise
40
+ # falls back to CMDx::Task. This allows applications to define their own
41
+ # base task class while maintaining compatibility.
42
+ #
43
+ # @return [Class] The parent class for the generated task
44
+ #
45
+ # @example
46
+ # parent_class_name # => ApplicationTask
47
+ #
48
+ # @example Fallback behavior
49
+ # parent_class_name # => CMDx::Task
50
+ def parent_class_name
51
+ ApplicationTask
52
+ rescue NameError
53
+ CMDx::Task
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,49 @@
1
+ af:
2
+ cmdx:
3
+ attributes:
4
+ required: "moet toeganklik wees via die bron"
5
+ undefined: "delegeer na ongedefinieerde metode %{method}"
6
+ coercions:
7
+ into_a: "kon nie na %{type} omskep word nie"
8
+ into_an: "kon nie na %{type} omskep word nie"
9
+ into_any: "kon nie na een van: %{types} omskep word nie"
10
+ unknown: "onbekende %{type} omskep tipe"
11
+ faults:
12
+ unspecified: "geen rede gegee nie"
13
+ types:
14
+ array: "skikking"
15
+ big_decimal: "groot desimale"
16
+ boolean: "booleaanse"
17
+ complex: "kompleks"
18
+ date_time: "datum en tyd"
19
+ date: "datum"
20
+ float: "drywende punt"
21
+ hash: "hash"
22
+ integer: "heelgetal"
23
+ rational: "rasionaal"
24
+ string: "string"
25
+ symbol: "simbool"
26
+ time: "tyd"
27
+ validators:
28
+ exclusion:
29
+ of: "moet nie een van wees nie: %{values}"
30
+ within: "moet nie binne %{min} en %{max} wees nie"
31
+ format: "is 'n ongeldige formaat"
32
+ inclusion:
33
+ of: "moet een van wees: %{values}"
34
+ within: "moet binne %{min} en %{max} wees"
35
+ length:
36
+ is: "lengte moet %{is} wees"
37
+ is_not: "lengte moet nie %{is_not} wees nie"
38
+ min: "lengte moet ten minste %{min} wees"
39
+ max: "lengte kan maksimum %{max} wees"
40
+ not_within: "lengte moet nie binne %{min} en %{max} wees nie"
41
+ within: "lengte moet binne %{min} en %{max} wees"
42
+ numeric:
43
+ is: "moet %{is} wees"
44
+ is_not: "moet nie %{is_not} wees nie"
45
+ min: "moet ten minste %{min} wees"
46
+ max: "kan maksimum %{max} wees"
47
+ not_within: "moet nie binne %{min} en %{max} wees nie"
48
+ within: "moet binne %{min} en %{max} wees"
49
+ presence: "kan nie leeg wees nie"
@@ -0,0 +1,49 @@
1
+ ar:
2
+ cmdx:
3
+ attributes:
4
+ required: "يجب أن يكون قابلاً للوصول عبر المصدر"
5
+ undefined: "يفوض إلى طريقة غير معرفة %{method}"
6
+ coercions:
7
+ into_a: "لا يمكن تحويله إلى %{type}"
8
+ into_an: "لا يمكن تحويله إلى %{type}"
9
+ into_any: "لا يمكن تحويله إلى واحد من: %{types}"
10
+ unknown: "نوع تحويل %{type} غير معروف"
11
+ faults:
12
+ unspecified: "لم يتم تقديم سبب"
13
+ types:
14
+ array: "مصفوفة"
15
+ big_decimal: "عدد عشري كبير"
16
+ boolean: "منطقي"
17
+ complex: "مركب"
18
+ date_time: "التاريخ والوقت"
19
+ date: "التاريخ"
20
+ float: "رقم عشري"
21
+ hash: "جدول تجزئة"
22
+ integer: "عدد صحيح"
23
+ rational: "عدد نسبي"
24
+ string: "سلسلة نصية"
25
+ symbol: "رمز"
26
+ time: "الوقت"
27
+ validators:
28
+ exclusion:
29
+ of: "يجب ألا يكون واحداً من: %{values}"
30
+ within: "يجب ألا يكون بين %{min} و %{max}"
31
+ format: "تنسيق غير صالح"
32
+ inclusion:
33
+ of: "يجب أن يكون واحداً من: %{values}"
34
+ within: "يجب أن يكون بين %{min} و %{max}"
35
+ length:
36
+ is: "يجب أن يكون الطول %{is}"
37
+ is_not: "يجب ألا يكون الطول %{is_not}"
38
+ min: "يجب أن يكون الطول على الأقل %{min}"
39
+ max: "يجب أن يكون الطول على الأكثر %{max}"
40
+ not_within: "يجب ألا يكون الطول بين %{min} و %{max}"
41
+ within: "يجب أن يكون الطول بين %{min} و %{max}"
42
+ numeric:
43
+ is: "يجب أن يكون %{is}"
44
+ is_not: "يجب ألا يكون %{is_not}"
45
+ min: "يجب أن يكون على الأقل %{min}"
46
+ max: "يجب أن يكون على الأكثر %{max}"
47
+ not_within: "يجب ألا يكون بين %{min} و %{max}"
48
+ within: "يجب أن يكون بين %{min} و %{max}"
49
+ presence: "لا يمكن أن يكون فارغاً"