cmdx 1.13.0 → 1.14.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +84 -76
  3. data/LICENSE.txt +3 -20
  4. data/README.md +8 -7
  5. data/lib/cmdx/attribute.rb +21 -5
  6. data/lib/cmdx/context.rb +16 -0
  7. data/lib/cmdx/executor.rb +9 -9
  8. data/lib/cmdx/result.rb +27 -7
  9. data/lib/cmdx/task.rb +19 -0
  10. data/lib/cmdx/version.rb +1 -1
  11. data/mkdocs.yml +62 -36
  12. metadata +3 -57
  13. data/.cursor/prompts/docs.md +0 -12
  14. data/.cursor/prompts/llms.md +0 -8
  15. data/.cursor/prompts/rspec.md +0 -24
  16. data/.cursor/prompts/yardoc.md +0 -15
  17. data/.cursor/rules/cursor-instructions.mdc +0 -68
  18. data/.irbrc +0 -18
  19. data/.rspec +0 -4
  20. data/.rubocop.yml +0 -95
  21. data/.ruby-version +0 -1
  22. data/.yard-lint.yml +0 -174
  23. data/.yardopts +0 -7
  24. data/docs/.DS_Store +0 -0
  25. data/docs/assets/favicon.ico +0 -0
  26. data/docs/assets/favicon.svg +0 -1
  27. data/docs/attributes/coercions.md +0 -155
  28. data/docs/attributes/defaults.md +0 -77
  29. data/docs/attributes/definitions.md +0 -283
  30. data/docs/attributes/naming.md +0 -68
  31. data/docs/attributes/transformations.md +0 -63
  32. data/docs/attributes/validations.md +0 -336
  33. data/docs/basics/chain.md +0 -108
  34. data/docs/basics/context.md +0 -121
  35. data/docs/basics/execution.md +0 -152
  36. data/docs/basics/setup.md +0 -107
  37. data/docs/callbacks.md +0 -157
  38. data/docs/configuration.md +0 -314
  39. data/docs/deprecation.md +0 -143
  40. data/docs/getting_started.md +0 -137
  41. data/docs/index.md +0 -134
  42. data/docs/internationalization.md +0 -126
  43. data/docs/interruptions/exceptions.md +0 -52
  44. data/docs/interruptions/faults.md +0 -169
  45. data/docs/interruptions/halt.md +0 -216
  46. data/docs/logging.md +0 -90
  47. data/docs/middlewares.md +0 -191
  48. data/docs/outcomes/result.md +0 -197
  49. data/docs/outcomes/states.md +0 -66
  50. data/docs/outcomes/statuses.md +0 -65
  51. data/docs/retries.md +0 -121
  52. data/docs/stylesheets/extra.css +0 -42
  53. data/docs/tips_and_tricks.md +0 -157
  54. data/docs/workflows.md +0 -226
  55. data/examples/active_record_database_transaction.md +0 -27
  56. data/examples/active_record_query_tagging.md +0 -46
  57. data/examples/flipper_feature_flags.md +0 -50
  58. data/examples/paper_trail_whatdunnit.md +0 -39
  59. data/examples/redis_idempotency.md +0 -71
  60. data/examples/sentry_error_tracking.md +0 -46
  61. data/examples/sidekiq_async_execution.md +0 -29
  62. data/examples/stoplight_circuit_breaker.md +0 -36
  63. data/src/cmdx-dark-logo.png +0 -0
  64. data/src/cmdx-favicon.svg +0 -1
  65. data/src/cmdx-light-logo.png +0 -0
  66. data/src/cmdx-logo.svg +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b1cd7841d40aeac40b6eb36a7ff87a5ace03deae3496e1aef5cb10e34f8f42d
4
- data.tar.gz: 303333d4635690575ceda40a2564be417b47f5ec4c2992af542c509710289ae3
3
+ metadata.gz: 620c2c00dd483c6a4122c7b5acbbe6cf7a07d22260d0331d6f1d54b571ef7648
4
+ data.tar.gz: aff47b340a77b052bc4cd2e201068044a443c1d8f4609163fa45025bdba25d00
5
5
  SHA512:
