lite-command 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +1 -1
- data/lib/lite/command/base.rb +2 -4
- data/lib/lite/command/context.rb +5 -10
- data/lib/lite/command/fault.rb +4 -24
- data/lib/lite/command/internals/callable.rb +21 -94
- data/lib/lite/command/internals/executable.rb +1 -4
- data/lib/lite/command/internals/faultable.rb +88 -0
- data/lib/lite/command/internals/resultable.rb +3 -3
- data/lib/lite/command/version.rb +1 -1
- data/lib/lite/command.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a841431a363de96b59d32abaa1bc733c04046a5d2f33b1c544e85b8b89cdcd9
|
4
|
+
data.tar.gz: 11dd1cd8c8e19cc8d58a631f94f647eb4d7a6b2effe2591d04eaea4c693ecdee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae2440d1e33ddf601c42996a513f66771fb06af24a6f60534329b3337335bb714e3be2e9fd5b43d5f71e26ff8d2bc5bbe7bc9a07d275b259491858f6f8864e9b
|
7
|
+
data.tar.gz: 873edb0d145a80033180e0a33072dd80da38512511d718af17e4e91ddc65d90118bd63d8a341d22278a1d026751b0cf867df708dafde21be54fc54ef0c821f47
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [2.0.2] - 2024-09-29
|
10
|
+
### Added
|
11
|
+
- faultable module
|
12
|
+
### Changed
|
13
|
+
- Simplified status variable check
|
14
|
+
- Simplified context merge
|
15
|
+
- Fixed invalid looking at wrong variable
|
16
|
+
- Renamed `fault` and `thrower` to `caused_by` and `thrown_by` respectively
|
17
|
+
- Removed unused `additional_result_data` method
|
18
|
+
### Removed
|
19
|
+
- Removed context init
|
20
|
+
|
9
21
|
## [2.0.1] - 2024-09-27
|
10
22
|
### Removed
|
11
23
|
- Activemodel dependency
|
data/Gemfile.lock
CHANGED
data/lib/lite/command/base.rb
CHANGED
@@ -9,6 +9,7 @@ module Lite
|
|
9
9
|
|
10
10
|
base.include Lite::Command::Internals::Callable
|
11
11
|
base.include Lite::Command::Internals::Executable
|
12
|
+
base.include Lite::Command::Internals::Faultable
|
12
13
|
base.include Lite::Command::Internals::Resultable
|
13
14
|
|
14
15
|
base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
@@ -25,6 +26,7 @@ module Lite
|
|
25
26
|
end
|
26
27
|
|
27
28
|
attr_reader :context
|
29
|
+
alias ctx context
|
28
30
|
|
29
31
|
def initialize(context = {})
|
30
32
|
@context = Lite::Command::Context.build(context)
|
@@ -32,10 +34,6 @@ module Lite
|
|
32
34
|
|
33
35
|
private
|
34
36
|
|
35
|
-
def additional_result_data
|
36
|
-
{} # Define in your class to add additional info to result hash
|
37
|
-
end
|
38
|
-
|
39
37
|
def on_before_execution
|
40
38
|
# Define in your class to run code before execution
|
41
39
|
end
|
data/lib/lite/command/context.rb
CHANGED
@@ -6,25 +6,20 @@ module Lite
|
|
6
6
|
module Command
|
7
7
|
class Context < OpenStruct
|
8
8
|
|
9
|
-
def self.
|
9
|
+
def self.build(attributes = {})
|
10
|
+
return attributes if attributes.is_a?(self) && !attributes.frozen?
|
11
|
+
|
10
12
|
# To save memory and speed up the access to an attribute, the accessor methods
|
11
13
|
# of an attribute are lazy loaded at certain points. This means that the methods
|
12
14
|
# are defined only when a set of defined actions are triggered. This allows context
|
13
15
|
# to only define the minimum amount of required methods to make your data structure work
|
14
|
-
os = new(attributes)
|
16
|
+
os = new(attributes.to_h)
|
15
17
|
os.methods(false)
|
16
18
|
os
|
17
19
|
end
|
18
20
|
|
19
|
-
def self.build(attributes = {})
|
20
|
-
return attributes if attributes.is_a?(self) && !attributes.frozen?
|
21
|
-
|
22
|
-
init(attributes.to_h)
|
23
|
-
end
|
24
|
-
|
25
21
|
def merge!(attributes = {})
|
26
|
-
|
27
|
-
attrs.each { |k, v| self[k] = v }
|
22
|
+
attributes.to_h.each { |k, v| self[k] = v }
|
28
23
|
end
|
29
24
|
|
30
25
|
end
|
data/lib/lite/command/fault.rb
CHANGED
@@ -3,18 +3,15 @@
|
|
3
3
|
module Lite
|
4
4
|
module Command
|
5
5
|
|
6
|
-
# Fault represent a stoppage of a call execution. This error should
|
7
|
-
# not be raised directly since it wont provide any context. Use
|
8
|
-
# `Noop`, `Invalid`, `Failure`, and `Error` to signify severity.
|
9
6
|
class Fault < StandardError
|
10
7
|
|
11
|
-
attr_reader :
|
8
|
+
attr_reader :caused_by, :thrown_by, :reason
|
12
9
|
|
13
|
-
def initialize(
|
10
|
+
def initialize(caused_by, thrown_by, reason)
|
14
11
|
super(reason)
|
15
12
|
|
16
|
-
@
|
17
|
-
@
|
13
|
+
@caused_by = caused_by
|
14
|
+
@thrown_by = thrown_by
|
18
15
|
@reason = reason
|
19
16
|
end
|
20
17
|
|
@@ -28,26 +25,9 @@ module Lite
|
|
28
25
|
|
29
26
|
end
|
30
27
|
|
31
|
-
# Noop represents skipping completion of call execution early
|
32
|
-
# an unsatisfied condition or logic check where there is no
|
33
|
-
# point on proceeding.
|
34
|
-
# eg: account is sample: skip since its a non-alterable record
|
35
28
|
class Noop < Fault; end
|
36
|
-
|
37
|
-
# Invalid represents a stoppage of call execution due to
|
38
|
-
# missing, bad, or corrupt data.
|
39
|
-
# eg: user not found: stop since rest of the call cant be executed
|
40
29
|
class Invalid < Fault; end
|
41
|
-
|
42
|
-
# Failure represents a stoppage of call execution due to
|
43
|
-
# an unsatisfied condition or logic check where it blocks
|
44
|
-
# proceeding any further.
|
45
|
-
# eg: record not found: stop since there is nothing todo
|
46
30
|
class Failure < Fault; end
|
47
|
-
|
48
|
-
# Error represents a caught exception for a call execution
|
49
|
-
# that could not complete.
|
50
|
-
# eg: ApiServerError: stop since there was a 3rd party issue
|
51
31
|
class Error < Fault; end
|
52
32
|
|
53
33
|
end
|
@@ -3,28 +3,20 @@
|
|
3
3
|
module Lite
|
4
4
|
module Command
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
# has not been executed.
|
9
|
-
FAULTS = [
|
6
|
+
STATUSES = [
|
7
|
+
SUCCESS = "success",
|
10
8
|
NOOP = "noop",
|
11
9
|
INVALID = "invalid",
|
12
10
|
FAILURE = "failure",
|
13
11
|
ERROR = "error"
|
14
12
|
].freeze
|
15
|
-
|
16
|
-
*FAULTS,
|
17
|
-
SUCCESS = "success"
|
18
|
-
].freeze
|
13
|
+
FAULTS = (STATUSES - [SUCCESS]).freeze
|
19
14
|
|
20
15
|
module Internals
|
21
16
|
module Callable
|
22
17
|
|
23
18
|
def self.included(base)
|
24
19
|
base.extend ClassMethods
|
25
|
-
base.class_eval do
|
26
|
-
attr_reader :faulter, :thrower, :reason
|
27
|
-
end
|
28
20
|
end
|
29
21
|
|
30
22
|
module ClassMethods
|
@@ -43,109 +35,44 @@ module Lite
|
|
43
35
|
raise NotImplementedError, "call method not defined in #{self.class}"
|
44
36
|
end
|
45
37
|
|
46
|
-
def success?
|
47
|
-
!fault?
|
48
|
-
end
|
49
|
-
|
50
|
-
def fault?(message = nil)
|
51
|
-
FAULTS.any? { |f| send(:"#{f}?", message) }
|
52
|
-
end
|
53
|
-
|
54
38
|
def status
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
def faulter?
|
59
|
-
faulter == self
|
39
|
+
@status || SUCCESS
|
60
40
|
end
|
61
41
|
|
62
|
-
def
|
63
|
-
|
42
|
+
def success?
|
43
|
+
status == SUCCESS
|
64
44
|
end
|
65
45
|
|
66
|
-
def
|
67
|
-
|
46
|
+
def fault?(str = nil)
|
47
|
+
!success? && reason?(str)
|
68
48
|
end
|
69
49
|
|
70
50
|
FAULTS.each do |f|
|
71
|
-
# eg:
|
72
|
-
define_method(:"#{f}?") do |
|
73
|
-
|
74
|
-
return fault_result if message.nil?
|
75
|
-
|
76
|
-
reason == message
|
51
|
+
# eg: noop? or failure?("idk")
|
52
|
+
define_method(:"#{f}?") do |str = nil|
|
53
|
+
status == f && reason?(str)
|
77
54
|
end
|
78
55
|
end
|
79
56
|
|
80
57
|
private
|
81
58
|
|
82
|
-
def derive_faulter_from(object)
|
83
|
-
(object.faulter if object.respond_to?(:faulter)) || self
|
84
|
-
end
|
85
|
-
|
86
|
-
def derive_thrower_from(object)
|
87
|
-
if object.respond_to?(:executed?) && object.executed?
|
88
|
-
object
|
89
|
-
else
|
90
|
-
(object.thrower if object.respond_to?(:thrower)) || faulter
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def derive_reason_from(object)
|
95
|
-
if object.respond_to?(:reason)
|
96
|
-
object.reason
|
97
|
-
elsif object.respond_to?(:message)
|
98
|
-
"[#{object.class.name}] #{object.message}".chomp(".")
|
99
|
-
else
|
100
|
-
object
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def fault(object)
|
105
|
-
@faulter ||= derive_faulter_from(object)
|
106
|
-
@thrower ||= derive_thrower_from(object)
|
107
|
-
@reason ||= derive_reason_from(object)
|
108
|
-
end
|
109
|
-
|
110
|
-
# eg: Lite::Command::Noop.new(...)
|
111
|
-
def raise_fault(klass, object)
|
112
|
-
exception = klass.new(faulter, self, reason)
|
113
|
-
exception.set_backtrace(object.backtrace) if object.respond_to?(:backtrace)
|
114
|
-
raise(exception)
|
115
|
-
end
|
116
|
-
|
117
|
-
# eg: Users::ResetPassword::Noop.new(...)
|
118
|
-
def raise_dynamic_fault(exception)
|
119
|
-
fault_klass = self.class.const_get(exception.fault_klass)
|
120
|
-
raise_fault(fault_klass, exception)
|
121
|
-
end
|
122
|
-
|
123
|
-
def raise_dynamic_faults?
|
124
|
-
false
|
125
|
-
end
|
126
|
-
|
127
|
-
def throw!(command)
|
128
|
-
return if command.success?
|
129
|
-
|
130
|
-
send(:"#{command.status}!", command)
|
131
|
-
end
|
132
|
-
|
133
59
|
FAULTS.each do |f|
|
134
|
-
# eg: error(
|
135
|
-
define_method(:"#{f}") do |
|
136
|
-
|
137
|
-
|
60
|
+
# eg: error(fault_or_string)
|
61
|
+
define_method(:"#{f}") do |fault_or_string|
|
62
|
+
derive_fault_from(fault_or_string)
|
63
|
+
@status = f
|
138
64
|
end
|
139
65
|
|
140
|
-
# eg: invalid!(
|
141
|
-
define_method(:"#{f}!") do |
|
142
|
-
send(:"#{f}",
|
143
|
-
raise_fault(Lite::Command.const_get(f.capitalize),
|
66
|
+
# eg: invalid!(fault_or_string)
|
67
|
+
define_method(:"#{f}!") do |fault_or_string|
|
68
|
+
send(:"#{f}", fault_or_string)
|
69
|
+
raise_fault(Lite::Command.const_get(f.capitalize), fault_or_string)
|
144
70
|
end
|
145
71
|
|
146
72
|
# eg: on_noop(exception)
|
147
73
|
define_method(:"on_#{f}") do |_exception|
|
148
|
-
# Define in your class to run code when a
|
74
|
+
# Define in your class to run code when a
|
75
|
+
# Lite::Command::Fault or StandardError happens
|
149
76
|
end
|
150
77
|
end
|
151
78
|
|
@@ -3,9 +3,6 @@
|
|
3
3
|
module Lite
|
4
4
|
module Command
|
5
5
|
|
6
|
-
# State represents the state of the executable code. Once `execute`
|
7
|
-
# is ran, it will always complete or dnf if a fault is thrown by a
|
8
|
-
# child command.
|
9
6
|
STATES = [
|
10
7
|
PENDING = "pending",
|
11
8
|
EXECUTING = "executing",
|
@@ -45,7 +42,7 @@ module Lite
|
|
45
42
|
end
|
46
43
|
|
47
44
|
STATES.each do |s|
|
48
|
-
# eg:
|
45
|
+
# eg: executing?
|
49
46
|
define_method(:"#{s}?") { state == s }
|
50
47
|
|
51
48
|
# eg: dnf!
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lite
|
4
|
+
module Command
|
5
|
+
module Internals
|
6
|
+
module Faultable
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
attr_reader :caused_by, :thrown_by, :reason
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def reason?(str)
|
15
|
+
return true if str.nil?
|
16
|
+
|
17
|
+
reason == str
|
18
|
+
end
|
19
|
+
|
20
|
+
def caused_fault?
|
21
|
+
caused_by == self
|
22
|
+
end
|
23
|
+
|
24
|
+
def threw_fault?
|
25
|
+
thrown_by == self
|
26
|
+
end
|
27
|
+
|
28
|
+
def thrown?
|
29
|
+
fault? && !caused_fault?
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def throw!(command)
|
35
|
+
return if command.success?
|
36
|
+
|
37
|
+
send(:"#{command.status}!", command)
|
38
|
+
end
|
39
|
+
|
40
|
+
def derive_caused_by_from(fault_or_string)
|
41
|
+
(fault_or_string.caused_by if fault_or_string.respond_to?(:caused_by)) || self
|
42
|
+
end
|
43
|
+
|
44
|
+
def derive_thrown_by_from(fault_or_string)
|
45
|
+
if fault_or_string.respond_to?(:executed?) && fault_or_string.executed?
|
46
|
+
fault_or_string
|
47
|
+
else
|
48
|
+
(fault_or_string.thrown_by if fault_or_string.respond_to?(:thrown_by)) || caused_by
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def derive_reason_from(fault_or_string)
|
53
|
+
if fault_or_string.respond_to?(:reason)
|
54
|
+
fault_or_string.reason
|
55
|
+
elsif fault_or_string.respond_to?(:message)
|
56
|
+
"[#{fault_or_string.class.name}] #{fault_or_string.message}".chomp(".")
|
57
|
+
else
|
58
|
+
fault_or_string
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def derive_fault_from(fault_or_string)
|
63
|
+
@caused_by ||= derive_caused_by_from(fault_or_string)
|
64
|
+
@thrown_by ||= derive_thrown_by_from(fault_or_string)
|
65
|
+
@reason ||= derive_reason_from(fault_or_string)
|
66
|
+
end
|
67
|
+
|
68
|
+
# eg: Lite::Command::Noop.new(...)
|
69
|
+
def raise_fault(klass, thrower)
|
70
|
+
exception = klass.new(caused_by, self, reason)
|
71
|
+
exception.set_backtrace(thrower.backtrace) if thrower.respond_to?(:backtrace)
|
72
|
+
raise(exception)
|
73
|
+
end
|
74
|
+
|
75
|
+
# eg: Users::ResetPassword::Noop.new(...)
|
76
|
+
def raise_dynamic_fault(exception)
|
77
|
+
fault_klass = self.class.const_get(exception.fault_klass)
|
78
|
+
raise_fault(fault_klass, exception)
|
79
|
+
end
|
80
|
+
|
81
|
+
def raise_dynamic_faults?
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -16,7 +16,7 @@ module Lite
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def outcome
|
19
|
-
return state if pending? ||
|
19
|
+
return state if pending? || thrown?
|
20
20
|
|
21
21
|
status
|
22
22
|
end
|
@@ -34,8 +34,8 @@ module Lite
|
|
34
34
|
state:,
|
35
35
|
status:,
|
36
36
|
reason:,
|
37
|
-
|
38
|
-
|
37
|
+
caused_by: caused_by&.index,
|
38
|
+
thrown_by: thrown_by&.index,
|
39
39
|
runtime:
|
40
40
|
}.compact
|
41
41
|
end
|
data/lib/lite/command/version.rb
CHANGED
data/lib/lite/command.rb
CHANGED
@@ -5,6 +5,7 @@ require "generators/rails/command_generator" if defined?(Rails::Generators)
|
|
5
5
|
require "lite/command/version"
|
6
6
|
require "lite/command/internals/callable"
|
7
7
|
require "lite/command/internals/executable"
|
8
|
+
require "lite/command/internals/faultable"
|
8
9
|
require "lite/command/internals/resultable"
|
9
10
|
require "lite/command/fault"
|
10
11
|
require "lite/command/context"
|
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: 2.0.
|
4
|
+
version: 2.0.2
|
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-09-
|
11
|
+
date: 2024-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ostruct
|
@@ -196,6 +196,7 @@ files:
|
|
196
196
|
- lib/lite/command/fault.rb
|
197
197
|
- lib/lite/command/internals/callable.rb
|
198
198
|
- lib/lite/command/internals/executable.rb
|
199
|
+
- lib/lite/command/internals/faultable.rb
|
199
200
|
- lib/lite/command/internals/resultable.rb
|
200
201
|
- lib/lite/command/version.rb
|
201
202
|
- lite-command.gemspec
|
@@ -219,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
220
|
- !ruby/object:Gem::Version
|
220
221
|
version: '0'
|
221
222
|
requirements: []
|
222
|
-
rubygems_version: 3.5.
|
223
|
+
rubygems_version: 3.5.20
|
223
224
|
signing_key:
|
224
225
|
specification_version: 4
|
225
226
|
summary: Ruby Command based framework (aka service objects)
|