cmdx 1.5.2 → 1.6.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/CHANGELOG.md +8 -1
- data/LLM.md +4 -2
- data/docs/internationalization.md +4 -2
- data/lib/cmdx/{worker.rb → executor.rb} +10 -10
- data/lib/cmdx/pipeline.rb +99 -0
- data/lib/cmdx/task.rb +1 -1
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx/workflow.rb +10 -28
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef05af7473358890c311d872369f870fbaa7ff7bf2fd6d6d14cddd9c9dc80aec
|
4
|
+
data.tar.gz: 8e1c20c5991d453f947ed5aea44099c9c05861ad11637b27eb02bb5baea4e4f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c59da9cc99292e6241bf9d7fabb91cc00887a6b8a4cd18950c22a495a1adfdc32a769194818944726da0e732e8fb23c842c7086d67ea451f2556a31c4f3a5ef2
|
7
|
+
data.tar.gz: 89d64b25f51d583605960e19d9b08b366dc4269b5c2ca07cddf562714aaf2cc4c0d9f1a06bbae42ed0ba9ed536715030c4d79dbf8c486305bd4891c331a5107d
|
data/CHANGELOG.md
CHANGED
@@ -6,10 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
|
7
7
|
## [TODO]
|
8
8
|
|
9
|
+
## [1.6.0] - 2025-08-22
|
10
|
+
|
11
|
+
### Changes
|
12
|
+
- Rename `Worker` class to `Executor`
|
13
|
+
- Move workflow `work` logic into `Pipeline`
|
14
|
+
- Add workflow task `:breakpoints`
|
15
|
+
|
9
16
|
## [1.5.2] - 2025-08-22
|
10
17
|
|
11
18
|
### Changes
|
12
|
-
- Rename
|
19
|
+
- Rename workflow `execution_groups` attribute to `pipeline`
|
13
20
|
|
14
21
|
## [1.5.1] - 2025-08-21
|
15
22
|
|
data/LLM.md
CHANGED
@@ -2794,8 +2794,7 @@ CMDx provides comprehensive internationalization support for all error messages,
|
|
2794
2794
|
|
2795
2795
|
## Localization
|
2796
2796
|
|
2797
|
-
|
2798
|
-
> CMDx automatically localizes all error messages based on the `I18n.locale` setting.
|
2797
|
+
CMDx automatically localizes all error messages based on the `I18n.locale` setting.
|
2799
2798
|
|
2800
2799
|
```ruby
|
2801
2800
|
class ProcessQuote < CMDx::Task
|
@@ -2812,6 +2811,9 @@ I18n.with_locale(:fr) do
|
|
2812
2811
|
end
|
2813
2812
|
```
|
2814
2813
|
|
2814
|
+
> [!TIP]
|
2815
|
+
> CMDx supports 85+ locales via the [cmdx-i18n](https://github.com/drexed/cmdx-i18n) gem.
|
2816
|
+
|
2815
2817
|
---
|
2816
2818
|
|
2817
2819
|
url: https://github.com/drexed/cmdx/blob/main/docs/deprecation.md
|
@@ -8,8 +8,7 @@ CMDx provides comprehensive internationalization support for all error messages,
|
|
8
8
|
|
9
9
|
## Localization
|
10
10
|
|
11
|
-
|
12
|
-
> CMDx automatically localizes all error messages based on the `I18n.locale` setting.
|
11
|
+
CMDx automatically localizes all error messages based on the `I18n.locale` setting.
|
13
12
|
|
14
13
|
```ruby
|
15
14
|
class ProcessQuote < CMDx::Task
|
@@ -26,6 +25,9 @@ I18n.with_locale(:fr) do
|
|
26
25
|
end
|
27
26
|
```
|
28
27
|
|
28
|
+
> [!TIP]
|
29
|
+
> CMDx supports 85+ locales via the [cmdx-i18n](https://github.com/drexed/cmdx-i18n) gem.
|
30
|
+
|
29
31
|
---
|
30
32
|
|
31
33
|
- **Prev:** [Logging](logging.md)
|
@@ -3,19 +3,19 @@
|
|
3
3
|
module CMDx
|
4
4
|
# Executes CMDx tasks with middleware support, error handling, and lifecycle management.
|
5
5
|
#
|
6
|
-
# The
|
6
|
+
# The Executor class is responsible for orchestrating task execution, including
|
7
7
|
# pre-execution validation, execution with middleware, post-execution callbacks,
|
8
8
|
# and proper error handling for different types of failures.
|
9
|
-
class
|
9
|
+
class Executor
|
10
10
|
|
11
11
|
attr_reader :task
|
12
12
|
|
13
13
|
# @param task [CMDx::Task] The task to execute
|
14
14
|
#
|
15
|
-
# @return [CMDx::
|
15
|
+
# @return [CMDx::Executor] A new executor instance
|
16
16
|
#
|
17
17
|
# @example
|
18
|
-
#
|
18
|
+
# executor = CMDx::Executor.new(my_task)
|
19
19
|
def initialize(task)
|
20
20
|
@task = task
|
21
21
|
end
|
@@ -30,8 +30,8 @@ module CMDx
|
|
30
30
|
# @raise [StandardError] When raise is true and execution fails
|
31
31
|
#
|
32
32
|
# @example
|
33
|
-
# CMDx::
|
34
|
-
# CMDx::
|
33
|
+
# CMDx::Executor.execute(my_task)
|
34
|
+
# CMDx::Executor.execute(my_task, raise: true)
|
35
35
|
def self.execute(task, raise: false)
|
36
36
|
instance = new(task)
|
37
37
|
raise ? instance.execute! : instance.execute
|
@@ -42,8 +42,8 @@ module CMDx
|
|
42
42
|
# @return [CMDx::Result] The execution result
|
43
43
|
#
|
44
44
|
# @example
|
45
|
-
#
|
46
|
-
# result =
|
45
|
+
# executor = CMDx::Executor.new(my_task)
|
46
|
+
# result = executor.execute
|
47
47
|
def execute
|
48
48
|
task.class.settings[:middlewares].call!(task) do
|
49
49
|
pre_execution!
|
@@ -69,8 +69,8 @@ module CMDx
|
|
69
69
|
# @raise [StandardError] When execution fails
|
70
70
|
#
|
71
71
|
# @example
|
72
|
-
#
|
73
|
-
# result =
|
72
|
+
# executor = CMDx::Executor.new(my_task)
|
73
|
+
# result = executor.execute!
|
74
74
|
def execute!
|
75
75
|
task.class.settings[:middlewares].call!(task) do
|
76
76
|
pre_execution!
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CMDx
|
4
|
+
# Executes workflows by processing task groups with conditional logic and breakpoint handling.
|
5
|
+
# The Pipeline class manages the execution flow of workflow tasks, evaluating conditions
|
6
|
+
# and handling breakpoints that can interrupt execution at specific task statuses.
|
7
|
+
class Pipeline
|
8
|
+
|
9
|
+
# @return [Workflow] The workflow instance being executed
|
10
|
+
attr_reader :workflow
|
11
|
+
|
12
|
+
# @param workflow [Workflow] The workflow to execute
|
13
|
+
#
|
14
|
+
# @return [Pipeline] A new pipeline instance
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# pipeline = Pipeline.new(my_workflow)
|
18
|
+
def initialize(workflow)
|
19
|
+
@workflow = workflow
|
20
|
+
end
|
21
|
+
|
22
|
+
# Executes a workflow using a new pipeline instance.
|
23
|
+
#
|
24
|
+
# @param workflow [Workflow] The workflow to execute
|
25
|
+
#
|
26
|
+
# @return [void]
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# Pipeline.execute(my_workflow)
|
30
|
+
def self.execute(workflow)
|
31
|
+
new(workflow).execute
|
32
|
+
end
|
33
|
+
|
34
|
+
# Executes the workflow by processing all task groups in sequence.
|
35
|
+
# Each group is evaluated against its conditions, and breakpoints are checked
|
36
|
+
# after each task execution to determine if workflow should continue or halt.
|
37
|
+
#
|
38
|
+
# @return [void]
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# pipeline = Pipeline.new(my_workflow)
|
42
|
+
# pipeline.execute
|
43
|
+
def execute
|
44
|
+
workflow.class.pipeline.each do |group|
|
45
|
+
next unless Utils::Condition.evaluate(workflow, group.options, workflow)
|
46
|
+
|
47
|
+
breakpoints = group.options[:breakpoints] ||
|
48
|
+
workflow.class.settings[:breakpoints] ||
|
49
|
+
workflow.class.settings[:workflow_breakpoints]
|
50
|
+
breakpoints = Array(breakpoints).map(&:to_s).uniq
|
51
|
+
|
52
|
+
execute_group_tasks(group, breakpoints)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
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.
|
61
|
+
#
|
62
|
+
# @param group [ExecutionGroup] The group of tasks to execute
|
63
|
+
# @param breakpoints [Array<String>] Breakpoint statuses that trigger workflow interruption
|
64
|
+
#
|
65
|
+
# @return [void]
|
66
|
+
#
|
67
|
+
# @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
|
72
|
+
def execute_group_tasks(group, breakpoints)
|
73
|
+
# NOTE: Override this method to introduce alternative execution strategies
|
74
|
+
execute_tasks_sequentially(group, breakpoints)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Executes tasks sequentially within a group, checking breakpoints after each task.
|
78
|
+
# If a task result status matches a breakpoint, the workflow is interrupted.
|
79
|
+
#
|
80
|
+
# @param group [ExecutionGroup] The group of tasks to execute
|
81
|
+
# @param breakpoints [Array<String>] Breakpoint statuses that trigger workflow interruption
|
82
|
+
#
|
83
|
+
# @return [void]
|
84
|
+
#
|
85
|
+
# @raise [HaltError] When a task result status matches a breakpoint
|
86
|
+
#
|
87
|
+
# @example
|
88
|
+
# execute_tasks_sequentially(group, ["failed", "skipped"])
|
89
|
+
def execute_tasks_sequentially(group, breakpoints)
|
90
|
+
group.tasks.each do |task|
|
91
|
+
task_result = task.execute(workflow.context)
|
92
|
+
next unless breakpoints.include?(task_result.status)
|
93
|
+
|
94
|
+
workflow.throw!(task_result)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
data/lib/cmdx/task.rb
CHANGED
@@ -200,7 +200,7 @@ module CMDx
|
|
200
200
|
# result = task.execute
|
201
201
|
# result = task.execute(raise: true)
|
202
202
|
def execute(raise: false)
|
203
|
-
|
203
|
+
Executor.execute(self, raise:)
|
204
204
|
end
|
205
205
|
|
206
206
|
# @raise [UndefinedMethodError] Always raised as this method must be overridden
|
data/lib/cmdx/version.rb
CHANGED
data/lib/cmdx/workflow.rb
CHANGED
@@ -87,39 +87,21 @@ module CMDx
|
|
87
87
|
base.extend(ClassMethods)
|
88
88
|
end
|
89
89
|
|
90
|
-
# Executes the workflow by processing
|
91
|
-
#
|
90
|
+
# Executes the workflow by processing all tasks in the pipeline.
|
91
|
+
# This method delegates execution to the Pipeline class which handles
|
92
|
+
# the processing of tasks with proper error handling and context management.
|
92
93
|
#
|
93
|
-
# @return [void]
|
94
|
-
#
|
95
|
-
# @raise [CMDx::Fault] If a breakpoint is encountered during execution
|
96
|
-
#
|
97
|
-
# @example
|
98
|
-
# workflow = MyWorkflow.new
|
99
|
-
# workflow.work # Executes all tasks in the workflow
|
100
94
|
# @example
|
101
|
-
# class
|
95
|
+
# class MyWorkflow
|
102
96
|
# include CMDx::Workflow
|
103
|
-
# task
|
104
|
-
# task
|
105
|
-
# task NotifyCompletionTask
|
97
|
+
# task ValidateTask
|
98
|
+
# task ProcessTask
|
106
99
|
# end
|
107
|
-
#
|
108
|
-
# workflow
|
100
|
+
#
|
101
|
+
# workflow = MyWorkflow.new
|
102
|
+
# result = workflow.work
|
109
103
|
def work
|
110
|
-
self
|
111
|
-
next unless Utils::Condition.evaluate(self, group.options, self)
|
112
|
-
|
113
|
-
breakpoints = group.options[:breakpoints] || self.class.settings[:workflow_breakpoints]
|
114
|
-
breakpoints = Array(breakpoints).map(&:to_s).uniq
|
115
|
-
|
116
|
-
group.tasks.each do |task|
|
117
|
-
task_result = task.execute(context)
|
118
|
-
next unless breakpoints.include?(task_result.status)
|
119
|
-
|
120
|
-
throw!(task_result)
|
121
|
-
end
|
122
|
-
end
|
104
|
+
Pipeline.execute(self)
|
123
105
|
end
|
124
106
|
|
125
107
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmdx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Gomez
|
@@ -235,6 +235,7 @@ files:
|
|
235
235
|
- lib/cmdx/deprecator.rb
|
236
236
|
- lib/cmdx/errors.rb
|
237
237
|
- lib/cmdx/exceptions.rb
|
238
|
+
- lib/cmdx/executor.rb
|
238
239
|
- lib/cmdx/faults.rb
|
239
240
|
- lib/cmdx/freezer.rb
|
240
241
|
- lib/cmdx/identifier.rb
|
@@ -248,6 +249,7 @@ files:
|
|
248
249
|
- lib/cmdx/middlewares/correlate.rb
|
249
250
|
- lib/cmdx/middlewares/runtime.rb
|
250
251
|
- lib/cmdx/middlewares/timeout.rb
|
252
|
+
- lib/cmdx/pipeline.rb
|
251
253
|
- lib/cmdx/railtie.rb
|
252
254
|
- lib/cmdx/result.rb
|
253
255
|
- lib/cmdx/task.rb
|
@@ -262,7 +264,6 @@ files:
|
|
262
264
|
- lib/cmdx/validators/numeric.rb
|
263
265
|
- lib/cmdx/validators/presence.rb
|
264
266
|
- lib/cmdx/version.rb
|
265
|
-
- lib/cmdx/worker.rb
|
266
267
|
- lib/cmdx/workflow.rb
|
267
268
|
- lib/generators/cmdx/install_generator.rb
|
268
269
|
- lib/generators/cmdx/task_generator.rb
|