6
- metadata.gz: 18cde5cf4b6c7fa974ffb7a3827e09d0a5c2ac5f3c2c01427abbc94de71ef1bc03aee78e25032900761f09c8d39e89e52a4ea1d5fa33e07c86f060b483fe839f
7
- data.tar.gz: 5ed05ecdb682ae160be47cf6399c76081486011b6143f95f9884a06b588474ba64e3e000efd72ba2dcd6abb343e3e12985d2691ca15ee7575873f90daff6e70f
6
+ metadata.gz: a8f6fec277ff0198937013c25a1a1c753d4cf5100ff4920c834dc92fba8df7d2adc1ef3fbcff91c999f1af8c4676c3e8702c71a29a3402efcf36d4a0236163ba
7
+ data.tar.gz: 2233517633c8d9afaafb7a44878b6b3fe0939dabcbe647ceafd9e7ca04450ee1e5e9f6b6f5adb2de58c305b0c2c0940e74ee2d7290f0eb202bda429d76b66992
data/CHANGELOG.md CHANGED
@@ -4,175 +4,183 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [UNRELEASED]
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+ - Add Ruby 4.0 compatibility
11
+ - Add `Context#clear!` method to remove all context data
12
+ - Add `Task.attribute_schema` class method for attribute introspection
13
+ - Add `#to_h` method for attribute serialization
14
+
15
+ ### Changed
16
+ - **BREAKING**: Switch license from MIT to LGPLv3
17
+ - Replace `instance_eval` with `define_singleton_method` for attribute method definitions
18
+ - Move retry count from metadata to result object
19
+ - Exclude non-essential files from gem package
20
+
21
+ ### Removed
22
+ - Remove public `Result#rolled_back!` method to hide internal implementation
8
23
 
9
24
  ## [1.13.0] - 2025-12-23
10
25
 
11
26
  ### Added
12
-
13
- - Added task execution rollback tracking and logging
14
- - Added `dry_run` option to task execution with inheritance support for nested tasks
15
- - Added context `delete` alias for `delete!`
16
- - Added context `merge` alias for `merge!`
27
+ - Add rollback tracking and logging for task execution
28
+ - Add `dry_run` execution option with inheritance support for nested tasks
29
+ - Add `Context#delete` alias for `Context#delete!`
30
+ - Add `Context#merge` alias for `Context#merge!`
17
31
 
18
32
  ## [1.12.0] - 2025-12-18
19
33
 
20
- ### Added
21
- - Added active record database transaction example
22
- - Added Sentry error tracking example
23
- - Added Redis idempotency example
24
- - Added Flipper feature flag example
25
-
26
- ### Updated
27
- - Remove `handle_*` methods and provide `on(*states_or_statuses)` method for more flexibility
28
- - Optimize logging ancestor lookup
29
- - Use chop instead of range for better string performance
30
- - Update boolean coercion `TRUTHY` and `FALSEY` regexp to be case insensitive
31
- - Improve YARD documentation with `yard-lint`
34
+ ### Changed
35
+ - Optimize logging ancestor chain lookup performance
36
+ - Use `String#chop` instead of range indexing for improved string performance
37
+ - Make boolean coercion `TRUTHY` and `FALSEY` patterns case-insensitive
38
+ - Enhance YARD documentation using `yard-lint` validation
39
+
40
+ ### Removed
41
+ - Remove `handle_*` callback methods in favor of `on(*states_or_statuses)` for flexible state handling
32
42
 
33
43
  ## [1.11.0] - 2025-11-08
34
44
 
35
- ### Updated
36
- - Added conditionally required attributes options
37
- - Update specs to use new `cmdx-rspec` matcher names
45
+ ### Changed
46
+ - Add conditional requirement support for attribute validation
47
+ - Update specs to use new `cmdx-rspec` matcher naming conventions
38
48
 
