lite-command 3.1.5 → 3.2.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 +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +50 -99
- data/lib/lite/command/base.rb +2 -1
- data/lib/lite/command/internals/attributes.rb +3 -3
- data/lib/lite/command/internals/calls.rb +0 -2
- data/lib/lite/command/internals/executions.rb +9 -16
- data/lib/lite/command/internals/hooks.rb +51 -0
- data/lib/lite/command/version.rb +1 -1
- data/lib/lite/command.rb +1 -0
- 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: ecfaebe941a3ed585e42a5a43b361d60de38076b6a4254125722b13d57294885
|
4
|
+
data.tar.gz: da15660c9410a9c8797d6c322ab79797f800f5233319a7a39d6476bba10504ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b91f356964b41577a7e274a5cc5cf46c74b60a088ffa781e7c5f3cbf0f7bd7713accf16ddf8bee16e99342e04a0040ea8dab2fb8c5ff7eb3132d7e3000596ca0
|
7
|
+
data.tar.gz: d905466a1fe16049f5af3877c2488120eb581070fe85a9bf20654cf09127bcccc8e6e9a79c436f16164e3104d5fc7d1bd6bbb7b839069250d29cc4b551e8c47e
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [3.2.0] - 2024-10-29
|
10
|
+
### Changed
|
11
|
+
- Move callbacks to hooks instead of try methods
|
12
|
+
|
9
13
|
## [3.1.5] - 2024-10-28
|
10
14
|
### Changed
|
11
15
|
- Renamed private `delegate` method to `delegates` to prevent rails clash
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -33,10 +33,9 @@ Or install it yourself as:
|
|
33
33
|
* [States](#states)
|
34
34
|
* [Statuses](#statuses)
|
35
35
|
* [Hooks](#hooks)
|
36
|
-
* [
|
37
|
-
* [Attribute Hooks](#attribute-hooks)
|
38
|
-
* [Execution Hooks](#execution-hooks)
|
36
|
+
* [Lifecycle Hooks](#lifecycle-hooks)
|
39
37
|
* [Status Hooks](#status-hooks)
|
38
|
+
* [State Hooks](#state-hooks)
|
40
39
|
* [Children](#children)
|
41
40
|
* [Throwing Faults](#throwing-faults)
|
42
41
|
* [Sequences](#sequences)
|
@@ -143,6 +142,10 @@ cmd.raise!(original: true) #=> raises Lite::Command::Fault
|
|
143
142
|
# On exception:
|
144
143
|
cmd.raise!(original: false) #=> raises Lite::Command::Error
|
145
144
|
cmd.raise!(original: true) #=> raises StandardError
|
145
|
+
|
146
|
+
# Access the exception objects directly
|
147
|
+
cmd.original_exception #=> <StandardError ...>
|
148
|
+
cmd.command_exception #=> <Lite::Command::Error ...>
|
146
149
|
```
|
147
150
|
|
148
151
|
### Dynamic Faults
|
@@ -361,9 +364,6 @@ cmd.status #=> "invalid"
|
|
361
364
|
cmd.reason #=> "Invalid message start value"
|
362
365
|
cmd.metadata #=> { i18n: "gb.invalid_start_value" }
|
363
366
|
|
364
|
-
cmd.original_exception #=> <RuntimeError ...>
|
365
|
-
cmd.command_exception #=> <DecryptSecretMessage::Error ...>
|
366
|
-
|
367
367
|
cmd.success? #=> false
|
368
368
|
cmd.noop? #=> false
|
369
369
|
cmd.invalid? #=> true
|
@@ -387,140 +387,91 @@ cmd.bad?("Other reason") #=> false
|
|
387
387
|
## Hooks
|
388
388
|
|
389
389
|
Use hooks to run arbituary code at transition points and on finalized internals.
|
390
|
-
|
391
|
-
|
390
|
+
All hooks are ran in the order they are defined. Hooks types can be defined
|
391
|
+
multiple times. The following is an example of the hooks called for a failed
|
392
|
+
command with a successful child command.
|
392
393
|
|
393
394
|
```ruby
|
394
|
-
-> 1. FooCommand.
|
395
|
-
-> 2. FooCommand.
|
396
|
-
-> 3. FooCommand.
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
--->
|
401
|
-
--->
|
402
|
-
--->
|
403
|
-
|
404
|
-
|
405
|
-
|
395
|
+
-> 1. FooCommand.after_initialize
|
396
|
+
-> 2. FooCommand.on_pending
|
397
|
+
-> 3. FooCommand.before_validation
|
398
|
+
-> 4. FooCommand.after_validation
|
399
|
+
-> 5. FooCommand.before_execution
|
400
|
+
-> 6. FooCommand.on_executing
|
401
|
+
---> 6a. BarCommand.after_initialize
|
402
|
+
---> 6b. BarCommand.on_pending
|
403
|
+
---> 6c. BarCommand.before_validation
|
404
|
+
---> 6d. BarCommand.after_validation
|
405
|
+
---> 6e. BarCommand.before_execution
|
406
|
+
---> 6f. BarCommand.on_executing
|
407
|
+
---> 6g. BarCommand.after_execution
|
408
|
+
---> 6h. BarCommand.on_failure
|
409
|
+
---> 6i. BarCommand.on_interrupted
|
410
|
+
-> 7. FooCommand.after_execution
|
411
|
+
-> 8. FooCommand.on_failure
|
412
|
+
-> 9. FooCommand.on_interrupted
|
406
413
|
```
|
407
414
|
|
408
|
-
###
|
415
|
+
### Lifecycle Hooks
|
409
416
|
|
410
|
-
Define
|
417
|
+
Define before and after callbacks to call around execution.
|
411
418
|
|
412
419
|
```ruby
|
413
420
|
class DecryptSecretMessage < Lite::Command::Base
|
414
421
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
def on_pending
|
422
|
-
# eg: Append additional contextual data
|
423
|
-
end
|
424
|
-
|
425
|
-
def on_executing
|
426
|
-
# eg: Insert inspection debugger
|
427
|
-
end
|
428
|
-
|
429
|
-
def on_complete
|
430
|
-
# eg: Log message for posterity
|
431
|
-
end
|
432
|
-
|
433
|
-
def on_interrupted
|
434
|
-
# eg: Report to APM with tags and metadata
|
435
|
-
end
|
436
|
-
|
437
|
-
end
|
438
|
-
```
|
439
|
-
|
440
|
-
### Attribute Hooks
|
441
|
-
|
442
|
-
Define before attribtue validation callbacks.
|
443
|
-
|
444
|
-
```ruby
|
445
|
-
class DecryptSecretMessage < Lite::Command::Base
|
422
|
+
after_initialize :some_method
|
423
|
+
before_validation :some_method
|
424
|
+
after_validation :some_method
|
425
|
+
before_execution :some_method
|
426
|
+
after_execution :some_method
|
446
427
|
|
447
428
|
def call
|
448
429
|
# ...
|
449
430
|
end
|
450
431
|
|
451
|
-
private
|
452
|
-
|
453
|
-
def on_before_validation
|
454
|
-
# eg: Normalize context data
|
455
|
-
end
|
456
|
-
|
457
432
|
end
|
458
433
|
```
|
459
434
|
|
460
|
-
###
|
435
|
+
### Status Hooks
|
461
436
|
|
462
|
-
Define
|
437
|
+
Define one or more callbacks that are called after execution for
|
438
|
+
specific statuses.
|
463
439
|
|
464
440
|
```ruby
|
465
441
|
class DecryptSecretMessage < Lite::Command::Base
|
466
442
|
|
443
|
+
on_success :some_method
|
444
|
+
on_noop :some_method
|
445
|
+
on_invalid :some_method
|
446
|
+
on_failure :some_method
|
447
|
+
on_error :some_method
|
448
|
+
|
467
449
|
def call
|
468
450
|
# ...
|
469
451
|
end
|
470
452
|
|
471
|
-
private
|
472
|
-
|
473
|
-
def on_before_execution
|
474
|
-
# eg: Append additional contextual data
|
475
|
-
end
|
476
|
-
|
477
|
-
def on_after_execution
|
478
|
-
# eg: Store results to database
|
479
|
-
end
|
480
|
-
|
481
453
|
end
|
482
454
|
```
|
483
455
|
|
484
|
-
###
|
456
|
+
### State Hooks
|
485
457
|
|
486
|
-
Define one or more callbacks that are called
|
487
|
-
specific statuses.
|
458
|
+
Define one or more callbacks that are called during transitions between states.
|
488
459
|
|
489
460
|
```ruby
|
490
461
|
class DecryptSecretMessage < Lite::Command::Base
|
491
462
|
|
463
|
+
on_pending :some_method
|
464
|
+
on_executing :some_method
|
465
|
+
on_complete :some_method
|
466
|
+
on_interrupted :some_method
|
467
|
+
|
492
468
|
def call
|
493
469
|
# ...
|
494
470
|
end
|
495
471
|
|
496
|
-
private
|
497
|
-
|
498
|
-
def on_success
|
499
|
-
# eg: Increment KPI counter
|
500
|
-
end
|
501
|
-
|
502
|
-
def on_noop(fault)
|
503
|
-
# eg: Log message for posterity
|
504
|
-
end
|
505
|
-
|
506
|
-
def on_invalid(fault)
|
507
|
-
# eg: Send metadata errors to frontend
|
508
|
-
end
|
509
|
-
|
510
|
-
def on_failure(fault)
|
511
|
-
# eg: Rollback record changes
|
512
|
-
end
|
513
|
-
|
514
|
-
def on_error(fault_or_exception)
|
515
|
-
# eg: Report to APM with tags and metadata
|
516
|
-
end
|
517
|
-
|
518
472
|
end
|
519
473
|
```
|
520
474
|
|
521
|
-
> [!NOTE]
|
522
|
-
> The `on_success` callback does **NOT** take any arguments.
|
523
|
-
|
524
475
|
## Children
|
525
476
|
|
526
477
|
When building complex commands, its best that you pass the parents context to the
|
data/lib/lite/command/base.rb
CHANGED
@@ -16,6 +16,7 @@ module Lite
|
|
16
16
|
base.include Internals::Faults
|
17
17
|
base.include Internals::Calls
|
18
18
|
base.include Internals::Executions
|
19
|
+
base.include Internals::Hooks
|
19
20
|
base.include Internals::Results
|
20
21
|
|
21
22
|
if Lite::Command.configuration.raise_dynamic_faults # rubocop:disable Style/GuardClause
|
@@ -34,7 +35,7 @@ module Lite
|
|
34
35
|
|
35
36
|
def initialize(context = {})
|
36
37
|
@context = Context.build(context)
|
37
|
-
|
38
|
+
run_hooks(:after_initialize)
|
38
39
|
end
|
39
40
|
|
40
41
|
end
|
@@ -52,9 +52,9 @@ module Lite
|
|
52
52
|
private
|
53
53
|
|
54
54
|
def validate_context_attributes
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
run_hooks(:before_validation)
|
56
|
+
invalid!(errors.full_messages.join(". "), metadata: errors.messages) unless valid?
|
57
|
+
run_hooks(:after_validation)
|
58
58
|
end
|
59
59
|
|
60
60
|
end
|
@@ -24,14 +24,12 @@ module Lite
|
|
24
24
|
|
25
25
|
def call(context = {})
|
26
26
|
instance = send(:new, context)
|
27
|
-
instance.validate
|
28
27
|
instance.send(:execute)
|
29
28
|
instance
|
30
29
|
end
|
31
30
|
|
32
31
|
def call!(context = {})
|
33
32
|
instance = send(:new, context)
|
34
|
-
instance.validate
|
35
33
|
instance.send(:execute!)
|
36
34
|
instance
|
37
35
|
end
|
@@ -50,16 +50,18 @@ module Lite
|
|
50
50
|
increment_execution_index
|
51
51
|
assign_execution_cmd_id
|
52
52
|
start_monotonic_time
|
53
|
-
|
53
|
+
run_hooks(:on_pending)
|
54
54
|
validate_context_attributes
|
55
|
-
|
55
|
+
run_hooks(:before_execution)
|
56
56
|
executing!
|
57
|
-
|
57
|
+
run_hooks(:on_executing)
|
58
58
|
end
|
59
59
|
|
60
60
|
def after_execution
|
61
61
|
send(:"#{success? ? COMPLETE : INTERRUPTED}!")
|
62
|
-
|
62
|
+
run_hooks(:after_execution)
|
63
|
+
run_hooks(:"on_#{status}")
|
64
|
+
run_hooks(:"on_#{state}")
|
63
65
|
stop_monotonic_time
|
64
66
|
append_execution_result
|
65
67
|
freeze_execution_objects
|
@@ -72,26 +74,17 @@ module Lite
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def execute
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
fault(e, Utils.try(e, :type) || ERROR, metadata, exception: e)
|
79
|
-
after_execution
|
80
|
-
Utils.try(self, :"on_#{status}", e)
|
81
|
-
ensure
|
82
|
-
Utils.try(self, :"on_#{state}")
|
77
|
+
execute!
|
78
|
+
rescue StandardError
|
79
|
+
# Do nothing
|
83
80
|
end
|
84
81
|
|
85
82
|
def execute!
|
86
83
|
around_execution { call }
|
87
|
-
Utils.try(self, :on_success)
|
88
84
|
rescue StandardError => e
|
89
85
|
fault(e, Utils.try(e, :type) || ERROR, metadata, exception: e)
|
90
86
|
after_execution
|
91
|
-
Utils.try(self, :"on_#{status}", e)
|
92
87
|
raise(e)
|
93
|
-
else
|
94
|
-
Utils.try(self, :"on_#{state}")
|
95
88
|
end
|
96
89
|
|
97
90
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lite
|
4
|
+
module Command
|
5
|
+
|
6
|
+
HOOKS = [
|
7
|
+
:after_initialize,
|
8
|
+
:before_validation,
|
9
|
+
:after_validation,
|
10
|
+
:before_execution,
|
11
|
+
:after_execution,
|
12
|
+
*STATUSES.map { |s| :"on_#{s}" },
|
13
|
+
*STATES.map { |s| :"on_#{s}" }
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
module Internals
|
17
|
+
module Hooks
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
base.extend ClassMethods
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def hooks
|
26
|
+
@hooks ||= Utils.try(superclass, :hooks).dup || {}
|
27
|
+
end
|
28
|
+
|
29
|
+
HOOKS.each do |h|
|
30
|
+
define_method(h) do |*method_names, &block|
|
31
|
+
method_names << block if block_given?
|
32
|
+
method_names.each { |mn| (hooks[h] ||= []) << mn }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def run_hooks(hook)
|
41
|
+
hooks = self.class.hooks[hook]
|
42
|
+
return if hooks.nil?
|
43
|
+
|
44
|
+
hooks.each { |h| Utils.call(self, h) }
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/lite/command/version.rb
CHANGED
data/lib/lite/command.rb
CHANGED
@@ -16,6 +16,7 @@ require "lite/command/internals/attributes"
|
|
16
16
|
require "lite/command/internals/faults"
|
17
17
|
require "lite/command/internals/calls"
|
18
18
|
require "lite/command/internals/executions"
|
19
|
+
require "lite/command/internals/hooks"
|
19
20
|
require "lite/command/internals/results"
|
20
21
|
require "lite/command/base"
|
21
22
|
require "lite/command/step"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lite-command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Gomez
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -201,6 +201,7 @@ files:
|
|
201
201
|
- lib/lite/command/internals/calls.rb
|
202
202
|
- lib/lite/command/internals/executions.rb
|
203
203
|
- lib/lite/command/internals/faults.rb
|
204
|
+
- lib/lite/command/internals/hooks.rb
|
204
205
|
- lib/lite/command/internals/results.rb
|
205
206
|
- lib/lite/command/internals/runtimes.rb
|
206
207
|
- lib/lite/command/sequence.rb
|