cmdx 1.8.0 → 1.9.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/.DS_Store +0 -0
- data/.cursor/prompts/docs.md +3 -3
- data/.cursor/prompts/llms.md +1 -3
- data/.irbrc +14 -2
- data/CHANGELOG.md +58 -45
- data/LLM.md +150 -53
- data/README.md +23 -85
- data/docs/.DS_Store +0 -0
- data/docs/assets/favicon.ico +0 -0
- data/docs/assets/favicon.svg +1 -0
- data/docs/attributes/coercions.md +12 -24
- data/docs/attributes/defaults.md +3 -16
- data/docs/attributes/definitions.md +16 -30
- data/docs/attributes/naming.md +3 -13
- data/docs/attributes/transformations.md +63 -0
- data/docs/attributes/validations.md +14 -33
- data/docs/basics/chain.md +14 -23
- data/docs/basics/context.md +13 -22
- data/docs/basics/execution.md +8 -26
- data/docs/basics/setup.md +8 -19
- data/docs/callbacks.md +19 -32
- data/docs/deprecation.md +8 -25
- data/docs/getting_started.md +101 -77
- data/docs/index.md +120 -0
- data/docs/internationalization.md +6 -18
- data/docs/interruptions/exceptions.md +10 -16
- data/docs/interruptions/faults.md +8 -25
- data/docs/interruptions/halt.md +12 -27
- data/docs/logging.md +7 -17
- data/docs/middlewares.md +13 -29
- data/docs/outcomes/result.md +21 -38
- data/docs/outcomes/states.md +8 -22
- data/docs/outcomes/statuses.md +10 -21
- data/docs/stylesheets/extra.css +42 -0
- data/docs/tips_and_tricks.md +7 -46
- data/docs/workflows.md +23 -38
- data/examples/active_record_query_tagging.md +46 -0
- data/examples/paper_trail_whatdunnit.md +39 -0
- data/lib/cmdx/attribute.rb +6 -5
- data/lib/cmdx/attribute_value.rb +31 -10
- data/lib/cmdx/callback_registry.rb +12 -2
- data/lib/cmdx/coercions/hash.rb +2 -0
- data/lib/cmdx/configuration.rb +10 -2
- data/lib/cmdx/deprecator.rb +3 -3
- data/lib/cmdx/executor.rb +93 -7
- data/lib/cmdx/pipeline.rb +4 -4
- data/lib/cmdx/railtie.rb +9 -0
- data/lib/cmdx/result.rb +10 -1
- data/lib/cmdx/task.rb +12 -7
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx.rb +1 -0
- data/lib/generators/cmdx/templates/install.rb +9 -0
- data/mkdocs.yml +122 -0
- data/src/cmdx-dark-logo.png +0 -0
- data/src/cmdx-favicon.svg +1 -0
- data/src/cmdx-light-logo.png +0 -0
- data/src/cmdx-logo.svg +1 -0
- metadata +14 -3
- data/lib/cmdx/freezer.rb +0 -51
- data/src/cmdx-logo.png +0 -0
data/lib/cmdx/executor.rb
CHANGED
|
@@ -46,14 +46,16 @@ module CMDx
|
|
|
46
46
|
# result = executor.execute
|
|
47
47
|
def execute
|
|
48
48
|
task.class.settings[:middlewares].call!(task) do
|
|
49
|
-
pre_execution!
|
|
49
|
+
pre_execution! unless @pre_execution
|
|
50
50
|
execution!
|
|
51
51
|
rescue UndefinedMethodError => e
|
|
52
52
|
raise(e) # No need to clear the Chain since exception is not being re-raised
|
|
53
53
|
rescue Fault => e
|
|
54
54
|
task.result.throw!(e.result, halt: false, cause: e)
|
|
55
55
|
rescue StandardError => e
|
|
56
|
+
retry if retry_execution?(e)
|
|
56
57
|
task.result.fail!("[#{e.class}] #{e.message}", halt: false, cause: e)
|
|
58
|
+
task.class.settings[:exception_handler]&.call(task, e)
|
|
57
59
|
ensure
|
|
58
60
|
task.result.executed!
|
|
59
61
|
post_execution!
|
|
@@ -73,7 +75,7 @@ module CMDx
|
|
|
73
75
|
# result = executor.execute!
|
|
74
76
|
def execute!
|
|
75
77
|
task.class.settings[:middlewares].call!(task) do
|
|
76
|
-
pre_execution!
|
|
78
|
+
pre_execution! unless @pre_execution
|
|
77
79
|
execution!
|
|
78
80
|
rescue UndefinedMethodError => e
|
|
79
81
|
raise_exception(e)
|
|
@@ -81,6 +83,7 @@ module CMDx
|
|
|
81
83
|
task.result.throw!(e.result, halt: false, cause: e)
|
|
82
84
|
halt_execution?(e) ? raise_exception(e) : post_execution!
|
|
83
85
|
rescue StandardError => e
|
|
86
|
+
retry if retry_execution?(e)
|
|
84
87
|
task.result.fail!("[#{e.class}] #{e.message}", halt: false, cause: e)
|
|
85
88
|
raise_exception(e)
|
|
86
89
|
else
|
|
@@ -108,6 +111,38 @@ module CMDx
|
|
|
108
111
|
breakpoints.include?(exception.result.status)
|
|
109
112
|
end
|
|
110
113
|
|
|
114
|
+
# Determines if execution should be retried based on retry configuration.
|
|
115
|
+
#
|
|
116
|
+
# @param exception [Exception] The exception that occurred
|
|
117
|
+
#
|
|
118
|
+
# @return [Boolean] Whether execution should be retried
|
|
119
|
+
#
|
|
120
|
+
# @example
|
|
121
|
+
# retry_execution?(standard_error)
|
|
122
|
+
def retry_execution?(exception)
|
|
123
|
+
available_retries = (task.class.settings[:retries] || 0).to_i
|
|
124
|
+
return false unless available_retries.positive?
|
|
125
|
+
|
|
126
|
+
current_retries = (task.result.metadata[:retries] ||= 0).to_i
|
|
127
|
+
remaining_retries = available_retries - current_retries
|
|
128
|
+
return false unless remaining_retries.positive?
|
|
129
|
+
|
|
130
|
+
exceptions = Array(task.class.settings[:retry_on] || StandardError)
|
|
131
|
+
return false unless exceptions.any? { |e| exception.class <= e }
|
|
132
|
+
|
|
133
|
+
task.result.metadata[:retries] += 1
|
|
134
|
+
|
|
135
|
+
task.logger.warn do
|
|
136
|
+
reason = "[#{exception.class}] #{exception.message}"
|
|
137
|
+
task.to_h.merge!(reason:, remaining_retries:)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
jitter = task.class.settings[:retry_jitter].to_f * current_retries
|
|
141
|
+
sleep(jitter) if jitter.positive?
|
|
142
|
+
|
|
143
|
+
true
|
|
144
|
+
end
|
|
145
|
+
|
|
111
146
|
# Raises an exception and clears the chain.
|
|
112
147
|
#
|
|
113
148
|
# @param exception [Exception] The exception to raise
|
|
@@ -118,6 +153,7 @@ module CMDx
|
|
|
118
153
|
# raise_exception(standard_error)
|
|
119
154
|
def raise_exception(exception)
|
|
120
155
|
Chain.clear
|
|
156
|
+
|
|
121
157
|
raise(exception)
|
|
122
158
|
end
|
|
123
159
|
|
|
@@ -135,8 +171,15 @@ module CMDx
|
|
|
135
171
|
|
|
136
172
|
private
|
|
137
173
|
|
|
174
|
+
# Lazy loaded repeator instance to handle retries.
|
|
175
|
+
def repeator
|
|
176
|
+
@repeator ||= Repeator.new(task)
|
|
177
|
+
end
|
|
178
|
+
|
|
138
179
|
# Performs pre-execution tasks including validation and attribute verification.
|
|
139
180
|
def pre_execution!
|
|
181
|
+
@pre_execution = true
|
|
182
|
+
|
|
140
183
|
invoke_callbacks(:before_validation)
|
|
141
184
|
|
|
142
185
|
task.class.settings[:attributes].define_and_verify(task)
|
|
@@ -171,13 +214,56 @@ module CMDx
|
|
|
171
214
|
|
|
172
215
|
# Finalizes execution by freezing the task and logging results.
|
|
173
216
|
def finalize_execution!
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
217
|
+
log_execution!
|
|
218
|
+
log_backtrace! if task.class.settings[:backtrace]
|
|
219
|
+
|
|
220
|
+
freeze_execution!
|
|
221
|
+
clear_chain!
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Logs the execution result at the configured log level.
|
|
225
|
+
def log_execution!
|
|
226
|
+
task.logger.info { task.result.to_h }
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Logs the backtrace of the exception if the task failed.
|
|
230
|
+
def log_backtrace!
|
|
231
|
+
return unless task.result.failed?
|
|
232
|
+
|
|
233
|
+
exception = task.result.caused_failure.cause
|
|
234
|
+
return if exception.is_a?(Fault)
|
|
235
|
+
|
|
236
|
+
task.logger.error do
|
|
237
|
+
"[#{exception.class}] #{exception.message}\n" <<
|
|
238
|
+
if (cleaner = task.class.settings[:backtrace_cleaner])
|
|
239
|
+
cleaner.call(exception.backtrace).join("\n\t")
|
|
240
|
+
else
|
|
241
|
+
exception.full_message(highlight: false)
|
|
242
|
+
end
|
|
178
243
|
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Freezes the task and its associated objects to prevent modifications.
|
|
247
|
+
def freeze_execution!
|
|
248
|
+
# Stubbing on frozen objects is not allowed in most test environments.
|
|
249
|
+
skip_freezing = ENV.fetch("SKIP_CMDX_FREEZING", false)
|
|
250
|
+
return if Coercions::Boolean.call(skip_freezing)
|
|
251
|
+
|
|
252
|
+
task.freeze
|
|
253
|
+
task.result.freeze
|
|
254
|
+
|
|
255
|
+
# Freezing the context and chain can only be done
|
|
256
|
+
# once the outer-most task has completed.
|
|
257
|
+
return unless task.result.index.zero?
|
|
179
258
|
|
|
180
|
-
|
|
259
|
+
task.context.freeze
|
|
260
|
+
task.chain.freeze
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def clear_chain!
|
|
264
|
+
return unless task.result.index.zero?
|
|
265
|
+
|
|
266
|
+
Chain.clear
|
|
181
267
|
end
|
|
182
268
|
|
|
183
269
|
end
|
data/lib/cmdx/pipeline.rb
CHANGED
|
@@ -42,7 +42,7 @@ module CMDx
|
|
|
42
42
|
# pipeline.execute
|
|
43
43
|
def execute
|
|
44
44
|
workflow.class.pipeline.each do |group|
|
|
45
|
-
next unless Utils::Condition.evaluate(workflow, group.options
|
|
45
|
+
next unless Utils::Condition.evaluate(workflow, group.options)
|
|
46
46
|
|
|
47
47
|
breakpoints = group.options[:breakpoints] ||
|
|
48
48
|
workflow.class.settings[:breakpoints] ||
|
|
@@ -108,18 +108,18 @@ module CMDx
|
|
|
108
108
|
# @example
|
|
109
109
|
# execute_tasks_in_parallel(group, ["failed"])
|
|
110
110
|
def execute_tasks_in_parallel(group, breakpoints)
|
|
111
|
-
raise "install the `parallel` gem to use this feature" unless defined?(
|
|
111
|
+
raise "install the `parallel` gem to use this feature" unless defined?(Parallel)
|
|
112
112
|
|
|
113
113
|
parallel_options = group.options.slice(:in_threads, :in_processes)
|
|
114
114
|
throwable_result = nil
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
Parallel.each(group.tasks, **parallel_options) do |task|
|
|
117
117
|
Chain.current = workflow.chain
|
|
118
118
|
|
|
119
119
|
task_result = task.execute(workflow.context)
|
|
120
120
|
next unless breakpoints.include?(task_result.status)
|
|
121
121
|
|
|
122
|
-
raise
|
|
122
|
+
raise Parallel::Break, throwable_result = task_result
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
return if throwable_result.nil?
|
data/lib/cmdx/railtie.rb
CHANGED
|
@@ -32,5 +32,14 @@ module CMDx
|
|
|
32
32
|
::I18n.reload!
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
# Configures the backtrace cleaner for CMDx in a Rails environment.
|
|
36
|
+
#
|
|
37
|
+
# Sets the backtrace cleaner to the Rails backtrace cleaner.
|
|
38
|
+
initializer("cmdx.backtrace_cleaner") do
|
|
39
|
+
CMDx.configuration.backtrace_cleaner = lambda do |backtrace|
|
|
40
|
+
Rails.backtrace_cleaner.clean(backtrace)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
35
44
|
end
|
|
36
45
|
end
|
data/lib/cmdx/result.rb
CHANGED
|
@@ -291,7 +291,16 @@ module CMDx
|
|
|
291
291
|
|
|
292
292
|
# Strip the first two frames (this method and the delegator)
|
|
293
293
|
frames = caller_locations(3..-1)
|
|
294
|
-
|
|
294
|
+
|
|
295
|
+
unless frames.empty?
|
|
296
|
+
frames = frames.map(&:to_s)
|
|
297
|
+
|
|
298
|
+
if (cleaner = task.class.settings[:backtrace_cleaner])
|
|
299
|
+
cleaner.call(frames)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
fault.set_backtrace(frames)
|
|
303
|
+
end
|
|
295
304
|
|
|
296
305
|
raise(fault)
|
|
297
306
|
end
|
data/lib/cmdx/task.rb
CHANGED
|
@@ -40,9 +40,6 @@ module CMDx
|
|
|
40
40
|
class << self
|
|
41
41
|
|
|
42
42
|
# @param options [Hash] Configuration options to merge with existing settings
|
|
43
|
-
# @option options [AttributeRegistry] :attributes Registry for task attributes
|
|
44
|
-
# @option options [Boolean] :deprecate Whether the task is deprecated
|
|
45
|
-
# @option options [Array<Symbol>] :tags Tags associated with the task
|
|
46
43
|
#
|
|
47
44
|
# @return [Hash] The merged settings hash
|
|
48
45
|
#
|
|
@@ -54,13 +51,21 @@ module CMDx
|
|
|
54
51
|
@settings ||= begin
|
|
55
52
|
hash =
|
|
56
53
|
if superclass.respond_to?(:settings)
|
|
57
|
-
superclass.settings
|
|
54
|
+
parent = superclass.settings
|
|
55
|
+
parent
|
|
56
|
+
.except(:backtrace_cleaner, :exception_handler, :logger, :deprecate)
|
|
57
|
+
.transform_values!(&:dup)
|
|
58
|
+
.merge!(
|
|
59
|
+
backtrace_cleaner: parent[:backtrace_cleaner] || CMDx.configuration.backtrace_cleaner,
|
|
60
|
+
exception_handler: parent[:exception_handler] || CMDx.configuration.exception_handler,
|
|
61
|
+
logger: parent[:logger] || CMDx.configuration.logger,
|
|
62
|
+
deprecate: parent[:deprecate]
|
|
63
|
+
)
|
|
58
64
|
else
|
|
59
|
-
CMDx.configuration.to_h
|
|
60
|
-
end
|
|
65
|
+
CMDx.configuration.to_h
|
|
66
|
+
end
|
|
61
67
|
|
|
62
68
|
hash[:attributes] ||= AttributeRegistry.new
|
|
63
|
-
hash[:deprecate] ||= false
|
|
64
69
|
hash[:tags] ||= []
|
|
65
70
|
|
|
66
71
|
hash.merge!(options)
|
data/lib/cmdx/version.rb
CHANGED
data/lib/cmdx.rb
CHANGED
|
@@ -32,6 +32,15 @@ CMDx.configure do |config|
|
|
|
32
32
|
level: Logger::INFO
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
+
# Backtrace configuration - controls whether to log backtraces on faults and exceptions
|
|
36
|
+
# https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#backtraces
|
|
37
|
+
# config.backtrace = false
|
|
38
|
+
# config.backtrace_cleaner = nil
|
|
39
|
+
|
|
40
|
+
# Exception handler configuration - called when non-fault exceptions are raised
|
|
41
|
+
# https://github.com/drexed/cmdx/blob/main/docs/getting_started.md#exception-handler
|
|
42
|
+
# config.exception_handler = nil
|
|
43
|
+
|
|
35
44
|
# Additional global configurations - automatically applied to all tasks
|
|
36
45
|
#
|
|
37
46
|
# Middlewares - https://github.com/drexed/cmdx/blob/main/docs/middlewares.md
|
data/mkdocs.yml
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json
|
|
2
|
+
|
|
3
|
+
site_name: CMDx
|
|
4
|
+
site_url: https://drexed.github.io/cmdx/
|
|
5
|
+
site_description: Build business logic that's powerful, predictable, and chaos-free.
|
|
6
|
+
site_author: drexed
|
|
7
|
+
repo_name: drexed/cmdx
|
|
8
|
+
repo_url: https://github.com/drexed/cmdx
|
|
9
|
+
edit_uri: edit/main/docs/
|
|
10
|
+
copyright: Drexed, Inc. © 2025 - EoT
|
|
11
|
+
|
|
12
|
+
theme:
|
|
13
|
+
name: material
|
|
14
|
+
logo: assets/favicon.svg
|
|
15
|
+
favicon: assets/favicon.ico
|
|
16
|
+
icon:
|
|
17
|
+
repo: fontawesome/brands/github
|
|
18
|
+
font:
|
|
19
|
+
text: Inter
|
|
20
|
+
code: IBM Plex Mono
|
|
21
|
+
palette:
|
|
22
|
+
# Palette toggle for automatic mode
|
|
23
|
+
- media: "(prefers-color-scheme)"
|
|
24
|
+
primary: custom
|
|
25
|
+
accent: custom
|
|
26
|
+
toggle:
|
|
27
|
+
icon: material/brightness-auto
|
|
28
|
+
name: Switch to light mode
|
|
29
|
+
# Palette toggle for light mode
|
|
30
|
+
- media: "(prefers-color-scheme: light)"
|
|
31
|
+
scheme: default
|
|
32
|
+
primary: custom
|
|
33
|
+
accent: custom
|
|
34
|
+
toggle:
|
|
35
|
+
icon: material/brightness-7
|
|
36
|
+
name: Switch to dark mode
|
|
37
|
+
# Palette toggle for dark mode
|
|
38
|
+
- media: "(prefers-color-scheme: dark)"
|
|
39
|
+
scheme: slate
|
|
40
|
+
primary: custom
|
|
41
|
+
accent: custom
|
|
42
|
+
toggle:
|
|
43
|
+
icon: material/brightness-4
|
|
44
|
+
name: Switch to system preference
|
|
45
|
+
features:
|
|
46
|
+
- navigation.footer
|
|
47
|
+
- navigation.instant
|
|
48
|
+
- navigation.instant.prefetch
|
|
49
|
+
- navigation.instant.progress
|
|
50
|
+
- navigation.tracking
|
|
51
|
+
- navigation.sections
|
|
52
|
+
- navigation.expand
|
|
53
|
+
- navigation.path
|
|
54
|
+
- navigation.top
|
|
55
|
+
- search.share
|
|
56
|
+
- search.suggest
|
|
57
|
+
- search.highlight
|
|
58
|
+
- content.code.copy
|
|
59
|
+
- content.code.annotate
|
|
60
|
+
- content.tabs.link
|
|
61
|
+
- content.tooltips
|
|
62
|
+
|
|
63
|
+
markdown_extensions:
|
|
64
|
+
- admonition
|
|
65
|
+
- pymdownx.details
|
|
66
|
+
- pymdownx.superfences
|
|
67
|
+
- pymdownx.highlight:
|
|
68
|
+
anchor_linenums: true
|
|
69
|
+
line_spans: __span
|
|
70
|
+
pygments_lang_class: true
|
|
71
|
+
- pymdownx.inlinehilite
|
|
72
|
+
- pymdownx.snippets
|
|
73
|
+
- pymdownx.tabbed:
|
|
74
|
+
alternate_style: true
|
|
75
|
+
- tables
|
|
76
|
+
- attr_list
|
|
77
|
+
- md_in_html
|
|
78
|
+
- toc:
|
|
79
|
+
permalink: true
|
|
80
|
+
|
|
81
|
+
plugins:
|
|
82
|
+
- search
|
|
83
|
+
|
|
84
|
+
nav:
|
|
85
|
+
- Home: index.md
|
|
86
|
+
- Getting Started: getting_started.md
|
|
87
|
+
- Basics:
|
|
88
|
+
- Setup: basics/setup.md
|
|
89
|
+
- Execution: basics/execution.md
|
|
90
|
+
- Context: basics/context.md
|
|
91
|
+
- Chain: basics/chain.md
|
|
92
|
+
- Interruptions:
|
|
93
|
+
- Halt: interruptions/halt.md
|
|
94
|
+
- Faults: interruptions/faults.md
|
|
95
|
+
- Exceptions: interruptions/exceptions.md
|
|
96
|
+
- Outcomes:
|
|
97
|
+
- Result: outcomes/result.md
|
|
98
|
+
- States: outcomes/states.md
|
|
99
|
+
- Statuses: outcomes/statuses.md
|
|
100
|
+
- Attributes:
|
|
101
|
+
- Definitions: attributes/definitions.md
|
|
102
|
+
- Naming: attributes/naming.md
|
|
103
|
+
- Coercions: attributes/coercions.md
|
|
104
|
+
- Validations: attributes/validations.md
|
|
105
|
+
- Defaults: attributes/defaults.md
|
|
106
|
+
- Transformations: attributes/transformations.md
|
|
107
|
+
- Callbacks: callbacks.md
|
|
108
|
+
- Middlewares: middlewares.md
|
|
109
|
+
- Logging: logging.md
|
|
110
|
+
- Internationalization: internationalization.md
|
|
111
|
+
- Deprecation: deprecation.md
|
|
112
|
+
- Workflows: workflows.md
|
|
113
|
+
- Tips and Tricks: tips_and_tricks.md
|
|
114
|
+
|
|
115
|
+
extra:
|
|
116
|
+
generator: false
|
|
117
|
+
social:
|
|
118
|
+
- icon: fontawesome/brands/github
|
|
119
|
+
link: https://github.com/drexed/cmdx
|
|
120
|
+
|
|
121
|
+
extra_css:
|
|
122
|
+
- stylesheets/extra.css
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="104.098" height="112.266" viewBox="0 0 60 64.708" xmlns="http://www.w3.org/2000/svg"><path d="M29.907 17.723 26.4 23.17 13.384 3.323h3.507l9.508 14.77 1.938-3.139L18.737 0H7.291L26.4 29.262 45.045 0h-3.97L30 17.54zM9.23 61.293H6.091l18.646-29.447L4.43.093H.46l20.308 31.846L0 64.708l10.985-.092 39.138-61.2h3.323L31.57 37.754l13.662 21.415h3.97L35.445 37.754 59.537.093H48.37zm29.63-23.262 15.047 23.262H43.384l-13.662-20.77-15.508 24.093h3.97l11.63-18 11.723 18H60L41.17 35.354l-.278-.461z" fill="#000"/></svg>
|
|
Binary file
|
data/src/cmdx-logo.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="352.2" height="112.266" viewBox="0 0 203 64.708" xmlns="http://www.w3.org/2000/svg" xmlSpace="preserve"><path d="M172.908 17.723 169.4 23.17 156.385 3.323h3.507l9.508 14.77 1.938-3.139L161.738 0h-11.446L169.4 29.262 188.046 0h-3.97L173 17.54zm-20.677 43.57h-3.139l18.646-29.447L147.431.093h-3.97l20.308 31.846L143 64.708l10.985-.092 39.138-61.2h3.323L174.57 37.754l13.662 21.415h3.969l-13.754-21.415L202.538.093H191.37zm29.63-23.262 15.047 23.262h-10.523l-13.662-20.77-15.508 24.093h3.97l11.63-18 11.723 18H203l-18.83-29.262-.278-.461z" fill="#fe1817"/><path d="M41.667 14v12.8h-23.42c-3.214.272-5.665 3.05-5.665 6.318s2.45 5.937 5.664 6.318H33.17v4.248H18.246a10.65 10.65 0 0 1-9.858-10.62c0-5.447 4.194-10.077 9.64-10.512h19.39v-4.303H18.246v.054A14.823 14.823 0 0 0 4.248 33.118c0 7.898 6.21 14.38 13.998 14.815h19.172v-8.497h4.249v12.745h-23.42A19.063 19.063 0 0 1 0 33.118a19.033 19.033 0 0 1 18.246-19.063zM75 35.623 87.2 14h13.508v38.181H87.963v-14.27l-8.116 14.27h-9.749L57.734 30.504v-8.007l14.87 25.436h4.792l14.815-25.436v25.436h4.249V18.249H89.65l-14.76 25.49-14.542-25.49H53.54v29.684h4.194v-8.007l4.249 7.299v4.956H49.292v-38.18H62.8zM108.333 14h23.42C141.94 14.436 150 22.824 150 33.064c0 10.294-8.061 18.681-18.246 19.117h-23.42V22.497h23.42a10.65 10.65 0 0 1 9.858 10.621c0 5.447-4.194 10.13-9.64 10.566H116.83V30.286h4.248v9.15l10.676-.054c3.213-.273 5.664-3.05 5.664-6.264 0-2.778-1.743-5.065-4.194-5.991-.926-.382-1.47-.382-2.94-.382h-17.702v21.188h19.172a14.84 14.84 0 0 0 13.998-14.87c0-7.897-6.21-14.379-13.998-14.814h-23.42z"/></svg>
|
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.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Juan Gomez
|
|
@@ -214,10 +214,14 @@ files:
|
|
|
214
214
|
- LLM.md
|
|
215
215
|
- README.md
|
|
216
216
|
- Rakefile
|
|
217
|
+
- docs/.DS_Store
|
|
218
|
+
- docs/assets/favicon.ico
|
|
219
|
+
- docs/assets/favicon.svg
|
|
217
220
|
- docs/attributes/coercions.md
|
|
218
221
|
- docs/attributes/defaults.md
|
|
219
222
|
- docs/attributes/definitions.md
|
|
220
223
|
- docs/attributes/naming.md
|
|
224
|
+
- docs/attributes/transformations.md
|
|
221
225
|
- docs/attributes/validations.md
|
|
222
226
|
- docs/basics/chain.md
|
|
223
227
|
- docs/basics/context.md
|
|
@@ -226,6 +230,7 @@ files:
|
|
|
226
230
|
- docs/callbacks.md
|
|
227
231
|
- docs/deprecation.md
|
|
228
232
|
- docs/getting_started.md
|
|
233
|
+
- docs/index.md
|
|
229
234
|
- docs/internationalization.md
|
|
230
235
|
- docs/interruptions/exceptions.md
|
|
231
236
|
- docs/interruptions/faults.md
|
|
@@ -235,8 +240,11 @@ files:
|
|
|
235
240
|
- docs/outcomes/result.md
|
|
236
241
|
- docs/outcomes/states.md
|
|
237
242
|
- docs/outcomes/statuses.md
|
|
243
|
+
- docs/stylesheets/extra.css
|
|
238
244
|
- docs/tips_and_tricks.md
|
|
239
245
|
- docs/workflows.md
|
|
246
|
+
- examples/active_record_query_tagging.md
|
|
247
|
+
- examples/paper_trail_whatdunnit.md
|
|
240
248
|
- lib/cmdx.rb
|
|
241
249
|
- lib/cmdx/.DS_Store
|
|
242
250
|
- lib/cmdx/attribute.rb
|
|
@@ -265,7 +273,6 @@ files:
|
|
|
265
273
|
- lib/cmdx/exceptions.rb
|
|
266
274
|
- lib/cmdx/executor.rb
|
|
267
275
|
- lib/cmdx/faults.rb
|
|
268
|
-
- lib/cmdx/freezer.rb
|
|
269
276
|
- lib/cmdx/identifier.rb
|
|
270
277
|
- lib/cmdx/locale.rb
|
|
271
278
|
- lib/cmdx/log_formatters/json.rb
|
|
@@ -386,7 +393,11 @@ files:
|
|
|
386
393
|
- lib/locales/zh-HK.yml
|
|
387
394
|
- lib/locales/zh-TW.yml
|
|
388
395
|
- lib/locales/zh-YUE.yml
|
|
389
|
-
-
|
|
396
|
+
- mkdocs.yml
|
|
397
|
+
- src/cmdx-dark-logo.png
|
|
398
|
+
- src/cmdx-favicon.svg
|
|
399
|
+
- src/cmdx-light-logo.png
|
|
400
|
+
- src/cmdx-logo.svg
|
|
390
401
|
homepage: https://github.com/drexed/cmdx
|
|
391
402
|
licenses:
|
|
392
403
|
- MIT
|
data/lib/cmdx/freezer.rb
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module CMDx
|
|
4
|
-
# Provides freezing functionality for CMDx tasks and their associated objects.
|
|
5
|
-
#
|
|
6
|
-
# The Freezer module is responsible for making task objects immutable after execution
|
|
7
|
-
# to prevent accidental modifications and ensure data integrity. It can be disabled
|
|
8
|
-
# via environment variable for testing or debugging purposes.
|
|
9
|
-
module Freezer
|
|
10
|
-
|
|
11
|
-
extend self
|
|
12
|
-
|
|
13
|
-
# Freezes a task and its associated objects to prevent modifications.
|
|
14
|
-
#
|
|
15
|
-
# This method makes the task, result, context, and chain immutable after execution.
|
|
16
|
-
# Freezing can be skipped by setting the SKIP_CMDX_FREEZING environment variable.
|
|
17
|
-
#
|
|
18
|
-
# @param task [Task] The task instance to freeze
|
|
19
|
-
# @option ENV["SKIP_CMDX_FREEZING"] [String, Boolean] Set to "true" or true to skip freezing
|
|
20
|
-
#
|
|
21
|
-
# @raise [RuntimeError] If attempting to stub on frozen objects
|
|
22
|
-
#
|
|
23
|
-
# @example Freeze a completed task
|
|
24
|
-
# task = MyTask.new
|
|
25
|
-
# task.execute
|
|
26
|
-
# CMDx::Freezer.immute(task)
|
|
27
|
-
# # task, result, context, and chain are now frozen
|
|
28
|
-
# @example Skip freezing for testing
|
|
29
|
-
# ENV["SKIP_CMDX_FREEZING"] = "true"
|
|
30
|
-
# CMDx::Freezer.immute(task)
|
|
31
|
-
# # No freezing occurs
|
|
32
|
-
def immute(task)
|
|
33
|
-
# Stubbing on frozen objects is not allowed
|
|
34
|
-
skip_freezing = ENV.fetch("SKIP_CMDX_FREEZING", false)
|
|
35
|
-
return if Coercions::Boolean.call(skip_freezing)
|
|
36
|
-
|
|
37
|
-
task.freeze
|
|
38
|
-
task.result.freeze
|
|
39
|
-
|
|
40
|
-
# Freezing the context and chain can only be done
|
|
41
|
-
# once the outer-most task has completed.
|
|
42
|
-
return unless task.result.index.zero?
|
|
43
|
-
|
|
44
|
-
task.context.freeze
|
|
45
|
-
task.chain.freeze
|
|
46
|
-
|
|
47
|
-
Chain.clear
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
end
|
|
51
|
-
end
|
data/src/cmdx-logo.png
DELETED
|
Binary file
|