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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71f2852f73f09542e278f594b692dd02c8e10f54fee85e1e9493d565520e5fc6
4
- data.tar.gz: 668b62c1be78ee8b18ad06469ddbabf703497777bc73536395c6608fe8e26614
3
+ metadata.gz: 1a841431a363de96b59d32abaa1bc733c04046a5d2f33b1c544e85b8b89cdcd9
4
+ data.tar.gz: 11dd1cd8c8e19cc8d58a631f94f647eb4d7a6b2effe2591d04eaea4c693ecdee
5
5
  SHA512:
6
- metadata.gz: 18815326f8e22082e906c0142dd0b157a910a9d1755a56e67869b58cfe39ce4394beccb7c48565969ac291569005eb35d0a365ca9854bd9adf383def93ec8c8f
7
- data.tar.gz: 3cba4a2e8fa9f780e7546e5934b38a5c3d3aadc318bca455824a8058aa5855cf47026c7c7813cfca8c2f390702b3fdb8d260139613853936d8e59cf68d6e8437
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lite-command (2.0.1)
4
+ lite-command (2.0.2)
5
5
  ostruct
6
6
 
7
7
  GEM
@@ -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
@@ -6,25 +6,20 @@ module Lite
6
6
  module Command
7
7
  class Context < OpenStruct
8
8
 
9
- def self.init(attributes = {})
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
- attrs = attributes.is_a?(self.class) ? attributes.to_h : attributes
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
@@ -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 :faulter, :thrower, :reason
8
+ attr_reader :caused_by, :thrown_by, :reason
12
9
 
13
- def initialize(faulter, thrower, reason)
10
+ def initialize(caused_by, thrown_by, reason)
14
11
  super(reason)
15
12
 
16
- @faulter = faulter
17
- @thrower = thrower
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
- # Status represents the state of the callable code. If no fault
7
- # is thrown then a status of SUCCESS is returned even if `call`
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
- STATUSES = [
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
- STATUSES.find { |s| send(:"#{s}?") }
56
- end
57
-
58
- def faulter?
59
- faulter == self
39
+ @status || SUCCESS
60
40
  end
61
41
 
62
- def thrower?
63
- thrower == self
42
+ def success?
43
+ status == SUCCESS
64
44
  end
65
45
 
66
- def thrown_fault?
67
- fault? && !faulter?
46
+ def fault?(str = nil)
47
+ !success? && reason?(str)
68
48
  end
69
49
 
70
50
  FAULTS.each do |f|
71
- # eg: error?(message = nil)
72
- define_method(:"#{f}?") do |message = nil|
73
- fault_result = instance_variable_get(:"@#{f}") || false
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(object)
135
- define_method(:"#{f}") do |object|
136
- fault(object)
137
- instance_variable_set(:"@#{f}", true)
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!(object)
141
- define_method(:"#{f}!") do |object|
142
- send(:"#{f}", object)
143
- raise_fault(Lite::Command.const_get(f.capitalize), object)
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 StandardError happens
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: running?
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? || thrown_fault?
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
- fault: faulter&.index,
38
- throw: thrower&.index,
37
+ caused_by: caused_by&.index,
38
+ thrown_by: thrown_by&.index,
39
39
  runtime:
40
40
  }.compact
41
41
  end
@@ -3,7 +3,7 @@
3
3
  module Lite
4
4
  module Command
5
5
 
6
- VERSION = "2.0.1"
6
+ VERSION = "2.0.2"
7
7
 
8
8
  end
9
9
  end
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.1
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-27 00:00:00.000000000 Z
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.19
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)