hanami-utils 2.0.0.alpha1 → 2.0.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 +216 -4
- data/README.md +16 -23
- data/hanami-utils.gemspec +6 -5
- data/lib/hanami/middleware.rb +10 -3
- data/lib/hanami/utils/blank.rb +7 -7
- data/lib/hanami/utils/callbacks.rb +4 -2
- data/lib/hanami/utils/class.rb +0 -31
- data/lib/hanami/utils/class_attribute.rb +7 -7
- data/lib/hanami/utils/escape.rb +172 -170
- data/lib/hanami/utils/file_list.rb +22 -2
- data/lib/hanami/utils/files.rb +13 -2
- data/lib/hanami/utils/hash.rb +20 -32
- data/lib/hanami/utils/json.rb +11 -1
- data/lib/hanami/utils/kernel.rb +14 -14
- data/lib/hanami/utils/load_paths.rb +3 -3
- data/lib/hanami/utils/path_prefix.rb +33 -3
- data/lib/hanami/utils/query_string.rb +1 -1
- data/lib/hanami/utils/shell_color.rb +14 -10
- data/lib/hanami/utils/string.rb +33 -394
- data/lib/hanami/utils/version.rb +3 -2
- data/lib/hanami/utils.rb +4 -4
- metadata +36 -21
- data/lib/hanami/interactor.rb +0 -619
- data/lib/hanami/logger/colorizer.rb +0 -105
- data/lib/hanami/logger/filter.rb +0 -68
- data/lib/hanami/logger/formatter.rb +0 -183
- data/lib/hanami/logger.rb +0 -360
- data/lib/hanami/utils/basic_object.rb +0 -84
data/lib/hanami/interactor.rb
DELETED
|
@@ -1,619 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "hanami/utils/basic_object"
|
|
4
|
-
require "hanami/utils/class_attribute"
|
|
5
|
-
require "hanami/utils/hash"
|
|
6
|
-
|
|
7
|
-
module Hanami
|
|
8
|
-
# Hanami Interactor
|
|
9
|
-
#
|
|
10
|
-
# @since 0.3.5
|
|
11
|
-
module Interactor
|
|
12
|
-
# Result of an operation
|
|
13
|
-
#
|
|
14
|
-
# @since 0.3.5
|
|
15
|
-
class Result < Utils::BasicObject
|
|
16
|
-
# Concrete methods
|
|
17
|
-
#
|
|
18
|
-
# @since 0.3.5
|
|
19
|
-
# @api private
|
|
20
|
-
#
|
|
21
|
-
# @see Hanami::Interactor::Result#respond_to_missing?
|
|
22
|
-
METHODS = ::Hash[initialize: true,
|
|
23
|
-
success?: true,
|
|
24
|
-
successful?: true,
|
|
25
|
-
failure?: true,
|
|
26
|
-
fail!: true,
|
|
27
|
-
prepare!: true,
|
|
28
|
-
errors: true,
|
|
29
|
-
error: true].freeze
|
|
30
|
-
|
|
31
|
-
# Initialize a new result
|
|
32
|
-
#
|
|
33
|
-
# @param payload [Hash] a payload to carry on
|
|
34
|
-
#
|
|
35
|
-
# @return [Hanami::Interactor::Result]
|
|
36
|
-
#
|
|
37
|
-
# @since 0.3.5
|
|
38
|
-
# @api private
|
|
39
|
-
def initialize(payload = {})
|
|
40
|
-
@payload = payload
|
|
41
|
-
@errors = []
|
|
42
|
-
@success = true
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Check if the current status is successful
|
|
46
|
-
#
|
|
47
|
-
# @return [TrueClass,FalseClass] the result of the check
|
|
48
|
-
#
|
|
49
|
-
# @since 0.8.1
|
|
50
|
-
def successful?
|
|
51
|
-
@success && errors.empty?
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# @since 0.3.5
|
|
55
|
-
alias success? successful?
|
|
56
|
-
|
|
57
|
-
# Check if the current status is not successful
|
|
58
|
-
#
|
|
59
|
-
# @return [TrueClass,FalseClass] the result of the check
|
|
60
|
-
#
|
|
61
|
-
# @since 0.9.2
|
|
62
|
-
def failure?
|
|
63
|
-
!successful?
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Force the status to be a failure
|
|
67
|
-
#
|
|
68
|
-
# @since 0.3.5
|
|
69
|
-
def fail!
|
|
70
|
-
@success = false
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Returns all the errors collected during an operation
|
|
74
|
-
#
|
|
75
|
-
# @return [Array] the errors
|
|
76
|
-
#
|
|
77
|
-
# @since 0.3.5
|
|
78
|
-
#
|
|
79
|
-
# @see Hanami::Interactor::Result#error
|
|
80
|
-
# @see Hanami::Interactor#call
|
|
81
|
-
# @see Hanami::Interactor#error
|
|
82
|
-
# @see Hanami::Interactor#error!
|
|
83
|
-
def errors
|
|
84
|
-
@errors.dup
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# @since 0.5.0
|
|
88
|
-
# @api private
|
|
89
|
-
def add_error(*errors)
|
|
90
|
-
@errors << errors
|
|
91
|
-
@errors.flatten!
|
|
92
|
-
nil
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Returns the first errors collected during an operation
|
|
96
|
-
#
|
|
97
|
-
# @return [nil,String] the error, if present
|
|
98
|
-
#
|
|
99
|
-
# @since 0.3.5
|
|
100
|
-
#
|
|
101
|
-
# @see Hanami::Interactor::Result#errors
|
|
102
|
-
# @see Hanami::Interactor#call
|
|
103
|
-
# @see Hanami::Interactor#error
|
|
104
|
-
# @see Hanami::Interactor#error!
|
|
105
|
-
def error
|
|
106
|
-
errors.first
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# Prepare the result before to be returned
|
|
110
|
-
#
|
|
111
|
-
# @param payload [Hash] an updated payload
|
|
112
|
-
#
|
|
113
|
-
# @since 0.3.5
|
|
114
|
-
# @api private
|
|
115
|
-
def prepare!(payload)
|
|
116
|
-
@payload.merge!(payload)
|
|
117
|
-
self
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
protected
|
|
121
|
-
|
|
122
|
-
# @since 0.3.5
|
|
123
|
-
# @api private
|
|
124
|
-
def method_missing(method_name, *)
|
|
125
|
-
@payload.fetch(method_name) { super }
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# @since 0.3.5
|
|
129
|
-
# @api private
|
|
130
|
-
def respond_to_missing?(method_name, _include_all)
|
|
131
|
-
method_name = method_name.to_sym
|
|
132
|
-
METHODS[method_name] || @payload.key?(method_name)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# @since 0.3.5
|
|
136
|
-
# @api private
|
|
137
|
-
def __inspect
|
|
138
|
-
" @success=#{@success} @payload=#{@payload.inspect}"
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Override for <tt>Module#included</tt>.
|
|
143
|
-
#
|
|
144
|
-
# @since 0.3.5
|
|
145
|
-
# @api private
|
|
146
|
-
def self.included(base)
|
|
147
|
-
super
|
|
148
|
-
|
|
149
|
-
base.class_eval do
|
|
150
|
-
extend ClassMethods
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# Interactor legacy interface
|
|
155
|
-
#
|
|
156
|
-
# @since 0.3.5
|
|
157
|
-
module LegacyInterface
|
|
158
|
-
# Initialize an interactor
|
|
159
|
-
#
|
|
160
|
-
# It accepts arbitrary number of arguments.
|
|
161
|
-
# Developers can override it.
|
|
162
|
-
#
|
|
163
|
-
# @param args [Array<Object>] arbitrary number of arguments
|
|
164
|
-
#
|
|
165
|
-
# @return [Hanami::Interactor] the interactor
|
|
166
|
-
#
|
|
167
|
-
# @since 0.3.5
|
|
168
|
-
#
|
|
169
|
-
# @example Override #initialize
|
|
170
|
-
# require 'hanami/interactor'
|
|
171
|
-
#
|
|
172
|
-
# class UpdateProfile
|
|
173
|
-
# include Hanami::Interactor
|
|
174
|
-
#
|
|
175
|
-
# def initialize(user, params)
|
|
176
|
-
# @user = user
|
|
177
|
-
# @params = params
|
|
178
|
-
# end
|
|
179
|
-
#
|
|
180
|
-
# def call
|
|
181
|
-
# # ...
|
|
182
|
-
# end
|
|
183
|
-
# end
|
|
184
|
-
def initialize(*args)
|
|
185
|
-
super
|
|
186
|
-
ensure
|
|
187
|
-
@__result = ::Hanami::Interactor::Result.new
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# Triggers the operation and return a result.
|
|
191
|
-
#
|
|
192
|
-
# All the instance variables will be available in the result.
|
|
193
|
-
#
|
|
194
|
-
# ATTENTION: This must be implemented by the including class.
|
|
195
|
-
#
|
|
196
|
-
# @return [Hanami::Interactor::Result] the result of the operation
|
|
197
|
-
#
|
|
198
|
-
# @raise [NoMethodError] if this isn't implemented by the including class.
|
|
199
|
-
#
|
|
200
|
-
# @example Expose instance variables in result payload
|
|
201
|
-
# require 'hanami/interactor'
|
|
202
|
-
#
|
|
203
|
-
# class Signup
|
|
204
|
-
# include Hanami::Interactor
|
|
205
|
-
# expose :user, :params
|
|
206
|
-
#
|
|
207
|
-
# def initialize(params)
|
|
208
|
-
# @params = params
|
|
209
|
-
# @foo = 'bar'
|
|
210
|
-
# end
|
|
211
|
-
#
|
|
212
|
-
# def call
|
|
213
|
-
# @user = UserRepository.new.create(@params)
|
|
214
|
-
# end
|
|
215
|
-
# end
|
|
216
|
-
#
|
|
217
|
-
# result = Signup.new(name: 'Luca').call
|
|
218
|
-
# result.failure? # => false
|
|
219
|
-
# result.successful? # => true
|
|
220
|
-
#
|
|
221
|
-
# result.user # => #<User:0x007fa311105778 @id=1 @name="Luca">
|
|
222
|
-
# result.params # => { :name=>"Luca" }
|
|
223
|
-
# result.foo # => raises NoMethodError
|
|
224
|
-
#
|
|
225
|
-
# @example Failed precondition
|
|
226
|
-
# require 'hanami/interactor'
|
|
227
|
-
#
|
|
228
|
-
# class Signup
|
|
229
|
-
# include Hanami::Interactor
|
|
230
|
-
# expose :user
|
|
231
|
-
#
|
|
232
|
-
# def initialize(params)
|
|
233
|
-
# @params = params
|
|
234
|
-
# end
|
|
235
|
-
#
|
|
236
|
-
# # THIS WON'T BE INVOKED BECAUSE #valid? WILL RETURN false
|
|
237
|
-
# def call
|
|
238
|
-
# @user = UserRepository.new.create(@params)
|
|
239
|
-
# end
|
|
240
|
-
#
|
|
241
|
-
# private
|
|
242
|
-
# def valid?
|
|
243
|
-
# @params.valid?
|
|
244
|
-
# end
|
|
245
|
-
# end
|
|
246
|
-
#
|
|
247
|
-
# result = Signup.new(name: nil).call
|
|
248
|
-
# result.successful? # => false
|
|
249
|
-
# result.failure? # => true
|
|
250
|
-
#
|
|
251
|
-
# result.user # => #<User:0x007fa311105778 @id=nil @name="Luca">
|
|
252
|
-
#
|
|
253
|
-
# @example Bad usage
|
|
254
|
-
# require 'hanami/interactor'
|
|
255
|
-
#
|
|
256
|
-
# class Signup
|
|
257
|
-
# include Hanami::Interactor
|
|
258
|
-
#
|
|
259
|
-
# # Method #call is not defined
|
|
260
|
-
# end
|
|
261
|
-
#
|
|
262
|
-
# Signup.new.call # => NoMethodError
|
|
263
|
-
def call
|
|
264
|
-
_call { super }
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
private
|
|
268
|
-
|
|
269
|
-
# @since 0.3.5
|
|
270
|
-
# @api private
|
|
271
|
-
def _call
|
|
272
|
-
catch :fail do
|
|
273
|
-
validate!
|
|
274
|
-
yield
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
_prepare!
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
# @since 0.3.5
|
|
281
|
-
def validate!
|
|
282
|
-
fail! unless valid?
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Interactor interface
|
|
287
|
-
# @since 1.1.0
|
|
288
|
-
module Interface
|
|
289
|
-
# Triggers the operation and return a result.
|
|
290
|
-
#
|
|
291
|
-
# All the exposed instance variables will be available in the result.
|
|
292
|
-
#
|
|
293
|
-
# ATTENTION: This must be implemented by the including class.
|
|
294
|
-
#
|
|
295
|
-
# @return [Hanami::Interactor::Result] the result of the operation
|
|
296
|
-
#
|
|
297
|
-
# @raise [NoMethodError] if this isn't implemented by the including class.
|
|
298
|
-
#
|
|
299
|
-
# @example Expose instance variables in result payload
|
|
300
|
-
# require 'hanami/interactor'
|
|
301
|
-
#
|
|
302
|
-
# class Signup
|
|
303
|
-
# include Hanami::Interactor
|
|
304
|
-
# expose :user, :params
|
|
305
|
-
#
|
|
306
|
-
# def call(params)
|
|
307
|
-
# @params = params
|
|
308
|
-
# @foo = 'bar'
|
|
309
|
-
# @user = UserRepository.new.persist(User.new(params))
|
|
310
|
-
# end
|
|
311
|
-
# end
|
|
312
|
-
#
|
|
313
|
-
# result = Signup.new(name: 'Luca').call
|
|
314
|
-
# result.failure? # => false
|
|
315
|
-
# result.successful? # => true
|
|
316
|
-
#
|
|
317
|
-
# result.user # => #<User:0x007fa311105778 @id=1 @name="Luca">
|
|
318
|
-
# result.params # => { :name=>"Luca" }
|
|
319
|
-
# result.foo # => raises NoMethodError
|
|
320
|
-
#
|
|
321
|
-
# @example Failed precondition
|
|
322
|
-
# require 'hanami/interactor'
|
|
323
|
-
#
|
|
324
|
-
# class Signup
|
|
325
|
-
# include Hanami::Interactor
|
|
326
|
-
# expose :user
|
|
327
|
-
#
|
|
328
|
-
# # THIS WON'T BE INVOKED BECAUSE #valid? WILL RETURN false
|
|
329
|
-
# def call(params)
|
|
330
|
-
# @user = User.new(params)
|
|
331
|
-
# @user = UserRepository.new.persist(@user)
|
|
332
|
-
# end
|
|
333
|
-
#
|
|
334
|
-
# private
|
|
335
|
-
# def valid?(params)
|
|
336
|
-
# params.valid?
|
|
337
|
-
# end
|
|
338
|
-
# end
|
|
339
|
-
#
|
|
340
|
-
# result = Signup.new.call(name: nil)
|
|
341
|
-
# result.successful? # => false
|
|
342
|
-
# result.failure? # => true
|
|
343
|
-
#
|
|
344
|
-
# result.user # => nil
|
|
345
|
-
#
|
|
346
|
-
# @example Bad usage
|
|
347
|
-
# require 'hanami/interactor'
|
|
348
|
-
#
|
|
349
|
-
# class Signup
|
|
350
|
-
# include Hanami::Interactor
|
|
351
|
-
#
|
|
352
|
-
# # Method #call is not defined
|
|
353
|
-
# end
|
|
354
|
-
#
|
|
355
|
-
# Signup.new.call # => NoMethodError
|
|
356
|
-
def call(*args)
|
|
357
|
-
@__result = ::Hanami::Interactor::Result.new
|
|
358
|
-
_call(*args) { super }
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
private
|
|
362
|
-
|
|
363
|
-
# @api private
|
|
364
|
-
# @since 1.1.0
|
|
365
|
-
def _call(*args)
|
|
366
|
-
catch :fail do
|
|
367
|
-
validate!(*args)
|
|
368
|
-
yield
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
_prepare!
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
# @since 1.1.0
|
|
375
|
-
def validate!(*args)
|
|
376
|
-
fail! unless valid?(*args)
|
|
377
|
-
end
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
private
|
|
381
|
-
|
|
382
|
-
# Check if proceed with <tt>#call</tt> invokation.
|
|
383
|
-
# By default it returns <tt>true</tt>.
|
|
384
|
-
#
|
|
385
|
-
# Developers can override it.
|
|
386
|
-
#
|
|
387
|
-
# @return [TrueClass,FalseClass] the result of the check
|
|
388
|
-
#
|
|
389
|
-
# @since 0.3.5
|
|
390
|
-
def valid?(*)
|
|
391
|
-
true
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
# Fail and interrupt the current flow.
|
|
395
|
-
#
|
|
396
|
-
# @since 0.3.5
|
|
397
|
-
#
|
|
398
|
-
# @example
|
|
399
|
-
# require 'hanami/interactor'
|
|
400
|
-
#
|
|
401
|
-
# class CreateEmailTest
|
|
402
|
-
# include Hanami::Interactor
|
|
403
|
-
#
|
|
404
|
-
# def initialize(params)
|
|
405
|
-
# @params = params
|
|
406
|
-
# end
|
|
407
|
-
#
|
|
408
|
-
# def call
|
|
409
|
-
# persist_email_test!
|
|
410
|
-
# capture_screenshot!
|
|
411
|
-
# end
|
|
412
|
-
#
|
|
413
|
-
# private
|
|
414
|
-
# def persist_email_test!
|
|
415
|
-
# @email_test = EmailTestRepository.new.create(@params)
|
|
416
|
-
# end
|
|
417
|
-
#
|
|
418
|
-
# # IF THIS RAISES AN EXCEPTION WE FORCE A FAILURE
|
|
419
|
-
# def capture_screenshot!
|
|
420
|
-
# Screenshot.new(@email_test).capture!
|
|
421
|
-
# rescue
|
|
422
|
-
# fail!
|
|
423
|
-
# end
|
|
424
|
-
# end
|
|
425
|
-
#
|
|
426
|
-
# result = CreateEmailTest.new(account_id: 1).call
|
|
427
|
-
# result.successful? # => false
|
|
428
|
-
def fail!
|
|
429
|
-
@__result.fail!
|
|
430
|
-
throw :fail
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
# Log an error without interrupting the flow.
|
|
434
|
-
#
|
|
435
|
-
# When used, the returned result won't be successful.
|
|
436
|
-
#
|
|
437
|
-
# @param message [String] the error message
|
|
438
|
-
#
|
|
439
|
-
# @return false
|
|
440
|
-
#
|
|
441
|
-
# @since 0.3.5
|
|
442
|
-
#
|
|
443
|
-
# @see Hanami::Interactor#error!
|
|
444
|
-
#
|
|
445
|
-
# @example
|
|
446
|
-
# require 'hanami/interactor'
|
|
447
|
-
#
|
|
448
|
-
# class CreateRecord
|
|
449
|
-
# include Hanami::Interactor
|
|
450
|
-
# expose :logger
|
|
451
|
-
#
|
|
452
|
-
# def initialize
|
|
453
|
-
# @logger = []
|
|
454
|
-
# end
|
|
455
|
-
#
|
|
456
|
-
# def call
|
|
457
|
-
# prepare_data!
|
|
458
|
-
# persist!
|
|
459
|
-
# sync!
|
|
460
|
-
# end
|
|
461
|
-
#
|
|
462
|
-
# private
|
|
463
|
-
# def prepare_data!
|
|
464
|
-
# @logger << __method__
|
|
465
|
-
# error "Prepare data error"
|
|
466
|
-
# end
|
|
467
|
-
#
|
|
468
|
-
# def persist!
|
|
469
|
-
# @logger << __method__
|
|
470
|
-
# error "Persist error"
|
|
471
|
-
# end
|
|
472
|
-
#
|
|
473
|
-
# def sync!
|
|
474
|
-
# @logger << __method__
|
|
475
|
-
# end
|
|
476
|
-
# end
|
|
477
|
-
#
|
|
478
|
-
# result = CreateRecord.new.call
|
|
479
|
-
# result.successful? # => false
|
|
480
|
-
#
|
|
481
|
-
# result.errors # => ["Prepare data error", "Persist error"]
|
|
482
|
-
# result.logger # => [:prepare_data!, :persist!, :sync!]
|
|
483
|
-
def error(message)
|
|
484
|
-
@__result.add_error message
|
|
485
|
-
false
|
|
486
|
-
end
|
|
487
|
-
|
|
488
|
-
# Log an error AND interrupting the flow.
|
|
489
|
-
#
|
|
490
|
-
# When used, the returned result won't be successful.
|
|
491
|
-
#
|
|
492
|
-
# @param message [String] the error message
|
|
493
|
-
#
|
|
494
|
-
# @since 0.3.5
|
|
495
|
-
#
|
|
496
|
-
# @see Hanami::Interactor#error
|
|
497
|
-
#
|
|
498
|
-
# @example
|
|
499
|
-
# require 'hanami/interactor'
|
|
500
|
-
#
|
|
501
|
-
# class CreateRecord
|
|
502
|
-
# include Hanami::Interactor
|
|
503
|
-
# expose :logger
|
|
504
|
-
#
|
|
505
|
-
# def initialize
|
|
506
|
-
# @logger = []
|
|
507
|
-
# end
|
|
508
|
-
#
|
|
509
|
-
# def call
|
|
510
|
-
# prepare_data!
|
|
511
|
-
# persist!
|
|
512
|
-
# sync!
|
|
513
|
-
# end
|
|
514
|
-
#
|
|
515
|
-
# private
|
|
516
|
-
# def prepare_data!
|
|
517
|
-
# @logger << __method__
|
|
518
|
-
# error "Prepare data error"
|
|
519
|
-
# end
|
|
520
|
-
#
|
|
521
|
-
# def persist!
|
|
522
|
-
# @logger << __method__
|
|
523
|
-
# error! "Persist error"
|
|
524
|
-
# end
|
|
525
|
-
#
|
|
526
|
-
# # THIS WILL NEVER BE INVOKED BECAUSE WE USE #error! IN #persist!
|
|
527
|
-
# def sync!
|
|
528
|
-
# @logger << __method__
|
|
529
|
-
# end
|
|
530
|
-
# end
|
|
531
|
-
#
|
|
532
|
-
# result = CreateRecord.new.call
|
|
533
|
-
# result.successful? # => false
|
|
534
|
-
#
|
|
535
|
-
# result.errors # => ["Prepare data error", "Persist error"]
|
|
536
|
-
# result.logger # => [:prepare_data!, :persist!]
|
|
537
|
-
def error!(message)
|
|
538
|
-
error(message)
|
|
539
|
-
fail!
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
# @since 0.3.5
|
|
543
|
-
# @api private
|
|
544
|
-
def _prepare!
|
|
545
|
-
@__result.prepare!(_exposures)
|
|
546
|
-
end
|
|
547
|
-
|
|
548
|
-
# @since 0.5.0
|
|
549
|
-
# @api private
|
|
550
|
-
def _exposures
|
|
551
|
-
::Hash[].tap do |result|
|
|
552
|
-
self.class.exposures.each do |name, ivar|
|
|
553
|
-
result[name] = instance_variable_defined?(ivar) ? instance_variable_get(ivar) : nil
|
|
554
|
-
end
|
|
555
|
-
end
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
|
|
559
|
-
# @since 0.5.0
|
|
560
|
-
# @api private
|
|
561
|
-
module ClassMethods
|
|
562
|
-
# @since 0.5.0
|
|
563
|
-
# @api private
|
|
564
|
-
def self.extended(interactor)
|
|
565
|
-
interactor.class_eval do
|
|
566
|
-
include Utils::ClassAttribute
|
|
567
|
-
|
|
568
|
-
class_attribute :exposures
|
|
569
|
-
self.exposures = {}
|
|
570
|
-
end
|
|
571
|
-
end
|
|
572
|
-
|
|
573
|
-
def method_added(method_name)
|
|
574
|
-
super
|
|
575
|
-
return unless method_name == :call
|
|
576
|
-
|
|
577
|
-
if instance_method(:call).arity.zero?
|
|
578
|
-
prepend Hanami::Interactor::LegacyInterface
|
|
579
|
-
else
|
|
580
|
-
prepend Hanami::Interactor::Interface
|
|
581
|
-
end
|
|
582
|
-
end
|
|
583
|
-
|
|
584
|
-
# Expose local instance variables into the returning value of <tt>#call</tt>
|
|
585
|
-
#
|
|
586
|
-
# @param instance_variable_names [Symbol,Array<Symbol>] one or more instance
|
|
587
|
-
# variable names
|
|
588
|
-
#
|
|
589
|
-
# @since 0.5.0
|
|
590
|
-
#
|
|
591
|
-
# @see Hanami::Interactor::Result
|
|
592
|
-
#
|
|
593
|
-
# @example Expose instance variable
|
|
594
|
-
#
|
|
595
|
-
# class Signup
|
|
596
|
-
# include Hanami::Interactor
|
|
597
|
-
# expose :user
|
|
598
|
-
#
|
|
599
|
-
# def initialize(params)
|
|
600
|
-
# @params = params
|
|
601
|
-
# @user = User.new(@params[:user])
|
|
602
|
-
# end
|
|
603
|
-
#
|
|
604
|
-
# def call
|
|
605
|
-
# # ...
|
|
606
|
-
# end
|
|
607
|
-
# end
|
|
608
|
-
#
|
|
609
|
-
# result = Signup.new(user: { name: "Luca" }).call
|
|
610
|
-
#
|
|
611
|
-
# result.user # => #<User:0x007fa85c58ccd8 @name="Luca">
|
|
612
|
-
# result.params # => NoMethodError
|
|
613
|
-
def expose(*instance_variable_names)
|
|
614
|
-
instance_variable_names.each do |name|
|
|
615
|
-
exposures[name.to_sym] = "@#{name}"
|
|
616
|
-
end
|
|
617
|
-
end
|
|
618
|
-
end
|
|
619
|
-
end
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "logger"
|
|
4
|
-
require "hanami/utils/shell_color"
|
|
5
|
-
|
|
6
|
-
module Hanami
|
|
7
|
-
class Logger < ::Logger
|
|
8
|
-
# Null colorizer for logger streams that aren't a TTY (eg. files)
|
|
9
|
-
#
|
|
10
|
-
# @since 1.2.0
|
|
11
|
-
# @api private
|
|
12
|
-
class NullColorizer
|
|
13
|
-
# @since 1.2.0
|
|
14
|
-
# @api private
|
|
15
|
-
def call(app, severity, datetime, _progname)
|
|
16
|
-
::Hash[
|
|
17
|
-
app: app,
|
|
18
|
-
severity: severity,
|
|
19
|
-
time: datetime,
|
|
20
|
-
]
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Hanami::Logger Default Colorizer
|
|
25
|
-
#
|
|
26
|
-
# This colorizer takes in parts of the log message and returns them with
|
|
27
|
-
# proper shellcode to colorize when displayed to a tty.
|
|
28
|
-
#
|
|
29
|
-
# @since 1.2.0
|
|
30
|
-
# @api private
|
|
31
|
-
class Colorizer < NullColorizer
|
|
32
|
-
def initialize(colors: COLORS)
|
|
33
|
-
@colors = colors
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Colorize the inputs
|
|
37
|
-
#
|
|
38
|
-
# @param app [#to_s] the app name
|
|
39
|
-
# @param severity [#to_s] log severity
|
|
40
|
-
# @param datetime [#to_s] timestamp
|
|
41
|
-
# @param _progname [#to_s] program name - ignored, accepted for
|
|
42
|
-
# compatibility with Ruby's Logger
|
|
43
|
-
#
|
|
44
|
-
# @return [::Hash] an Hash containing the keys `:app`, `:severity`, and `:time`
|
|
45
|
-
def call(app, severity, datetime, _progname)
|
|
46
|
-
::Hash[
|
|
47
|
-
app: app(app),
|
|
48
|
-
severity: severity(severity),
|
|
49
|
-
time: datetime(datetime),
|
|
50
|
-
]
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
private
|
|
54
|
-
|
|
55
|
-
# The colors defined for the three parts of the log message
|
|
56
|
-
#
|
|
57
|
-
# @since 1.2.0
|
|
58
|
-
# @api private
|
|
59
|
-
COLORS = ::Hash[
|
|
60
|
-
app: :blue,
|
|
61
|
-
datetime: :cyan,
|
|
62
|
-
].freeze
|
|
63
|
-
|
|
64
|
-
# @since 1.2.0
|
|
65
|
-
# @api private
|
|
66
|
-
LEVELS = ::Hash[
|
|
67
|
-
Hanami::Logger::DEBUG => :cyan,
|
|
68
|
-
Hanami::Logger::INFO => :magenta,
|
|
69
|
-
Hanami::Logger::WARN => :yellow,
|
|
70
|
-
Hanami::Logger::ERROR => :red,
|
|
71
|
-
Hanami::Logger::FATAL => :red,
|
|
72
|
-
Hanami::Logger::UNKNOWN => :blue,
|
|
73
|
-
].freeze
|
|
74
|
-
|
|
75
|
-
attr_reader :colors
|
|
76
|
-
|
|
77
|
-
# @since 1.2.0
|
|
78
|
-
# @api private
|
|
79
|
-
def app(input)
|
|
80
|
-
colorize(input, color: colors.fetch(:app, nil))
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# @since 1.2.0
|
|
84
|
-
# @api private
|
|
85
|
-
def severity(input)
|
|
86
|
-
color = LEVELS.fetch(Hanami::Logger.level(input), :gray)
|
|
87
|
-
colorize(input, color: color)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# @since 1.2.0
|
|
91
|
-
# @api private
|
|
92
|
-
def datetime(input)
|
|
93
|
-
colorize(input, color: colors.fetch(:datetime, nil))
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# @since 1.2.0
|
|
97
|
-
# @api private
|
|
98
|
-
def colorize(message, color:)
|
|
99
|
-
return message if color.nil?
|
|
100
|
-
|
|
101
|
-
Hanami::Utils::ShellColor.call(message, color: color)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|