39
49
  ## [1.10.1] - 2025-11-06
40
50
 
41
51
  ### Added
42
- - Added Sidekiq async integration example
43
- - Added YARDoc documentation to docs site
52
+ - Add YARDoc documentation to documentation site
44
53
 
45
54
  ### Removed
46
- - Removed `Executor#repeator` method (never used)
55
+ - Remove unused `Executor#repeator` method
47
56
 
48
57
  ## [1.10.0] - 2025-10-26
49
58
 
50
59
  ### Added
51
- - Added `rollback` ability to undo on matching status
52
- - Added documentation for retries
53
- - Added Stoplight circuit breaker integration example
60
+ - Add `rollback` capability to undo operations based on status
61
+ - Add retry mechanism documentation
54
62
 
55
- ### Updated
56
- - Updated `retry_jitter` option to support symbol, proc, and callables on top of fixed values
63
+ ### Changed
64
+ - Extend `retry_jitter` option to accept symbols, procs, and callable objects
57
65
 
58
66
  ## [1.9.1] - 2025-10-22
59
67
 
60
68
  ### Added
61
- - Added RBS inlines type signatures
62
- - Added YARDocs for `attr_reader` and `attr_accessor` methods
69
+ - Add RBS inline type signatures
70
+ - Add YARDocs for `attr_reader` and `attr_accessor` methods
63
71
 
64
72
  ## [1.9.0] - 2025-10-21
65
73
 
66
74
  ### Added
67
- - Added `transform` option to attributes
68
- - Added option to output failure backtraces
69
- - Added exception handling for non-bang methods
70
- - Added durability with automatic retries to execution
71
- - Added `to_h` hash coercion support
72
- - Added comprehensive MkDocs configuration with material theme
75
+ - Add `transform` option for attribute value transformations
76
+ - Add optional failure backtrace output
77
+ - Add exception handling for non-bang execution methods
78
+ - Add automatic retry mechanism for execution durability
79
+ - Add `to_h` hash coercion support
80
+ - Add MkDocs configuration with Material theme
73
81
 
74
82
  ### Changed
75
- - Improved performance of task settings setup
76
- - Improved error messages for raised exceptions
77
- - Improved inheritance of parent settings
78
- - Cleaned halt backtrace frames for better readability
83
+ - Improve task settings initialization performance
84
+ - Improve exception error message clarity
85
+ - Improve parent settings inheritance behavior
86
+ - Clean halt backtrace frames for better readability
79
87
 
80
88
  ### Removed
81
- - Removed `Freezer` module and moved logic into executor `freeze_execution!` method
82
- - Removed task parameter from callback signature
83
- - Removed task and workflow arguments from conditional checks
84
- - Removed chain persistence after execution in specs
89
+ - Remove `Freezer` module; consolidate logic into `Executor#freeze_execution!`
90
+ - Remove `task` parameter from callback method signatures
91
+ - Remove `task` and `workflow` arguments from conditional checks
92
+ - Remove chain persistence after execution in specs
85
93
 
86
94
  ## [1.8.0] - 2025-09-22
87
95
 
88
96
  ### Changed
89
- - Generalized locale values for fault `invalid` and `unspecified`
90
- - Nested attribute error messages under `error` key within metadata
91
- - Reordered logstash formatter keys for consistency
92
- - Improved error message for already defined items
93
- - Changed hash coercion for `nil` to return `{}`
97
+ - Generalize locale values for `invalid` and `unspecified` faults
98
+ - Nest attribute error messages under `error` key in metadata
99
+ - Reorder Logstash formatter keys for consistency
100
+ - Improve error messaging for duplicate item definitions
101
+ - Return empty hash `{}` for `nil` hash coercion
94
102
 
95
103
  ## [1.7.5] - 2025-09-10
96
104
 
97
105
  ### Added
