cmdx 1.20.0 → 2.0.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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +131 -1
  3. data/README.md +37 -24
  4. data/lib/cmdx/.DS_Store +0 -0
  5. data/lib/cmdx/callbacks.rb +179 -0
  6. data/lib/cmdx/chain.rb +78 -175
  7. data/lib/cmdx/coercions/array.rb +19 -33
  8. data/lib/cmdx/coercions/big_decimal.rb +12 -29
  9. data/lib/cmdx/coercions/boolean.rb +25 -45
  10. data/lib/cmdx/coercions/coerce.rb +32 -0
  11. data/lib/cmdx/coercions/complex.rb +12 -27
  12. data/lib/cmdx/coercions/date.rb +29 -33
  13. data/lib/cmdx/coercions/date_time.rb +29 -33
  14. data/lib/cmdx/coercions/float.rb +8 -29
  15. data/lib/cmdx/coercions/hash.rb +17 -43
  16. data/lib/cmdx/coercions/integer.rb +8 -32
  17. data/lib/cmdx/coercions/rational.rb +12 -33
  18. data/lib/cmdx/coercions/string.rb +6 -24
  19. data/lib/cmdx/coercions/symbol.rb +12 -26
  20. data/lib/cmdx/coercions/time.rb +31 -35
  21. data/lib/cmdx/coercions.rb +174 -0
  22. data/lib/cmdx/configuration.rb +45 -225
  23. data/lib/cmdx/context.rb +263 -242
  24. data/lib/cmdx/deprecation.rb +67 -0
  25. data/lib/cmdx/deprecators/error.rb +22 -0
  26. data/lib/cmdx/deprecators/log.rb +22 -0
  27. data/lib/cmdx/deprecators/warn.rb +21 -0
  28. data/lib/cmdx/deprecators.rb +101 -0
  29. data/lib/cmdx/errors.rb +145 -79
  30. data/lib/cmdx/executors/fiber.rb +42 -0
  31. data/lib/cmdx/executors/thread.rb +36 -0
  32. data/lib/cmdx/executors.rb +95 -0
  33. data/lib/cmdx/fault.rb +85 -78
  34. data/lib/cmdx/i18n_proxy.rb +104 -0
  35. data/lib/cmdx/input.rb +294 -0
  36. data/lib/cmdx/inputs.rb +218 -0
  37. data/lib/cmdx/log_formatters/json.rb +9 -20
  38. data/lib/cmdx/log_formatters/key_value.rb +10 -21
  39. data/lib/cmdx/log_formatters/line.rb +7 -19
  40. data/lib/cmdx/log_formatters/logstash.rb +8 -21
  41. data/lib/cmdx/log_formatters/raw.rb +8 -20
  42. data/lib/cmdx/logger_proxy.rb +30 -0
  43. data/lib/cmdx/mergers/deep_merge.rb +23 -0
  44. data/lib/cmdx/mergers/last_write_wins.rb +23 -0
  45. data/lib/cmdx/mergers/no_merge.rb +20 -0
  46. data/lib/cmdx/mergers.rb +95 -0
  47. data/lib/cmdx/middlewares.rb +128 -0
  48. data/lib/cmdx/output.rb +115 -0
  49. data/lib/cmdx/outputs.rb +66 -0
  50. data/lib/cmdx/pipeline.rb +144 -131
  51. data/lib/cmdx/railtie.rb +10 -36
  52. data/lib/cmdx/result.rb +252 -473
  53. data/lib/cmdx/retriers/bounded_random.rb +24 -0
  54. data/lib/cmdx/retriers/decorrelated_jitter.rb +28 -0
  55. data/lib/cmdx/retriers/exponential.rb +23 -0
  56. data/lib/cmdx/retriers/fibonacci.rb +39 -0
  57. data/lib/cmdx/retriers/full_random.rb +23 -0
  58. data/lib/cmdx/retriers/half_random.rb +24 -0
  59. data/lib/cmdx/retriers/linear.rb +23 -0
  60. data/lib/cmdx/retriers.rb +106 -0
  61. data/lib/cmdx/retry.rb +117 -138
  62. data/lib/cmdx/runtime.rb +251 -0
  63. data/lib/cmdx/settings.rb +68 -196
  64. data/lib/cmdx/signal.rb +165 -0
  65. data/lib/cmdx/task.rb +443 -336
  66. data/lib/cmdx/telemetry.rb +108 -0
  67. data/lib/cmdx/util.rb +73 -0
  68. data/lib/cmdx/validators/absence.rb +10 -39
  69. data/lib/cmdx/validators/exclusion.rb +33 -52
  70. data/lib/cmdx/validators/format.rb +19 -49
  71. data/lib/cmdx/validators/inclusion.rb +33 -54
  72. data/lib/cmdx/validators/length.rb +125 -127
  73. data/lib/cmdx/validators/numeric.rb +123 -123
  74. data/lib/cmdx/validators/presence.rb +10 -39
  75. data/lib/cmdx/validators/validate.rb +31 -0
  76. data/lib/cmdx/validators.rb +161 -0
  77. data/lib/cmdx/version.rb +2 -4
  78. data/lib/cmdx/workflow.rb +74 -82
  79. data/lib/cmdx.rb +111 -42
  80. data/lib/generators/cmdx/install_generator.rb +7 -17
  81. data/lib/generators/cmdx/task_generator.rb +12 -29
  82. data/lib/generators/cmdx/templates/install.rb +128 -52
  83. data/lib/generators/cmdx/templates/task.rb.tt +1 -1
  84. data/lib/generators/cmdx/templates/workflow.rb.tt +1 -2
  85. data/lib/generators/cmdx/workflow_generator.rb +12 -29
  86. data/lib/locales/en.yml +9 -6
  87. data/mkdocs.yml +25 -23
  88. metadata +39 -138
  89. data/lib/cmdx/attribute.rb +0 -440
  90. data/lib/cmdx/attribute_registry.rb +0 -185
  91. data/lib/cmdx/attribute_value.rb +0 -252
  92. data/lib/cmdx/callback_registry.rb +0 -169
  93. data/lib/cmdx/coercion_registry.rb +0 -138
  94. data/lib/cmdx/deprecator.rb +0 -77
  95. data/lib/cmdx/exception.rb +0 -46
  96. data/lib/cmdx/executor.rb +0 -374
  97. data/lib/cmdx/identifier.rb +0 -30
  98. data/lib/cmdx/locale.rb +0 -78
  99. data/lib/cmdx/middleware_registry.rb +0 -148
  100. data/lib/cmdx/middlewares/correlate.rb +0 -140
  101. data/lib/cmdx/middlewares/runtime.rb +0 -62
  102. data/lib/cmdx/middlewares/timeout.rb +0 -78
  103. data/lib/cmdx/parallelizer.rb +0 -100
  104. data/lib/cmdx/utils/call.rb +0 -53
  105. data/lib/cmdx/utils/condition.rb +0 -71
  106. data/lib/cmdx/utils/format.rb +0 -82
  107. data/lib/cmdx/utils/normalize.rb +0 -52
  108. data/lib/cmdx/utils/wrap.rb +0 -38
  109. data/lib/cmdx/validator_registry.rb +0 -143
  110. data/lib/generators/cmdx/locale_generator.rb +0 -39
  111. data/lib/locales/af.yml +0 -53
  112. data/lib/locales/ar.yml +0 -53
  113. data/lib/locales/az.yml +0 -53
  114. data/lib/locales/be.yml +0 -53
  115. data/lib/locales/bg.yml +0 -53
  116. data/lib/locales/bn.yml +0 -53
  117. data/lib/locales/bs.yml +0 -53
  118. data/lib/locales/ca.yml +0 -53
  119. data/lib/locales/cnr.yml +0 -53
  120. data/lib/locales/cs.yml +0 -53
  121. data/lib/locales/cy.yml +0 -53
  122. data/lib/locales/da.yml +0 -53
  123. data/lib/locales/de.yml +0 -53
  124. data/lib/locales/dz.yml +0 -53
  125. data/lib/locales/el.yml +0 -53
  126. data/lib/locales/eo.yml +0 -53
  127. data/lib/locales/es.yml +0 -53
  128. data/lib/locales/et.yml +0 -53
  129. data/lib/locales/eu.yml +0 -53
  130. data/lib/locales/fa.yml +0 -53
  131. data/lib/locales/fi.yml +0 -53
  132. data/lib/locales/fr.yml +0 -53
  133. data/lib/locales/fy.yml +0 -53
  134. data/lib/locales/gd.yml +0 -53
  135. data/lib/locales/gl.yml +0 -53
  136. data/lib/locales/he.yml +0 -53
  137. data/lib/locales/hi.yml +0 -53
  138. data/lib/locales/hr.yml +0 -53
  139. data/lib/locales/hu.yml +0 -53
  140. data/lib/locales/hy.yml +0 -53
  141. data/lib/locales/id.yml +0 -53
  142. data/lib/locales/is.yml +0 -53
  143. data/lib/locales/it.yml +0 -53
  144. data/lib/locales/ja.yml +0 -53
  145. data/lib/locales/ka.yml +0 -53
  146. data/lib/locales/kk.yml +0 -53
  147. data/lib/locales/km.yml +0 -53
  148. data/lib/locales/kn.yml +0 -53
  149. data/lib/locales/ko.yml +0 -53
  150. data/lib/locales/lb.yml +0 -53
  151. data/lib/locales/lo.yml +0 -53
  152. data/lib/locales/lt.yml +0 -53
  153. data/lib/locales/lv.yml +0 -53
  154. data/lib/locales/mg.yml +0 -53
  155. data/lib/locales/mk.yml +0 -53
  156. data/lib/locales/ml.yml +0 -53
  157. data/lib/locales/mn.yml +0 -53
  158. data/lib/locales/mr-IN.yml +0 -53
  159. data/lib/locales/ms.yml +0 -53
  160. data/lib/locales/nb.yml +0 -53
  161. data/lib/locales/ne.yml +0 -53
  162. data/lib/locales/nl.yml +0 -53
  163. data/lib/locales/nn.yml +0 -53
  164. data/lib/locales/oc.yml +0 -53
  165. data/lib/locales/or.yml +0 -53
  166. data/lib/locales/pa.yml +0 -53
  167. data/lib/locales/pl.yml +0 -53
  168. data/lib/locales/pt.yml +0 -53
  169. data/lib/locales/rm.yml +0 -53
  170. data/lib/locales/ro.yml +0 -53
  171. data/lib/locales/ru.yml +0 -53
  172. data/lib/locales/sc.yml +0 -53
  173. data/lib/locales/sk.yml +0 -53
  174. data/lib/locales/sl.yml +0 -53
  175. data/lib/locales/sq.yml +0 -53
  176. data/lib/locales/sr.yml +0 -53
  177. data/lib/locales/st.yml +0 -53
  178. data/lib/locales/sv.yml +0 -53
  179. data/lib/locales/sw.yml +0 -53
  180. data/lib/locales/ta.yml +0 -53
  181. data/lib/locales/te.yml +0 -53
  182. data/lib/locales/th.yml +0 -53
  183. data/lib/locales/tl.yml +0 -53
  184. data/lib/locales/tr.yml +0 -53
  185. data/lib/locales/tt.yml +0 -53
  186. data/lib/locales/ug.yml +0 -53
  187. data/lib/locales/uk.yml +0 -53
  188. data/lib/locales/ur.yml +0 -53
  189. data/lib/locales/uz.yml +0 -53
  190. data/lib/locales/vi.yml +0 -53
  191. data/lib/locales/wo.yml +0 -53
  192. data/lib/locales/zh-CN.yml +0 -53
  193. data/lib/locales/zh-HK.yml +0 -53
  194. data/lib/locales/zh-TW.yml +0 -53
  195. data/lib/locales/zh-YUE.yml +0 -53
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CMDx
4
+ # Internal halt token thrown by `success!`, `skip!`, `fail!`, and `throw!`
5
+ # from inside a Task's `work`. Runtime catches `Signal::TAG` and converts the
6
+ # payload into a {Result}. Not meant to be raised directly by user code.
7
+ #
8
+ # @see Runtime#perform_work
9
+ # @see Task#success!
10
+ # @see Task#fail!
11
+ class Signal
12
+
13
+ # `catch`/`throw` tag used by Runtime to intercept signal payloads.
14
+ TAG = :cmdx_signal
15
+
16
+ # All valid execution lifecycle states.
17
+ STATES = [
18
+ COMPLETE = "complete",
19
+ INTERRUPTED = "interrupted"
20
+ ].freeze
21
+ # All valid outcome statuses.
22
+ STATUSES = [
23
+ SUCCESS = "success",
24
+ SKIPPED = "skipped",
25
+ FAILED = "failed"
26
+ ].freeze
27
+
28
+ class << self
29
+
30
+ # Builds a successful signal (state `complete`, status `success`).
31
+ #
32
+ # @param reason [String, nil] optional human-readable reason
33
+ # @param options [Hash{Symbol => Object}] optional `:metadata`, `:cause`, `:backtrace`
34
+ # @option options [Hash{Symbol => Object}] :metadata merged onto the task metadata payload
35
+ # @option options [Exception] :cause upstream exception when mirroring failures
36
+ # @option options [Array<Thread::Backtrace::Location>] :backtrace captured frames
37
+ # @return [Signal] new instance with frozen options
38
+ def success(reason = nil, **options)
39
+ new(COMPLETE, SUCCESS, **options, reason:)
40
+ end
41
+
42
+ # Builds a skipped signal (state `interrupted`, status `skipped`).
43
+ #
44
+ # @param reason [String, nil] optional human-readable reason
45
+ # @param options [Hash{Symbol => Object}] optional `:metadata`, `:cause`, `:backtrace`
46
+ # @option options [Hash{Symbol => Object}] :metadata merged onto the task metadata payload
47
+ # @option options [Exception] :cause upstream exception when mirroring failures
48
+ # @option options [Array<Thread::Backtrace::Location>] :backtrace captured frames
49
+ # @return [Signal] new instance with frozen options
50
+ def skipped(reason = nil, **options)
51
+ new(INTERRUPTED, SKIPPED, **options, reason:)
52
+ end
53
+
54
+ # Builds a failed signal (state `interrupted`, status `failed`).
55
+ #
56
+ # @param reason [String, nil] optional human-readable reason
57
+ # @param options [Hash{Symbol => Object}] optional `:metadata`, `:cause`, `:backtrace`
58
+ # @option options [Hash{Symbol => Object}] :metadata merged onto the task metadata payload
59
+ # @option options [Exception] :cause upstream exception when mirroring failures
60
+ # @option options [Array<Thread::Backtrace::Location>] :backtrace captured frames
61
+ # @return [Signal] new instance with frozen options
62
+ def failed(reason = nil, **options)
63
+ new(INTERRUPTED, FAILED, **options, reason:)
64
+ end
65
+
66
+ # Mirrors another Signal/Result's state + status with fresh options.
67
+ # Used by Runtime to propagate a nested `Fault`'s outcome.
68
+ #
69
+ # @param other [Signal, Result] source to mirror state/status/reason from
70
+ # @param options [Hash{Symbol => Object}] overrides: `:metadata`, `:cause`,
71
+ # `:backtrace`, `:origin`
72
+ # @option options [Hash{Symbol => Object}] :metadata merged onto the task metadata payload
73
+ # @option options [Exception] :cause upstream exception when mirroring failures
74
+ # @option options [Array<Thread::Backtrace::Location>] :backtrace captured frames
75
+ # @option options [Result] :origin peer result this signal echoes (set automatically for Results)
76
+ # @return [Signal] new instance mirroring `other`
77
+ # @raise [ArgumentError] when `other` is neither a Signal nor a Result
78
+ def echoed(other, **options)
79
+ raise ArgumentError, "must be a Result or Signal" unless other.is_a?(Result) || other.is_a?(Signal)
80
+
81
+ options[:origin] = other if other.is_a?(Result) && !options.key?(:origin)
82
+ new(other.state, other.status, **options, reason: other.reason)
83
+ end
84
+
85
+ end
86
+
87
+ attr_reader :state, :status
88
+
89
+ # @param state [String] one of {STATES}
90
+ # @param status [String] one of {STATUSES}
91
+ # @param options [Hash{Symbol => Object}] frozen metadata payload
92
+ # @option options [String] :reason
93
+ # @option options [Hash] :metadata
94
+ # @option options [Exception] :cause
95
+ # @option options [Result] :origin
96
+ # @option options [Array<Thread::Backtrace::Location>] :backtrace
97
+ def initialize(state, status, **options)
98
+ @state = state
99
+ @status = status
100
+ @options = options.freeze
101
+ end
102
+
103
+ # @return [Boolean] true when the task ran to completion without interruption
104
+ def complete?
105
+ state == COMPLETE
106
+ end
107
+
108
+ # @return [Boolean] true when skip/fail interrupted the task
109
+ def interrupted?
110
+ state == INTERRUPTED
111
+ end
112
+
113
+ # @return [Boolean]
114
+ def success?
115
+ status == SUCCESS
116
+ end
117
+
118
+ # @return [Boolean]
119
+ def skipped?
120
+ status == SKIPPED
121
+ end
122
+
123
+ # @return [Boolean]
124
+ def failed?
125
+ status == FAILED
126
+ end
127
+
128
+ # @return [Boolean] true for success or skipped (anything but failed)
129
+ def ok?
130
+ !failed?
131
+ end
132
+
133
+ # @return [Boolean] true for skipped or failed (anything but success)
134
+ def ko?
135
+ !success?
136
+ end
137
+
138
+ # @return [String, nil] human-readable explanation supplied by the caller
139
+ def reason
140
+ @options[:reason]
141
+ end
142
+
143
+ # @return [Hash{Symbol => Object}] frozen-empty hash when none was provided
144
+ def metadata
145
+ @options[:metadata] || EMPTY_HASH
146
+ end
147
+
148
+ # @return [Exception, nil] underlying exception when a rescue produced this signal
149
+ def cause
150
+ @options[:cause]
151
+ end
152
+
153
+ # @return [Result, nil] upstream result this signal was echoed from, when any
154
+ def origin
155
+ @options[:origin]
156
+ end
157
+
158
+ # @return [Array<Thread::Backtrace::Location>, nil] caller locations captured
159
+ # by `fail!` / `throw!` for Fault backtraces
160
+ def backtrace
161
+ @options[:backtrace]
162
+ end
163
+
164
+ end
165
+ end