gl_command 1.0.1 → 1.1.1
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/lib/gl_command/callable.rb +19 -7
- data/lib/gl_command/chainable.rb +1 -1
- data/lib/gl_command/context.rb +18 -4
- data/lib/gl_command/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: 2c64386ffafec990d01604c12482b0cf2deb8b4caff95c638d9d4e8835c4cb92
|
4
|
+
data.tar.gz: 9a58f0b30039b493382f01d22fb8cc2c8d6950af71f16ec3b4e708a776e78af9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 126e275c0bd65be3fb7fe1ead77e283231a158359b1c95ab00d691e010287f41b397a97a9202de316ba921313b1df66c59e76b4f5e13d62d4130d762aba6f803
|
7
|
+
data.tar.gz: 728454632aa41f5b740b4f3eaf97c85ee8022857ac349ca86bfa0d655687fc6b402b7501629e580c3ed3c2b87b621a56a11333a95f3239d8ec0095901bb0e311
|
data/lib/gl_command/callable.rb
CHANGED
@@ -6,7 +6,7 @@ require 'gl_command/validatable'
|
|
6
6
|
|
7
7
|
module GLCommand
|
8
8
|
class Callable
|
9
|
-
DEFAULT_OPTS = { raise_errors: false, skip_unknown_parameters: true }.freeze
|
9
|
+
DEFAULT_OPTS = { raise_errors: false, skip_unknown_parameters: true, in_chain: false }.freeze
|
10
10
|
RESERVED_WORDS = (DEFAULT_OPTS.keys + GLCommand::ChainableContext.reserved_words).sort.freeze
|
11
11
|
|
12
12
|
class << self
|
@@ -25,7 +25,8 @@ module GLCommand
|
|
25
25
|
|
26
26
|
# DEFAULT_OPTS contains skip_unknown_parameters: true - so it raises on call
|
27
27
|
# (rather than in context initialize) to make errors more legible
|
28
|
-
opts = DEFAULT_OPTS.merge(raise_errors: args.delete(:raise_errors)
|
28
|
+
opts = DEFAULT_OPTS.merge(raise_errors: args.delete(:raise_errors),
|
29
|
+
in_chain: args.delete(:in_chain)).compact
|
29
30
|
# args are passed in in perform_call(args) so that invalid args raise in a legible place
|
30
31
|
new(build_context(**args.merge(opts))).perform_call(args)
|
31
32
|
end
|
@@ -34,9 +35,13 @@ module GLCommand
|
|
34
35
|
call(*posargs, **args.merge(raise_errors: true))
|
35
36
|
end
|
36
37
|
|
37
|
-
|
38
|
+
# error can be passed to build context, useful for stubbing in tests
|
39
|
+
def build_context(raise_errors: false, skip_unknown_parameters: false, error: nil,
|
38
40
|
**arguments_and_returns)
|
39
|
-
context_class.new(self, raise_errors:, skip_unknown_parameters:,
|
41
|
+
new_context = context_class.new(self, raise_errors:, skip_unknown_parameters:,
|
42
|
+
**arguments_and_returns)
|
43
|
+
new_context.error = error if error.present?
|
44
|
+
new_context
|
40
45
|
end
|
41
46
|
|
42
47
|
def requires(*attributes, **strong_attributes)
|
@@ -70,7 +75,7 @@ module GLCommand
|
|
70
75
|
(arguments + returns).uniq
|
71
76
|
end
|
72
77
|
|
73
|
-
# Used internally by GLCommand (probably don't reference
|
78
|
+
# Used internally by GLCommand (probably don't reference in your own GLCommands)
|
74
79
|
# is true in GLCommand::Chainable
|
75
80
|
def chain?
|
76
81
|
false
|
@@ -106,7 +111,9 @@ module GLCommand
|
|
106
111
|
|
107
112
|
def perform_call(args)
|
108
113
|
raise_for_invalid_args!(**args)
|
114
|
+
instrument_command(:before_call)
|
109
115
|
call_with_callbacks
|
116
|
+
instrument_command(:after_call)
|
110
117
|
raise_unless_chained_or_skipped if self.class.chain? # defined in GLCommand::Chainable
|
111
118
|
context.failure? ? handle_failure : context
|
112
119
|
rescue StandardError => e
|
@@ -133,6 +140,11 @@ module GLCommand
|
|
133
140
|
|
134
141
|
private
|
135
142
|
|
143
|
+
# trigger: [:before_call, :after_call, :before_rollback]
|
144
|
+
def instrument_command(trigger)
|
145
|
+
# Override where gem is used if you want to instrument commands
|
146
|
+
end
|
147
|
+
|
136
148
|
# rubocop:disable Metrics/AbcSize
|
137
149
|
def handle_failure(e = nil)
|
138
150
|
context.error ||= e
|
@@ -159,9 +171,7 @@ module GLCommand
|
|
159
171
|
rescue GLCommand::CommandNoNotifyError
|
160
172
|
raise context.error # makes CommandNoNotifyError the cause
|
161
173
|
end
|
162
|
-
# rubocop:enable Metrics/AbcSize
|
163
174
|
|
164
|
-
# rubocop:disable Metrics/AbcSize
|
165
175
|
def call_with_callbacks
|
166
176
|
GLExceptionNotifier.breadcrumbs(data: { context: context.inspect }, message: self.class.to_s)
|
167
177
|
validate_validatable! # defined in GLCommand::Validatable
|
@@ -186,6 +196,8 @@ module GLCommand
|
|
186
196
|
def call_rollbacks
|
187
197
|
return if defined?(@rolled_back) # Not sure this is required
|
188
198
|
|
199
|
+
instrument_command(:before_rollback)
|
200
|
+
|
189
201
|
@rolled_back = true
|
190
202
|
|
191
203
|
chain_rollback if self.class.chain? # defined in GLCommand::Chainable
|
data/lib/gl_command/chainable.rb
CHANGED
@@ -41,7 +41,7 @@ module GLCommand
|
|
41
41
|
|
42
42
|
commands.map do |command|
|
43
43
|
cargs = context.chain_arguments_and_returns.slice(*command.arguments)
|
44
|
-
.merge(context.opts_hash)
|
44
|
+
.merge(context.opts_hash).merge(in_chain: true)
|
45
45
|
|
46
46
|
result = command.call(**cargs)
|
47
47
|
context.assign_parameters(skip_unknown_parameters: true, **result.returns)
|
data/lib/gl_command/context.rb
CHANGED
@@ -7,9 +7,10 @@ require 'active_support/core_ext/module'
|
|
7
7
|
module GLCommand
|
8
8
|
class Context
|
9
9
|
def initialize(klass, raise_errors: false, skip_unknown_parameters: false,
|
10
|
-
**arguments_and_returns)
|
10
|
+
in_chain: false, **arguments_and_returns)
|
11
11
|
@klass = klass
|
12
12
|
@raise_errors = raise_errors.nil? ? false : raise_errors
|
13
|
+
@in_chain = in_chain
|
13
14
|
@klass.arguments_and_returns.each { |key| singleton_class.class_eval { attr_accessor key } }
|
14
15
|
initialize_chain_context(**arguments_and_returns) if chain?
|
15
16
|
assign_parameters(skip_unknown_parameters:, **arguments_and_returns)
|
@@ -24,12 +25,21 @@ module GLCommand
|
|
24
25
|
attr_reader :klass, :error
|
25
26
|
attr_writer :full_error_message
|
26
27
|
|
27
|
-
|
28
|
+
# If someone calls errors on a context, they expect to get the errors!
|
29
|
+
# Make that work, but also try to make it clear that they probably shouldn't be using that for presentation
|
30
|
+
def errors
|
31
|
+
current_errors&.add(:base, "full_error_message: #{full_error_message}") if @failure && current_errors.blank?
|
32
|
+
current_errors
|
33
|
+
end
|
28
34
|
|
29
35
|
def chain?
|
30
36
|
false
|
31
37
|
end
|
32
38
|
|
39
|
+
def in_chain?
|
40
|
+
@in_chain
|
41
|
+
end
|
42
|
+
|
33
43
|
def returns
|
34
44
|
@klass.returns.index_with { |rattr| send(rattr) }
|
35
45
|
end
|
@@ -43,7 +53,7 @@ module GLCommand
|
|
43
53
|
end
|
44
54
|
|
45
55
|
def failure?
|
46
|
-
@failure ||
|
56
|
+
@failure || current_errors.present? || @full_error_message.present? || false
|
47
57
|
end
|
48
58
|
|
49
59
|
def success?
|
@@ -98,7 +108,7 @@ module GLCommand
|
|
98
108
|
passed_error.is_a?(ActiveRecord::RecordInvalid) && defined?(passed_error.record.errors)
|
99
109
|
# Return a new error if it's an error (rather than the class)
|
100
110
|
passed_error.is_a?(Class) ? passed_error.new(@full_error_message) : passed_error
|
101
|
-
elsif
|
111
|
+
elsif current_errors.present? # check for validation errors
|
102
112
|
# Assign ActiveRecord::RecordInvalid if validatable error
|
103
113
|
ActiveRecord::RecordInvalid.new(@callable)
|
104
114
|
else
|
@@ -118,6 +128,10 @@ module GLCommand
|
|
118
128
|
|
119
129
|
private
|
120
130
|
|
131
|
+
def current_errors
|
132
|
+
@callable&.errors
|
133
|
+
end
|
134
|
+
|
121
135
|
def exception?(passed_error)
|
122
136
|
passed_error.is_a?(Exception) ||
|
123
137
|
(passed_error.respond_to?(:ancestors) && passed_error.ancestors.include?(Exception))
|
data/lib/gl_command/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gl_command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Give Lively
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|