98
- - Added `fetch_or_store` method to context
99
- - Added `ctx` alias for context in result
100
- - Added `ok?` alias for `good?` in result
101
- - Added deconstruction values in result
106
+ - Add `Context#fetch_or_store` method for atomic get-or-set operations
107
+ - Add `Result#ctx` alias for `Result#context`
108
+ - Add `Result#ok?` alias for `Result#good?`
109
+ - Add result deconstruction support for pattern matching
102
110
 
103
111
  ## [1.7.4] - 2025-09-03
104
112
 
105
113
  ### Added
106
- - Added errors delegation from result object
107
- - Added `full_messages` and `to_hash` methods to errors
114
+ - Add errors delegation from result object
115
+ - Add `Errors#full_messages` and `Errors#to_hash` methods
108
116
 
109
117
  ## [1.7.3] - 2025-09-03
110
118
 
111
119
  ### Changed
112
- - Changed validation reasons to use generic values
113
- - Moved validation full message string to `:full_message` key within metadata
120
+ - Use generic validation reason values
121
+ - Move validation full message to `:full_message` key in metadata
114
122
 
115
123
  ## [1.7.2] - 2025-09-03
116
124
 
117
125
  ### Changed
118
- - Changed correlation ID to be set before continuing to further steps
126
+ - Set correlation ID before proceeding to subsequent execution steps
119
127
 
120
128
  ## [1.7.1] - 2025-08-26
121
129
 
122
130
  ### Added
123
- - Added result yielding when block is given to `execute` and `execute!` methods
131
+ - Add block yielding support to `execute` and `execute!` methods
124
132
 
125
133
  ## [1.7.0] - 2025-08-25
126
134
 
127
135
  ### Added
128
- - Added workflow generator
136
+ - Add workflow generator
129
137
 
130
138
  ### Changed
131
- - Ported `cmdx-parallel` changes into core
132
- - Ported `cmdx-i18n` changes into core
139
+ - Integrate `cmdx-parallel` functionality into core
140
+ - Integrate `cmdx-i18n` functionality into core
133
141
 
134
142
  ## [1.6.2] - 2025-08-24
135
143
 
136
144
  ### Changed
137
- - Prefixed railtie I18n with `::` for compatibility with `CMDx::I18n`
138
- - Changed to use `cmdx-rspec` for matchers support
145
+ - Prefix railtie I18n with `::` for `CMDx::I18n` compatibility
146
+ - Switch to `cmdx-rspec` for matcher support
139
147
 
140
148
  ## [1.6.1] - 2025-08-23
141
149
 
142
150
  ### Changed
143
- - Changed task results to be logged before freezing
144
- - Renamed `execute_tasks_sequentially` to `execute_tasks_in_sequence`
151
+ - Log task results before freezing execution state
152
+ - Rename `execute_tasks_sequentially` to `execute_tasks_in_sequence`
145
153
 
146
154
  ## [1.6.0] - 2025-08-22
147
155
 
148
156
  ### Added
149
- - Added workflow task `:breakpoints` support
157
+ - Add workflow task `:breakpoints` support
150
158
 
151
159
  ### Changed
152
- - Renamed `Worker` class to `Executor`
153
- - Moved workflow `work` logic into `Pipeline`
160
+ - Rename `Worker` class to `Executor`
161
+ - Extract workflow execution logic into `Pipeline` class
154
162
 
155
163
  ## [1.5.2] - 2025-08-22
156
164
 
157
165
  ### Changed
158
- - Renamed workflow `execution_groups` attribute to `pipeline`
166
+ - Rename workflow `execution_groups` attribute to `pipeline`
159
167
 
160
168
  ## [1.5.1] - 2025-08-21
161
169
 
162
170
  ### Changed
163
- - Prefixed locale I18n with `::` for compatibility with `CMDx::I18n`
164
- - Added safe navigation to length and numeric validators
165
- - Updated railtie file path to point to correct directory
171
+ - Prefix locale I18n with `::` for `CMDx::I18n` compatibility
172
+ - Add safe navigation to length and numeric validators
173
+ - Fix railtie file path to reference correct directory
166
174
 
