cmdx 1.17.0 → 1.19.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 +19 -1
- data/lib/cmdx/attribute.rb +10 -5
- data/lib/cmdx/attribute_value.rb +12 -2
- data/lib/cmdx/chain.rb +34 -9
- data/lib/cmdx/coercions/array.rb +6 -1
- data/lib/cmdx/coercions/boolean.rb +5 -1
- data/lib/cmdx/coercions/date.rb +1 -6
- data/lib/cmdx/coercions/date_time.rb +1 -6
- data/lib/cmdx/coercions/integer.rb +3 -4
- data/lib/cmdx/coercions/time.rb +0 -6
- data/lib/cmdx/executor.rb +3 -3
- data/lib/cmdx/middlewares/correlate.rb +23 -12
- data/lib/cmdx/task.rb +20 -7
- data/lib/cmdx/validator_registry.rb +1 -1
- data/lib/cmdx/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ead1d181ed1eac565ea3287eeaaca3216e5d24a40f4071000539584435fc1327
|
|
4
|
+
data.tar.gz: ba0273c00286e10621f06fc5b0ba7be760afa99dd8d3fbfc6fc7da1c3c11891f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30e8c09228e765f2ac8e9b4f8db854da21a13e3a2d7e67b9ad61ecad66d09dd7f8ca9327ac9a8ef8777e78d56d5844a06f52e55d282cc1d78d7ddb9141b9acc2
|
|
7
|
+
data.tar.gz: 922de5ad8342195dc94bf8137e7023612db4df09b3979581c0e77aecf599cae971004e64b9ab71261ea6795feb8ca8b7fe3fe4fc3f37a570ed50157c404aff33
|
data/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,25 @@ 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
|
-
## [
|
|
7
|
+
## [UNRELEASED]
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Add attribute `source` fallback to `:context` when no task is given
|
|
11
|
+
- Improve falsy attribute derived Hash value lookup
|
|
12
|
+
- Freeze chain results
|
|
13
|
+
- Fix missing fault cause no method error issue
|
|
14
|
+
- Add context respond_to? with setter methods
|
|
15
|
+
- Fix validator `allow_nil` inverted logic
|
|
16
|
+
- Array coercion JSON parse error no returns CoercionError
|
|
17
|
+
- Boolean coercions now return `false` for `nil` and `""`
|
|
18
|
+
- Coerce anaglous date, datetime, and time class checks to rely on `to_date`, `to_time`, `to_datetime` methods
|
|
19
|
+
|
|
20
|
+
## [1.18.0] - 2025-03-09
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Use `Fiber.storage` instead of `Thread.current` for `Chain` and `Correlate` storage, with fallback to `Thread.current` for Ruby < 3.2, making them thread and fiber safe
|
|
24
|
+
- Clone shared logger in `Task#logger` when `log_level` or `log_formatter` is customized to prevent mutation of the shared instance
|
|
25
|
+
- Derive attribute values from source objects that respond to the attribute name (via `send`) as fallback when the source is not callable
|
|
8
26
|
|
|
9
27
|
## [1.17.0] - 2025-02-23
|
|
10
28
|
|
data/lib/cmdx/attribute.rb
CHANGED
|
@@ -208,7 +208,8 @@ module CMDx
|
|
|
208
208
|
!!@required
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
-
# Determines the source of the attribute value.
|
|
211
|
+
# Determines the source of the attribute value. Returns :context
|
|
212
|
+
# as a safe fallback when task is not yet set (e.g., schema introspection).
|
|
212
213
|
#
|
|
213
214
|
# @return [Symbol] The source identifier for the attribute value
|
|
214
215
|
#
|
|
@@ -217,13 +218,15 @@ module CMDx
|
|
|
217
218
|
#
|
|
218
219
|
# @rbs () -> untyped
|
|
219
220
|
def source
|
|
220
|
-
@source
|
|
221
|
+
return @source if defined?(@source)
|
|
222
|
+
|
|
223
|
+
@source = parent&.method_name || begin
|
|
221
224
|
value = options[:source]
|
|
222
225
|
|
|
223
226
|
if value.is_a?(Proc)
|
|
224
|
-
task.instance_eval(&value)
|
|
227
|
+
task ? task.instance_eval(&value) : :context
|
|
225
228
|
elsif value.respond_to?(:call)
|
|
226
|
-
value.call(task)
|
|
229
|
+
task ? value.call(task) : :context
|
|
227
230
|
else
|
|
228
231
|
value || :context
|
|
229
232
|
end
|
|
@@ -239,7 +242,9 @@ module CMDx
|
|
|
239
242
|
#
|
|
240
243
|
# @rbs () -> Symbol
|
|
241
244
|
def method_name
|
|
242
|
-
@method_name
|
|
245
|
+
return @method_name if defined?(@method_name)
|
|
246
|
+
|
|
247
|
+
@method_name = options[:as] || begin
|
|
243
248
|
prefix = AFFIX.call(options[:prefix]) { "#{source}_" }
|
|
244
249
|
suffix = AFFIX.call(options[:suffix]) { "_#{source}" }
|
|
245
250
|
|
data/lib/cmdx/attribute_value.rb
CHANGED
|
@@ -166,10 +166,20 @@ module CMDx
|
|
|
166
166
|
derived_value =
|
|
167
167
|
case source_value
|
|
168
168
|
when Context then source_value[name]
|
|
169
|
-
when Hash
|
|
169
|
+
when Hash
|
|
170
|
+
if source_value.key?(name.to_s)
|
|
171
|
+
source_value[name.to_s]
|
|
172
|
+
elsif source_value.key?(name.to_sym)
|
|
173
|
+
source_value[name.to_sym]
|
|
174
|
+
end
|
|
170
175
|
when Symbol then source_value.send(name)
|
|
171
176
|
when Proc then task.instance_exec(name, &source_value)
|
|
172
|
-
else
|
|
177
|
+
else
|
|
178
|
+
if source_value.respond_to?(:call)
|
|
179
|
+
source_value.call(task, name)
|
|
180
|
+
elsif source_value.respond_to?(name, true)
|
|
181
|
+
source_value.send(name)
|
|
182
|
+
end
|
|
173
183
|
end
|
|
174
184
|
|
|
175
185
|
derived_value.nil? ? default_value : derived_value
|
data/lib/cmdx/chain.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module CMDx
|
|
4
|
-
# Manages a collection of task execution results in a thread
|
|
4
|
+
# Manages a collection of task execution results in a thread and fiber safe manner.
|
|
5
5
|
# Chains provide a way to track related task executions and their outcomes
|
|
6
6
|
# within the same execution context.
|
|
7
7
|
class Chain
|
|
8
8
|
|
|
9
9
|
extend Forwardable
|
|
10
10
|
|
|
11
|
-
# @rbs
|
|
12
|
-
|
|
11
|
+
# @rbs CONCURRENCY_KEY: Symbol
|
|
12
|
+
CONCURRENCY_KEY = :cmdx_chain
|
|
13
13
|
|
|
14
14
|
# Returns the unique identifier for this chain.
|
|
15
15
|
#
|
|
@@ -47,7 +47,7 @@ module CMDx
|
|
|
47
47
|
|
|
48
48
|
class << self
|
|
49
49
|
|
|
50
|
-
# Retrieves the current chain for the current
|
|
50
|
+
# Retrieves the current chain for the current execution context.
|
|
51
51
|
#
|
|
52
52
|
# @return [Chain, nil] The current chain or nil if none exists
|
|
53
53
|
#
|
|
@@ -59,10 +59,10 @@ module CMDx
|
|
|
59
59
|
#
|
|
60
60
|
# @rbs () -> Chain?
|
|
61
61
|
def current
|
|
62
|
-
|
|
62
|
+
thread_or_fiber[CONCURRENCY_KEY]
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
# Sets the current chain for the current
|
|
65
|
+
# Sets the current chain for the current execution context.
|
|
66
66
|
#
|
|
67
67
|
# @param chain [Chain] The chain to set as current
|
|
68
68
|
#
|
|
@@ -73,10 +73,10 @@ module CMDx
|
|
|
73
73
|
#
|
|
74
74
|
# @rbs (Chain chain) -> Chain
|
|
75
75
|
def current=(chain)
|
|
76
|
-
|
|
76
|
+
thread_or_fiber[CONCURRENCY_KEY] = chain
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
# Clears the current chain for the current
|
|
79
|
+
# Clears the current chain for the current execution context.
|
|
80
80
|
#
|
|
81
81
|
# @return [nil] Always returns nil
|
|
82
82
|
#
|
|
@@ -85,7 +85,7 @@ module CMDx
|
|
|
85
85
|
#
|
|
86
86
|
# @rbs () -> nil
|
|
87
87
|
def clear
|
|
88
|
-
|
|
88
|
+
thread_or_fiber[CONCURRENCY_KEY] = nil
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
# Builds or extends the current chain by adding a result.
|
|
@@ -111,6 +111,17 @@ module CMDx
|
|
|
111
111
|
current
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
# Returns the thread or fiber storage for the current execution context.
|
|
117
|
+
#
|
|
118
|
+
# @return [Hash] The thread or fiber storage
|
|
119
|
+
#
|
|
120
|
+
# @rbs () -> Hash
|
|
121
|
+
def thread_or_fiber
|
|
122
|
+
Fiber.respond_to?(:storage) ? Fiber.storage : Thread.current
|
|
123
|
+
end
|
|
124
|
+
|
|
114
125
|
end
|
|
115
126
|
|
|
116
127
|
# Returns whether the chain is running in dry-run mode.
|
|
@@ -125,6 +136,20 @@ module CMDx
|
|
|
125
136
|
!!@dry_run
|
|
126
137
|
end
|
|
127
138
|
|
|
139
|
+
# Freezes the chain and its internal results to prevent modifications.
|
|
140
|
+
#
|
|
141
|
+
# @return [Chain] the frozen chain
|
|
142
|
+
#
|
|
143
|
+
# @example
|
|
144
|
+
# chain.freeze
|
|
145
|
+
# chain.results << result # => raises FrozenError
|
|
146
|
+
#
|
|
147
|
+
# @rbs () -> self
|
|
148
|
+
def freeze
|
|
149
|
+
results.freeze
|
|
150
|
+
super
|
|
151
|
+
end
|
|
152
|
+
|
|
128
153
|
# Converts the chain to a hash representation.
|
|
129
154
|
#
|
|
130
155
|
# @option return [String] :id The chain identifier
|
data/lib/cmdx/coercions/array.rb
CHANGED
|
@@ -18,7 +18,7 @@ module CMDx
|
|
|
18
18
|
#
|
|
19
19
|
# @return [Array] The converted array value
|
|
20
20
|
#
|
|
21
|
-
# @raise [
|
|
21
|
+
# @raise [CoercionError] If the value cannot be converted to an array
|
|
22
22
|
#
|
|
23
23
|
# @example Convert a JSON-like string to an array
|
|
24
24
|
# Array.call("[1, 2, 3]") # => [1, 2, 3]
|
|
@@ -26,6 +26,8 @@ module CMDx
|
|
|
26
26
|
# Array.call("hello") # => ["hello"]
|
|
27
27
|
# Array.call(42) # => [42]
|
|
28
28
|
# Array.call(nil) # => []
|
|
29
|
+
# @example Handle invalid JSON-like strings
|
|
30
|
+
# Array.call("[not json") # => raises CoercionError
|
|
29
31
|
#
|
|
30
32
|
# @rbs (untyped value, ?Hash[Symbol, untyped] options) -> Array[untyped]
|
|
31
33
|
def call(value, options = {})
|
|
@@ -37,6 +39,9 @@ module CMDx
|
|
|
37
39
|
else
|
|
38
40
|
Array(value)
|
|
39
41
|
end
|
|
42
|
+
rescue JSON::ParserError
|
|
43
|
+
type = Locale.t("cmdx.types.array")
|
|
44
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_an", type:)
|
|
40
45
|
end
|
|
41
46
|
|
|
42
47
|
end
|
|
@@ -34,14 +34,18 @@ module CMDx
|
|
|
34
34
|
# Boolean.call("false") # => false
|
|
35
35
|
# Boolean.call("no") # => false
|
|
36
36
|
# Boolean.call("0") # => false
|
|
37
|
+
# Boolean.call(nil) # => false
|
|
38
|
+
# Boolean.call("") # => false
|
|
37
39
|
# @example Handle case-insensitive input
|
|
38
40
|
# Boolean.call("TRUE") # => true
|
|
39
41
|
# Boolean.call("False") # => false
|
|
42
|
+
# @example Handle edge cases
|
|
43
|
+
# Boolean.call("abc") # => raises CoercionError
|
|
40
44
|
#
|
|
41
45
|
# @rbs (untyped value, ?Hash[Symbol, untyped] options) -> bool
|
|
42
46
|
def call(value, options = {})
|
|
43
47
|
case value.to_s
|
|
44
|
-
when FALSEY then false
|
|
48
|
+
when FALSEY, "" then false
|
|
45
49
|
when TRUTHY then true
|
|
46
50
|
else
|
|
47
51
|
type = Locale.t("cmdx.types.boolean")
|
data/lib/cmdx/coercions/date.rb
CHANGED
|
@@ -11,11 +11,6 @@ module CMDx
|
|
|
11
11
|
|
|
12
12
|
extend self
|
|
13
13
|
|
|
14
|
-
# Types that are already date-like and don't need conversion
|
|
15
|
-
#
|
|
16
|
-
# @rbs ANALOG_TYPES: Array[String]
|
|
17
|
-
ANALOG_TYPES = %w[Date DateTime Time].freeze
|
|
18
|
-
|
|
19
14
|
# Converts a value to a Date object
|
|
20
15
|
#
|
|
21
16
|
# @param value [Object] The value to convert to a Date
|
|
@@ -38,7 +33,7 @@ module CMDx
|
|
|
38
33
|
#
|
|
39
34
|
# @rbs (untyped value, ?Hash[Symbol, untyped] options) -> Date
|
|
40
35
|
def call(value, options = {})
|
|
41
|
-
return value if
|
|
36
|
+
return value.to_date if value.respond_to?(:to_date)
|
|
42
37
|
return ::Date.strptime(value, options[:strptime]) if options[:strptime]
|
|
43
38
|
|
|
44
39
|
::Date.parse(value)
|
|
@@ -11,11 +11,6 @@ module CMDx
|
|
|
11
11
|
|
|
12
12
|
extend self
|
|
13
13
|
|
|
14
|
-
# Types that are already date-time-like and don't need conversion
|
|
15
|
-
#
|
|
16
|
-
# @rbs ANALOG_TYPES: Array[String]
|
|
17
|
-
ANALOG_TYPES = %w[Date DateTime Time].freeze
|
|
18
|
-
|
|
19
14
|
# Converts a value to a DateTime
|
|
20
15
|
#
|
|
21
16
|
# @param value [Object] The value to convert to DateTime
|
|
@@ -38,7 +33,7 @@ module CMDx
|
|
|
38
33
|
#
|
|
39
34
|
# @rbs (untyped value, ?Hash[Symbol, untyped] options) -> DateTime
|
|
40
35
|
def call(value, options = {})
|
|
41
|
-
return value if
|
|
36
|
+
return value.to_datetime if value.respond_to?(:to_datetime)
|
|
42
37
|
return ::DateTime.strptime(value, options[:strptime]) if options[:strptime]
|
|
43
38
|
|
|
44
39
|
::DateTime.parse(value)
|
|
@@ -30,10 +30,9 @@ module CMDx
|
|
|
30
30
|
# Integer.call(3.14) # => 3
|
|
31
31
|
# Integer.call(0.0) # => 0
|
|
32
32
|
# @example Handle edge cases
|
|
33
|
-
# Integer.call("") # =>
|
|
34
|
-
# Integer.call(nil) # =>
|
|
35
|
-
# Integer.call(
|
|
36
|
-
# Integer.call(true) # => 1
|
|
33
|
+
# Integer.call("") # => raises CoercionError
|
|
34
|
+
# Integer.call(nil) # => raises CoercionError
|
|
35
|
+
# Integer.call("abc") # => raises CoercionError
|
|
37
36
|
#
|
|
38
37
|
# @rbs (untyped value, ?Hash[Symbol, untyped] options) -> Integer
|
|
39
38
|
def call(value, options = {})
|
data/lib/cmdx/coercions/time.rb
CHANGED
|
@@ -11,11 +11,6 @@ module CMDx
|
|
|
11
11
|
|
|
12
12
|
extend self
|
|
13
13
|
|
|
14
|
-
# Types that are already time-like and don't need conversion
|
|
15
|
-
#
|
|
16
|
-
# @rbs ANALOG_TYPES: Array[String]
|
|
17
|
-
ANALOG_TYPES = %w[DateTime Time].freeze
|
|
18
|
-
|
|
19
14
|
# Converts a value to a Time object
|
|
20
15
|
#
|
|
21
16
|
# @param value [Object] The value to convert to a Time object
|
|
@@ -40,7 +35,6 @@ module CMDx
|
|
|
40
35
|
#
|
|
41
36
|
# @rbs (untyped value, ?Hash[Symbol, untyped] options) -> Time
|
|
42
37
|
def call(value, options = {})
|
|
43
|
-
return value if ANALOG_TYPES.include?(value.class.name)
|
|
44
38
|
return value.to_time if value.respond_to?(:to_time)
|
|
45
39
|
return ::Time.strptime(value, options[:strptime]) if options[:strptime]
|
|
46
40
|
|
data/lib/cmdx/executor.rb
CHANGED
|
@@ -169,7 +169,7 @@ module CMDx
|
|
|
169
169
|
jitter.to_f * current_retry
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
-
sleep(jitter) if jitter.positive?
|
|
172
|
+
sleep(jitter) if Float(jitter).positive?
|
|
173
173
|
|
|
174
174
|
true
|
|
175
175
|
end
|
|
@@ -291,8 +291,8 @@ module CMDx
|
|
|
291
291
|
def log_backtrace!
|
|
292
292
|
return unless result.failed?
|
|
293
293
|
|
|
294
|
-
exception = result.caused_failure
|
|
295
|
-
return if exception.is_a?(Fault)
|
|
294
|
+
exception = result.caused_failure&.cause
|
|
295
|
+
return if exception.nil? || exception.is_a?(Fault)
|
|
296
296
|
|
|
297
297
|
task.logger.error do
|
|
298
298
|
"[#{exception.class}] #{exception.message}\n" <<
|
|
@@ -4,18 +4,18 @@ module CMDx
|
|
|
4
4
|
module Middlewares
|
|
5
5
|
# Middleware for correlating task executions with unique identifiers.
|
|
6
6
|
#
|
|
7
|
-
# The Correlate middleware provides thread
|
|
8
|
-
# for tracking task execution flows across different operations.
|
|
9
|
-
#
|
|
10
|
-
#
|
|
7
|
+
# The Correlate middleware provides thread and fiber safe correlation ID management
|
|
8
|
+
# for tracking task execution flows across different operations. It automatically
|
|
9
|
+
# generates correlation IDs when none are provided and stores them in task result
|
|
10
|
+
# metadata for traceability.
|
|
11
11
|
module Correlate
|
|
12
12
|
|
|
13
13
|
extend self
|
|
14
14
|
|
|
15
|
-
# @rbs
|
|
16
|
-
|
|
15
|
+
# @rbs CONCURRENCY_KEY: Symbol
|
|
16
|
+
CONCURRENCY_KEY = :cmdx_correlate
|
|
17
17
|
|
|
18
|
-
# Retrieves the current correlation ID from
|
|
18
|
+
# Retrieves the current correlation ID from local storage.
|
|
19
19
|
#
|
|
20
20
|
# @return [String, nil] The current correlation ID or nil if not set
|
|
21
21
|
#
|
|
@@ -24,10 +24,10 @@ module CMDx
|
|
|
24
24
|
#
|
|
25
25
|
# @rbs () -> String?
|
|
26
26
|
def id
|
|
27
|
-
|
|
27
|
+
thread_or_fiber[CONCURRENCY_KEY]
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
# Sets the correlation ID in
|
|
30
|
+
# Sets the correlation ID in local storage.
|
|
31
31
|
#
|
|
32
32
|
# @param id [String] The correlation ID to set
|
|
33
33
|
# @return [String] The set correlation ID
|
|
@@ -37,10 +37,10 @@ module CMDx
|
|
|
37
37
|
#
|
|
38
38
|
# @rbs (String id) -> String
|
|
39
39
|
def id=(id)
|
|
40
|
-
|
|
40
|
+
thread_or_fiber[CONCURRENCY_KEY] = id
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
# Clears the current correlation ID from
|
|
43
|
+
# Clears the current correlation ID from local storage.
|
|
44
44
|
#
|
|
45
45
|
# @return [nil] Always returns nil
|
|
46
46
|
#
|
|
@@ -49,7 +49,7 @@ module CMDx
|
|
|
49
49
|
#
|
|
50
50
|
# @rbs () -> nil
|
|
51
51
|
def clear
|
|
52
|
-
|
|
52
|
+
thread_or_fiber[CONCURRENCY_KEY] = nil
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
# Temporarily uses a new correlation ID for the duration of a block.
|
|
@@ -122,6 +122,17 @@ module CMDx
|
|
|
122
122
|
use(correlation_id, &)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
# Returns the thread or fiber storage for the current execution context.
|
|
128
|
+
#
|
|
129
|
+
# @return [Hash] The thread or fiber storage
|
|
130
|
+
#
|
|
131
|
+
# @rbs () -> Hash
|
|
132
|
+
def thread_or_fiber
|
|
133
|
+
Fiber.respond_to?(:storage) ? Fiber.storage : Thread.current
|
|
134
|
+
end
|
|
135
|
+
|
|
125
136
|
end
|
|
126
137
|
end
|
|
127
138
|
end
|
data/lib/cmdx/task.rb
CHANGED
|
@@ -95,7 +95,9 @@ module CMDx
|
|
|
95
95
|
@id = Identifier.generate
|
|
96
96
|
@context = Context.build(context)
|
|
97
97
|
@result = Result.new(self)
|
|
98
|
-
|
|
98
|
+
|
|
99
|
+
dry_run = @context.delete(:dry_run)
|
|
100
|
+
@chain = Chain.build(@result, dry_run:)
|
|
99
101
|
end
|
|
100
102
|
|
|
101
103
|
class << self
|
|
@@ -259,8 +261,8 @@ module CMDx
|
|
|
259
261
|
#
|
|
260
262
|
# @rbs () -> Hash[Symbol, Hash[Symbol, untyped]]
|
|
261
263
|
def attributes_schema
|
|
262
|
-
Array(settings[:attributes]).
|
|
263
|
-
|
|
264
|
+
Array(settings[:attributes]).to_h do |attr|
|
|
265
|
+
[attr.method_name, attr.to_h]
|
|
264
266
|
end
|
|
265
267
|
end
|
|
266
268
|
|
|
@@ -351,6 +353,10 @@ module CMDx
|
|
|
351
353
|
raise UndefinedMethodError, "undefined method #{self.class.name}#work"
|
|
352
354
|
end
|
|
353
355
|
|
|
356
|
+
# Returns a logger for this task. When a custom log_level or
|
|
357
|
+
# log_formatter is configured, the shared logger is duplicated
|
|
358
|
+
# so the original instance is never mutated.
|
|
359
|
+
#
|
|
354
360
|
# @return [Logger] The logger instance for this task
|
|
355
361
|
#
|
|
356
362
|
# @example
|
|
@@ -360,10 +366,17 @@ module CMDx
|
|
|
360
366
|
# @rbs () -> Logger
|
|
361
367
|
def logger
|
|
362
368
|
@logger ||= begin
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
369
|
+
log_instance = self.class.settings[:logger] || CMDx.configuration.logger
|
|
370
|
+
log_level = self.class.settings[:log_level]
|
|
371
|
+
log_formatter = self.class.settings[:log_formatter]
|
|
372
|
+
|
|
373
|
+
if log_level || log_formatter
|
|
374
|
+
log_instance = log_instance.dup
|
|
375
|
+
log_instance.level = log_level if log_level
|
|
376
|
+
log_instance.formatter = log_formatter if log_formatter
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
log_instance
|
|
367
380
|
end
|
|
368
381
|
end
|
|
369
382
|
|
data/lib/cmdx/version.rb
CHANGED
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.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Juan Gomez
|
|
@@ -420,7 +420,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
420
420
|
- !ruby/object:Gem::Version
|
|
421
421
|
version: '0'
|
|
422
422
|
requirements: []
|
|
423
|
-
rubygems_version: 4.0.
|
|
423
|
+
rubygems_version: 4.0.6
|
|
424
424
|
specification_version: 4
|
|
425
425
|
summary: CMDx is a framework for building maintainable business processes.
|
|
426
426
|
test_files: []
|