lite-command 2.0.0 → 2.0.2
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 +17 -1
- data/Gemfile.lock +1 -4
- 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
- data/lite-command.gemspec +0 -1
- metadata +4 -17
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,7 +6,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
-
## [2.0.
|
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
|
+
|
21
|
+
## [2.0.1] - 2024-09-27
|
22
|
+
### Removed
|
23
|
+
- Activemodel dependency
|
24
|
+
|
25
|
+
## [2.0.0] - 2024-09-27
|
10
26
|
### Changed
|
11
27
|
- Rewrite app to use interactor pattern
|
12
28
|
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lite-command (2.0.
|
5
|
-
activemodel
|
4
|
+
lite-command (2.0.2)
|
6
5
|
ostruct
|
7
6
|
|
8
7
|
GEM
|
@@ -25,8 +24,6 @@ GEM
|
|
25
24
|
erubi (~> 1.11)
|
26
25
|
rails-dom-testing (~> 2.2)
|
27
26
|
rails-html-sanitizer (~> 1.6)
|
28
|
-
activemodel (7.2.1)
|
29
|
-
activesupport (= 7.2.1)
|
30
27
|
activesupport (7.2.1)
|
31
28
|
base64
|
32
29
|
bigdecimal
|
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"
|
data/lite-command.gemspec
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
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
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activemodel
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: ostruct
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,6 +196,7 @@ files:
|
|
210
196
|
- lib/lite/command/fault.rb
|
211
197
|
- lib/lite/command/internals/callable.rb
|
212
198
|
- lib/lite/command/internals/executable.rb
|
199
|
+
- lib/lite/command/internals/faultable.rb
|
213
200
|
- lib/lite/command/internals/resultable.rb
|
214
201
|
- lib/lite/command/version.rb
|
215
202
|
- lite-command.gemspec
|
@@ -233,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
233
220
|
- !ruby/object:Gem::Version
|
234
221
|
version: '0'
|
235
222
|
requirements: []
|
236
|
-
rubygems_version: 3.5.
|
223
|
+
rubygems_version: 3.5.20
|
237
224
|
signing_key:
|
238
225
|
specification_version: 4
|
239
226
|
summary: Ruby Command based framework (aka service objects)
|