167
175
  ## [1.5.0] - 2025-08-21
168
176
 
169
177
  ### Changed
170
- - **BREAKING**: Revamped CMDx for improved clarity, transparency, and higher performance
178
+ - **BREAKING**: Complete architecture redesign for improved clarity, transparency, and performance
171
179
 
172
180
  ## [1.1.2] - 2025-07-20
173
181
 
174
182
  ### Changed
175
- - All changes between versions `0.1.0` and `1.1.2` should be reviewed within their respective git tags
183
+ - See git tags for changes between versions 0.1.0 and 1.1.2
176
184
 
177
185
  ## [0.1.0] - 2025-03-07
178
186
 
data/LICENSE.txt CHANGED
@@ -1,21 +1,4 @@
1
- The MIT License (MIT)
1
+ Copyright (c) Drexed
2
2
 
3
- Copyright (c) 2025 Juan Gomez
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
3
+ CMDx is an Open Source project licensed under the terms of the LGPLv3 license.
4
+ Please see <http://www.gnu.org/licenses/lgpl-3.0.html> for license text.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
- <img src="./src/cmdx-light-logo.png#gh-light-mode-only" width="200" alt="CMDx Logo">
3
- <img src="./src/cmdx-dark-logo.png#gh-dark-mode-only" width="200" alt="CMDx Logo">
2
+ <img src="./src/cmdx-light-logo.png#gh-light-mode-only" width="200" alt="CMDx Light Logo">
3
+ <img src="./src/cmdx-dark-logo.png#gh-dark-mode-only" width="200" alt="CMDx Dark Logo">
4
4
 
5
5
  ---
6
6
 
@@ -10,7 +10,7 @@
10
10
 
11
11
  <img alt="Version" src="https://img.shields.io/gem/v/cmdx">
12
12
  <img alt="Build" src="https://github.com/drexed/cmdx/actions/workflows/ci.yml/badge.svg">
13
- <img alt="License" src="https://img.shields.io/github/license/drexed/cmdx">
13
+ <img alt="License" src="https://img.shields.io/badge/license-LGPL%20v3-blue.svg">
14
14
  </div>
15
15
 
16
16
  # CMDx
@@ -18,13 +18,14 @@
18
18
  Say goodbye to messy service objects. CMDx helps you design business logic with clarity and consistency—build faster, debug easier, and ship with confidence.
19
19
 
20
20
  > [!NOTE]
21
- > Documentation reflects the latest code on `main`. For version-specific documentation, please refer to the `docs/` directory within that version's tag.
21
+ > [Documentation](https://drexed.github.io/cmdx/getting_started/) reflects the latest code on `main`. For version-specific documentation, please refer to the `docs/` directory within that version's tag.
22
22
 
23
23
  ## Requirements
24
24
 
25
- - Ruby: MRI 3.1+ or JRuby 9.4+.
25
+ - Ruby: MRI 3.1+ or JRuby 9.4+
26
+ - Dependencies: None
26
27
 
27
- CMDx works with any Ruby framework. Rails support is built-in, but it's framework-agnostic at its core.
28
+ Rails support is built-in, but it's framework-agnostic at its core.
28
29
 
29
30
  ## Installation
30
31
 
@@ -125,4 +126,4 @@ Bug reports and pull requests are welcome at <https://github.com/drexed/cmdx>. W
125
126
 
126
127
  ## License
127
128
 
128
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
129
+ The gem is available as open source under the terms of the [LGPLv3 License](https://www.gnu.org/licenses/lgpl-3.0.html).
@@ -235,6 +235,23 @@ module CMDx
235
235
  end
236
236
  end
237
237
 
238
+ # @return [Hash] A hash representation of the attribute
239
+ #
240
+ # @example
241
+ # attribute.to_h # => { name: :user_id, method_name: :user_id, required: true, types: [:integer], options: {}, children: [] }
242
+ #
243
+ # @rbs () -> Hash[Symbol, untyped]
244
+ def to_h
245
+ {
246
+ name: name,
247
+ method_name: method_name,
248
+ required: required?,
249
+ types: types,
250
+ options: options.except(:if, :unless),
251
+ children: children.map(&:to_h)
252
+ }
253
+ end
254
+
238
255
  private
239
256
 
240
257
  # Creates nested attributes as children of this attribute.
@@ -312,11 +329,10 @@ module CMDx
312
329
  attribute_value.generate
313
330
  attribute_value.validate
314
331
 
315
- task.instance_eval(<<~RUBY, __FILE__, __LINE__ + 1)
316
- def #{method_name}
317
- attributes[:#{method_name}]
318
- end
319
- RUBY
332
+ name_of_method = method_name
333
+ task.define_singleton_method(name_of_method) do
334
+ attributes[name_of_method]
335
+ end
320
336
  end
321
337
 
322
338
  end
data/lib/cmdx/context.rb CHANGED
@@ -185,6 +185,22 @@ module CMDx
185
185
  end
186
186
  alias delete delete!
187
187
 
188
+ # Clears all key-value pairs from the context.
189
+ #
190
+ # @return [Context] self for method chaining
191
+ #
192
+ # @example
193
+ # context = Context.new(name: "John")
194
+ # context.clear!
195
+ # context.to_h # => {}
196
+ #
197
+ # @rbs () -> self
198
+ def clear!
199
+ table.clear
200
+ self
201
+ end
202
+ alias clear clear!
203
+
188
204
  # Compares this context with another object for equality.
189
205
  #
190
206
  # @param other [Object] the object to compare with
data/lib/cmdx/executor.rb CHANGED
@@ -138,17 +138,17 @@ module CMDx
138
138
  #
139
139
  # @rbs (Exception exception) -> bool
140
140
  def retry_execution?(exception)
141
- available_retries = (task.class.settings[:retries] || 0).to_i
141
+ available_retries = Integer(task.class.settings[:retries] || 0)
142
142
  return false unless available_retries.positive?
143
143
 
144
- current_retries = (result.metadata[:retries] ||= 0).to_i
145
- remaining_retries = available_retries - current_retries
144
+ current_retry = result.retries
145
+ remaining_retries = available_retries - current_retry
146
146
  return false unless remaining_retries.positive?
147
147
 
148
148
  exceptions = Array(task.class.settings[:retry_on] || StandardError)
149
149
  return false unless exceptions.any? { |e| exception.class <= e }
150
150
 
151
- result.metadata[:retries] += 1
151
+ result.retries += 1
152
152
 
153
153
  task.logger.warn do
154
154
  reason = "[#{exception.class}] #{exception.message}"
@@ -158,13 +158,13 @@ module CMDx
158
158
  jitter = task.class.settings[:retry_jitter]
159
159
  jitter =
160
160
  if jitter.is_a?(Symbol)
161
- task.send(jitter, current_retries)
161
+ task.send(jitter, current_retry)
162
162
  elsif jitter.is_a?(Proc)
163
- task.instance_exec(current_retries, &jitter)
163
+ task.instance_exec(current_retry, &jitter)
164
164
  elsif jitter.respond_to?(:call)
165
- jitter.call(task, current_retries)
165
+ jitter.call(task, current_retry)
166
166
  else
167
- jitter.to_f * current_retries
167
+ jitter.to_f * current_retry
168
168
  end
169
169
 
170
170
  sleep(jitter) if jitter.positive?
@@ -320,7 +320,7 @@ module CMDx
320
320
  statuses = Array(statuses).map(&:to_s).uniq
321
321
  return unless statuses.include?(result.status)
322
322
 
323
- result.rolled_back!
323
+ result.rolled_back = true
324
324
  task.rollback
325
325
  end
326
326
 
data/lib/cmdx/result.rb CHANGED
@@ -70,7 +70,7 @@ module CMDx
70
70
  # @return [Hash{Symbol => Object}] Metadata hash
71
71
  #
72
72
  # @example
73
- # result.metadata # => { duration: 1.5, retries: 2 }
73
+ # result.metadata # => { duration: 1.5, code: 200, message: "Success" }
74
74
  #
75
75
  # @rbs @metadata: Hash[Symbol, untyped]
76
76
  attr_reader :metadata
@@ -95,6 +95,26 @@ module CMDx
95
95
  # @rbs @cause: (Exception | nil)
96
96
  attr_reader :cause
97
97
 
98
+ # Returns the number of retries attempted.
99
+ #
100
+ # @return [Integer] The number of retries attempted
101
+ #
102
+ # @example
103
+ # result.retries # => 2
104
+ #
105
+ # @rbs @retries: Integer
106
+ attr_accessor :retries
107
+
108
+ # Returns whether the result has been rolled back.
109
+ #
110
+ # @return [Boolean] Whether the result has been rolled back
111
+ #
112
+ # @example
113
+ # result.rolled_back? # => true
114
+ #
115
+ # @rbs @rolled_back: bool
116
+ attr_accessor :rolled_back
117
+
98
118
  def_delegators :task, :context, :chain, :errors, :dry_run?
99
119
  alias ctx context
100
120
 
@@ -118,6 +138,7 @@ module CMDx
118
138
  @metadata = {}
119
139
  @reason = nil
120
140
  @cause = nil
141
+ @retries = 0
121
142
  @rolled_back = false
122
143
  end
123
144
 
@@ -420,15 +441,14 @@ module CMDx
420
441
  failed? && !caused_failure?
421
442
  end
422
443
 
423
- # @return [void]
444
+ # @return [Boolean] Whether the result has been retried
424
445
  #
425
446
  # @example
426
- # result.rolled_back!
427
- # result.rolled_back? # => true
447
+ # result.retried? # => true
428
448
  #
429
- # @rbs () -> void
430
- def rolled_back!
431
- @rolled_back = true
449
+ # @rbs () -> bool
450
+ def retried?
451
+ retries.positive?
432
452
  end
433
453
 
434
454
  # @return [Boolean] Whether the result has been rolled back
data/lib/cmdx/task.rb CHANGED
@@ -217,6 +217,25 @@ module CMDx
217
217
  end
218
218
  alias remove_attribute remove_attributes
219
219
 
220
+ # @return [Hash] Hash of attribute names to their configurations
221
+ #
222
+ # @example
223
+ # MyTask.attributes_schema #=> {
224
+ # user_id: { name: :user_id, method_name: :user_id, required: true, types: [:integer], options: {}, children: [] },
225
+ # email: { name: :email, method_name: :email, required: false, types: [:string], options: { default: nil }, children: [] },
226
+ # profile: { name: :profile, method_name: :profile, required: false, types: [:hash], options: {}, children: [
227
+ # { name: :bio, method_name: :bio, required: false, types: [:string], options: {}, children: [] },
228
+ # { name: :name, method_name: :name, required: true, types: [:string], options: {}, children: [] }
229
+ # ] }
230
+ # }
231
+ #
232
+ # @rbs () -> Hash[Symbol, Hash[Symbol, untyped]]
233
+ def attributes_schema
234
+ Array(settings[:attributes]).each_with_object({}) do |attr, schema|
235
+ schema[attr.method_name] = attr.to_h
236
+ end
237
+ end
238
+
220
239
  CallbackRegistry::TYPES.each do |callback|
221
240
  # @param callables [Array] Callable objects to register as callbacks
222
241
  # @param options [Hash] Options for the callback registration
data/lib/cmdx/version.rb CHANGED
@@ -5,6 +5,6 @@ module CMDx
5
5
  # @return [String] the version of the CMDx gem
6
6
  #
7
7
  # @rbs return: String
8
- VERSION = "1.13.0"
8
+ VERSION = "1.14.0"
9
9
 
10
10
  end