hanami-utils 1.3.8 → 2.0.0.alpha1
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 +14 -33
- data/README.md +5 -13
- data/hanami-utils.gemspec +3 -4
- data/lib/hanami/interactor.rb +33 -65
- data/lib/hanami/logger.rb +12 -12
- data/lib/hanami/logger/colorizer.rb +10 -10
- data/lib/hanami/logger/filter.rb +10 -89
- data/lib/hanami/logger/formatter.rb +7 -7
- data/lib/hanami/middleware.rb +11 -0
- data/lib/hanami/utils.rb +3 -19
- data/lib/hanami/utils/basic_object.rb +3 -63
- data/lib/hanami/utils/blank.rb +6 -8
- data/lib/hanami/utils/callbacks.rb +20 -5
- data/lib/hanami/utils/class.rb +3 -52
- data/lib/hanami/utils/class_attribute.rb +22 -13
- data/lib/hanami/utils/class_attribute/attributes.rb +45 -0
- data/lib/hanami/utils/escape.rb +170 -172
- data/lib/hanami/utils/file_list.rb +1 -1
- data/lib/hanami/utils/files.rb +2 -31
- data/lib/hanami/utils/hash.rb +12 -341
- data/lib/hanami/utils/json.rb +1 -1
- data/lib/hanami/utils/kernel.rb +12 -11
- data/lib/hanami/utils/load_paths.rb +3 -3
- data/lib/hanami/utils/query_string.rb +1 -1
- data/lib/hanami/utils/shell_color.rb +9 -9
- data/lib/hanami/utils/string.rb +38 -102
- data/lib/hanami/utils/version.rb +1 -1
- metadata +12 -26
- data/lib/hanami/utils/duplicable.rb +0 -82
- data/lib/hanami/utils/inflector.rb +0 -493
@@ -6,7 +6,7 @@ module Hanami
|
|
6
6
|
#
|
7
7
|
# @since 0.9.0
|
8
8
|
module FileList
|
9
|
-
#
|
9
|
+
# Return an ordered list of files, consistent across operating systems
|
10
10
|
#
|
11
11
|
# It has the same signature of <tt>Dir.glob</tt>, it just guarantees to
|
12
12
|
# order the results before to return them.
|
data/lib/hanami/utils/files.rb
CHANGED
@@ -34,24 +34,6 @@ module Hanami
|
|
34
34
|
open(path, ::File::CREAT | ::File::WRONLY | ::File::TRUNC, *content) # rubocop:disable Security/Open - this isn't a call to `::Kernel.open`, but to `self.open`
|
35
35
|
end
|
36
36
|
|
37
|
-
# Rewrites the contents of an existing file.
|
38
|
-
# If the path already exists, it replaces the contents.
|
39
|
-
#
|
40
|
-
# @param path [String,Pathname] the path to file
|
41
|
-
# @param content [String, Array<String>] the content to write
|
42
|
-
#
|
43
|
-
# @raise [Errno::ENOENT] if the path doesn't exist
|
44
|
-
#
|
45
|
-
# @since 1.1.0
|
46
|
-
def self.rewrite(path, *content)
|
47
|
-
Hanami::Utils::Deprecation.new(
|
48
|
-
"`.rewrite' is deprecated, please use `.write'"
|
49
|
-
)
|
50
|
-
raise Errno::ENOENT unless File.exist?(path)
|
51
|
-
|
52
|
-
write(path, *content)
|
53
|
-
end
|
54
|
-
|
55
37
|
# Copies source into destination.
|
56
38
|
# All the intermediate directories are created.
|
57
39
|
# If the destination already exists, it overrides the contents.
|
@@ -165,7 +147,6 @@ module Hanami
|
|
165
147
|
mkdir_p(path)
|
166
148
|
|
167
149
|
content = ::File.readlines(path)
|
168
|
-
content << "\n" if _append_newline?(content)
|
169
150
|
content << "#{contents}\n"
|
170
151
|
|
171
152
|
write(path, content)
|
@@ -326,12 +307,12 @@ module Hanami
|
|
326
307
|
#
|
327
308
|
# # class App
|
328
309
|
# # end
|
329
|
-
def self.remove_block(path, target)
|
310
|
+
def self.remove_block(path, target) # rubocop:disable Metrics/AbcSize
|
330
311
|
content = ::File.readlines(path)
|
331
312
|
starting = index(content, path, target)
|
332
313
|
line = content[starting]
|
333
314
|
size = line[/\A[[:space:]]*/].bytesize
|
334
|
-
closing = (" " * size) + (
|
315
|
+
closing = (" " * size) + (/{/.match?(target) ? "}" : "end")
|
335
316
|
ending = starting + index(content[starting..-1], path, closing)
|
336
317
|
|
337
318
|
content.slice!(starting..ending)
|
@@ -454,16 +435,6 @@ module Hanami
|
|
454
435
|
end
|
455
436
|
|
456
437
|
private_class_method :line_number
|
457
|
-
|
458
|
-
# @since 1.3.6
|
459
|
-
# @api private
|
460
|
-
def self._append_newline?(content)
|
461
|
-
return false if content.empty?
|
462
|
-
|
463
|
-
!content.last.end_with?("\n")
|
464
|
-
end
|
465
|
-
|
466
|
-
private_class_method :_append_newline?
|
467
438
|
end
|
468
439
|
end
|
469
440
|
end
|
data/lib/hanami/utils/hash.rb
CHANGED
@@ -1,28 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "hanami/utils/duplicable"
|
4
3
|
require "transproc"
|
5
4
|
|
6
5
|
module Hanami
|
7
6
|
module Utils
|
8
|
-
# Hash
|
7
|
+
# Hash transformations
|
9
8
|
# @since 0.1.0
|
10
|
-
|
11
|
-
class Hash
|
12
|
-
# @since 0.6.0
|
13
|
-
# @api private
|
14
|
-
#
|
15
|
-
# @see Hanami::Utils::Hash#deep_dup
|
16
|
-
# @see Hanami::Utils::Duplicable
|
17
|
-
DUPLICATE_LOGIC = proc do |value|
|
18
|
-
case value
|
19
|
-
when Hash
|
20
|
-
value.deep_dup
|
21
|
-
when ::Hash
|
22
|
-
Hash.new(value).deep_dup.to_h
|
23
|
-
end
|
24
|
-
end.freeze
|
25
|
-
|
9
|
+
module Hash
|
26
10
|
extend Transproc::Registry
|
27
11
|
import Transproc::HashTransformations
|
28
12
|
|
@@ -48,7 +32,7 @@ module Hanami
|
|
48
32
|
self[:symbolize_keys].call(input)
|
49
33
|
end
|
50
34
|
|
51
|
-
#
|
35
|
+
# Deep symbolize the given hash
|
52
36
|
#
|
53
37
|
# @param input [::Hash] the input
|
54
38
|
#
|
@@ -70,7 +54,7 @@ module Hanami
|
|
70
54
|
self[:deep_symbolize_keys].call(input)
|
71
55
|
end
|
72
56
|
|
73
|
-
#
|
57
|
+
# Stringify the given hash
|
74
58
|
#
|
75
59
|
# @param input [::Hash] the input
|
76
60
|
#
|
@@ -90,7 +74,7 @@ module Hanami
|
|
90
74
|
self[:stringify_keys].call(input)
|
91
75
|
end
|
92
76
|
|
93
|
-
# Deeply
|
77
|
+
# Deeply stringify the given hash
|
94
78
|
#
|
95
79
|
# @param input [::Hash] the input
|
96
80
|
#
|
@@ -106,7 +90,7 @@ module Hanami
|
|
106
90
|
#
|
107
91
|
# hash.class
|
108
92
|
# # => Hash
|
109
|
-
def self.deep_stringify(input)
|
93
|
+
def self.deep_stringify(input) # rubocop:disable Metrics/MethodLength
|
110
94
|
input.each_with_object({}) do |(key, value), output|
|
111
95
|
output[key.to_s] =
|
112
96
|
case value
|
@@ -122,15 +106,15 @@ module Hanami
|
|
122
106
|
end
|
123
107
|
end
|
124
108
|
|
125
|
-
# Deep
|
109
|
+
# Deep duplicate hash values
|
126
110
|
#
|
127
|
-
# The output of this function is a
|
111
|
+
# The output of this function is a shallow duplicate of the input.
|
128
112
|
# Any further modification on the input, won't be reflected on the output
|
129
113
|
# and viceversa.
|
130
114
|
#
|
131
115
|
# @param input [::Hash] the input
|
132
116
|
#
|
133
|
-
# @return [::Hash] the
|
117
|
+
# @return [::Hash] the shallow duplicate of input
|
134
118
|
#
|
135
119
|
# @since 1.0.1
|
136
120
|
#
|
@@ -165,12 +149,12 @@ module Hanami
|
|
165
149
|
when ::Hash
|
166
150
|
deep_dup(v)
|
167
151
|
else
|
168
|
-
|
152
|
+
v.dup
|
169
153
|
end
|
170
154
|
end
|
171
155
|
end
|
172
156
|
|
173
|
-
# Deep
|
157
|
+
# Deep serialize given object into a `Hash`
|
174
158
|
#
|
175
159
|
# Please note that the returning `Hash` will use symbols as keys.
|
176
160
|
#
|
@@ -194,7 +178,7 @@ module Hanami
|
|
194
178
|
#
|
195
179
|
# Hanami::Utils::Hash.deep_serialize(input)
|
196
180
|
# # => {:foo=>"bar", :baz=>[{:hello=>"world"}]}
|
197
|
-
def self.deep_serialize(input)
|
181
|
+
def self.deep_serialize(input) # rubocop:disable Metrics/MethodLength
|
198
182
|
input.to_hash.each_with_object({}) do |(key, value), output|
|
199
183
|
output[key.to_sym] =
|
200
184
|
case value
|
@@ -209,319 +193,6 @@ module Hanami
|
|
209
193
|
end
|
210
194
|
end
|
211
195
|
end
|
212
|
-
|
213
|
-
# Initialize the hash
|
214
|
-
#
|
215
|
-
# @param hash [#to_h] the value we want to use to initialize this instance
|
216
|
-
# @param blk [Proc] define the default value
|
217
|
-
#
|
218
|
-
# @return [Hanami::Utils::Hash] self
|
219
|
-
#
|
220
|
-
# @since 0.1.0
|
221
|
-
# @deprecated
|
222
|
-
#
|
223
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-c-5B-5D
|
224
|
-
#
|
225
|
-
# @example Passing a Hash
|
226
|
-
# require 'hanami/utils/hash'
|
227
|
-
#
|
228
|
-
# hash = Hanami::Utils::Hash.new('l' => 23)
|
229
|
-
# hash['l'] # => 23
|
230
|
-
#
|
231
|
-
# @example Passing a block for default
|
232
|
-
# require 'hanami/utils/hash'
|
233
|
-
#
|
234
|
-
# hash = Hanami::Utils::Hash.new {|h,k| h[k] = [] }
|
235
|
-
# hash['foo'].push 'bar'
|
236
|
-
#
|
237
|
-
# hash.to_h # => { 'foo' => ['bar'] }
|
238
|
-
def initialize(hash = {}, &blk)
|
239
|
-
@hash = hash.to_hash
|
240
|
-
@hash.default_proc = blk if blk
|
241
|
-
end
|
242
|
-
|
243
|
-
# Converts in-place all the keys to Symbol instances.
|
244
|
-
#
|
245
|
-
# @return [Hash] self
|
246
|
-
#
|
247
|
-
# @since 0.1.0
|
248
|
-
# @deprecated Use {Hanami::Utils::Hash.symbolize}
|
249
|
-
#
|
250
|
-
# @example
|
251
|
-
# require 'hanami/utils/hash'
|
252
|
-
#
|
253
|
-
# hash = Hanami::Utils::Hash.new 'a' => 23, 'b' => { 'c' => ['x','y','z'] }
|
254
|
-
# hash.symbolize!
|
255
|
-
#
|
256
|
-
# hash.keys # => [:a, :b]
|
257
|
-
# hash.inspect # => { :a => 23, :b => { 'c' => ["x", "y", "z"] } }
|
258
|
-
def symbolize!
|
259
|
-
keys.each do |k|
|
260
|
-
v = delete(k)
|
261
|
-
self[k.to_sym] = v
|
262
|
-
end
|
263
|
-
|
264
|
-
self
|
265
|
-
end
|
266
|
-
|
267
|
-
# Converts in-place all the keys to Symbol instances, nested hashes are converted too.
|
268
|
-
#
|
269
|
-
# @return [Hash] self
|
270
|
-
#
|
271
|
-
# @since 1.0.0
|
272
|
-
# @deprecated Use {Hanami::Utils::Hash.deep_symbolize}
|
273
|
-
#
|
274
|
-
# @example
|
275
|
-
# require 'hanami/utils/hash'
|
276
|
-
#
|
277
|
-
# hash = Hanami::Utils::Hash.new 'a' => 23, 'b' => { 'c' => ['x','y','z'] }
|
278
|
-
# hash.deep_symbolize!
|
279
|
-
#
|
280
|
-
# hash.keys # => [:a, :b]
|
281
|
-
# hash.inspect # => {:a=>23, :b=>{:c=>["x", "y", "z"]}}
|
282
|
-
def deep_symbolize!
|
283
|
-
keys.each do |k|
|
284
|
-
v = delete(k)
|
285
|
-
v = self.class.new(v).deep_symbolize! if v.respond_to?(:to_hash)
|
286
|
-
|
287
|
-
self[k.to_sym] = v
|
288
|
-
end
|
289
|
-
|
290
|
-
self
|
291
|
-
end
|
292
|
-
|
293
|
-
# Converts in-place all the keys to Symbol instances, nested hashes are converted too.
|
294
|
-
#
|
295
|
-
# @return [Hash] self
|
296
|
-
#
|
297
|
-
# @since 0.3.2
|
298
|
-
# @deprecated Use {Hanami::Utils::Hash.stringify}
|
299
|
-
#
|
300
|
-
# @example
|
301
|
-
# require 'hanami/utils/hash'
|
302
|
-
#
|
303
|
-
# hash = Hanami::Utils::Hash.new a: 23, b: { c: ['x','y','z'] }
|
304
|
-
# hash.stringify!
|
305
|
-
#
|
306
|
-
# hash.keys # => [:a, :b]
|
307
|
-
# hash.inspect # => {"a"=>23, "b"=>{"c"=>["x", "y", "z"]}}
|
308
|
-
def stringify!
|
309
|
-
keys.each do |k|
|
310
|
-
v = delete(k)
|
311
|
-
v = self.class.new(v).stringify! if v.respond_to?(:to_hash)
|
312
|
-
|
313
|
-
self[k.to_s] = v
|
314
|
-
end
|
315
|
-
|
316
|
-
self
|
317
|
-
end
|
318
|
-
|
319
|
-
# Returns a deep copy of the current Hanami::Utils::Hash
|
320
|
-
#
|
321
|
-
# @return [Hash] a deep duplicated self
|
322
|
-
#
|
323
|
-
# @since 0.3.1
|
324
|
-
# @deprecated Use {Hanami::Utils::Hash.deep_dup}
|
325
|
-
#
|
326
|
-
# @example
|
327
|
-
# require 'hanami/utils/hash'
|
328
|
-
#
|
329
|
-
# hash = Hanami::Utils::Hash.new(
|
330
|
-
# 'nil' => nil,
|
331
|
-
# 'false' => false,
|
332
|
-
# 'true' => true,
|
333
|
-
# 'symbol' => :foo,
|
334
|
-
# 'fixnum' => 23,
|
335
|
-
# 'bignum' => 13289301283 ** 2,
|
336
|
-
# 'float' => 1.0,
|
337
|
-
# 'complex' => Complex(0.3),
|
338
|
-
# 'bigdecimal' => BigDecimal('12.0001'),
|
339
|
-
# 'rational' => Rational(0.3),
|
340
|
-
# 'string' => 'foo bar',
|
341
|
-
# 'hash' => { a: 1, b: 'two', c: :three },
|
342
|
-
# 'u_hash' => Hanami::Utils::Hash.new({ a: 1, b: 'two', c: :three })
|
343
|
-
# )
|
344
|
-
#
|
345
|
-
# duped = hash.deep_dup
|
346
|
-
#
|
347
|
-
# hash.class # => Hanami::Utils::Hash
|
348
|
-
# duped.class # => Hanami::Utils::Hash
|
349
|
-
#
|
350
|
-
# hash.object_id # => 70147385937100
|
351
|
-
# duped.object_id # => 70147385950620
|
352
|
-
#
|
353
|
-
# # unduplicated values
|
354
|
-
# duped['nil'] # => nil
|
355
|
-
# duped['false'] # => false
|
356
|
-
# duped['true'] # => true
|
357
|
-
# duped['symbol'] # => :foo
|
358
|
-
# duped['fixnum'] # => 23
|
359
|
-
# duped['bignum'] # => 176605528590345446089
|
360
|
-
# duped['float'] # => 1.0
|
361
|
-
# duped['complex'] # => (0.3+0i)
|
362
|
-
# duped['bigdecimal'] # => #<BigDecimal:7f9ffe6e2fd0,'0.120001E2',18(18)>
|
363
|
-
# duped['rational'] # => 5404319552844595/18014398509481984)
|
364
|
-
#
|
365
|
-
# # it duplicates values
|
366
|
-
# duped['string'].reverse!
|
367
|
-
# duped['string'] # => "rab oof"
|
368
|
-
# hash['string'] # => "foo bar"
|
369
|
-
#
|
370
|
-
# # it deeply duplicates Hash, by preserving the class
|
371
|
-
# duped['hash'].class # => Hash
|
372
|
-
# duped['hash'].delete(:a)
|
373
|
-
# hash['hash'][:a] # => 1
|
374
|
-
#
|
375
|
-
# duped['hash'][:b].upcase!
|
376
|
-
# duped['hash'][:b] # => "TWO"
|
377
|
-
# hash['hash'][:b] # => "two"
|
378
|
-
#
|
379
|
-
# # it deeply duplicates Hanami::Utils::Hash, by preserving the class
|
380
|
-
# duped['u_hash'].class # => Hanami::Utils::Hash
|
381
|
-
def deep_dup
|
382
|
-
self.class.new.tap do |result|
|
383
|
-
@hash.each { |k, v| result[k] = Duplicable.dup(v, &DUPLICATE_LOGIC) }
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
# Returns a new array populated with the keys from this hash
|
388
|
-
#
|
389
|
-
# @return [Array] the keys
|
390
|
-
#
|
391
|
-
# @since 0.3.0
|
392
|
-
# @deprecated
|
393
|
-
#
|
394
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-i-keys
|
395
|
-
def keys
|
396
|
-
@hash.keys
|
397
|
-
end
|
398
|
-
|
399
|
-
# Deletes the key-value pair and returns the value from hsh whose key is
|
400
|
-
# equal to key.
|
401
|
-
#
|
402
|
-
# @param key [Object] the key to remove
|
403
|
-
#
|
404
|
-
# @return [Object,nil] the value hold by the given key, if present
|
405
|
-
#
|
406
|
-
# @since 0.3.0
|
407
|
-
# @deprecated
|
408
|
-
#
|
409
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-i-keys
|
410
|
-
def delete(key)
|
411
|
-
@hash.delete(key)
|
412
|
-
end
|
413
|
-
|
414
|
-
# Retrieves the value object corresponding to the key object.
|
415
|
-
#
|
416
|
-
# @param key [Object] the key
|
417
|
-
#
|
418
|
-
# @return [Object,nil] the correspoding value, if present
|
419
|
-
#
|
420
|
-
# @since 0.3.0
|
421
|
-
# @deprecated
|
422
|
-
#
|
423
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-i-5B-5D
|
424
|
-
def [](key)
|
425
|
-
@hash[key]
|
426
|
-
end
|
427
|
-
|
428
|
-
# Associates the value given by value with the key given by key.
|
429
|
-
#
|
430
|
-
# @param key [Object] the key to assign
|
431
|
-
# @param value [Object] the value to assign
|
432
|
-
#
|
433
|
-
# @since 0.3.0
|
434
|
-
# @deprecated
|
435
|
-
#
|
436
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-i-5B-5D-3D
|
437
|
-
def []=(key, value)
|
438
|
-
@hash[key] = value
|
439
|
-
end
|
440
|
-
|
441
|
-
# Returns a Ruby Hash as duplicated version of self
|
442
|
-
#
|
443
|
-
# @return [::Hash] the hash
|
444
|
-
#
|
445
|
-
# @since 0.3.0
|
446
|
-
# @deprecated
|
447
|
-
#
|
448
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-i-to_h
|
449
|
-
def to_h
|
450
|
-
@hash.each_with_object({}) do |(k, v), result|
|
451
|
-
v = v.to_h if v.respond_to?(:to_hash)
|
452
|
-
result[k] = v
|
453
|
-
end
|
454
|
-
end
|
455
|
-
|
456
|
-
alias_method :to_hash, :to_h
|
457
|
-
|
458
|
-
# Converts into a nested array of [ key, value ] arrays.
|
459
|
-
#
|
460
|
-
# @return [::Array] the array
|
461
|
-
#
|
462
|
-
# @since 0.3.0
|
463
|
-
# @deprecated
|
464
|
-
#
|
465
|
-
# @see http://www.ruby-doc.org/core/Hash.html#method-i-to_a
|
466
|
-
def to_a
|
467
|
-
@hash.to_a
|
468
|
-
end
|
469
|
-
|
470
|
-
# Equality
|
471
|
-
#
|
472
|
-
# @return [TrueClass,FalseClass]
|
473
|
-
#
|
474
|
-
# @since 0.3.0
|
475
|
-
# @deprecated
|
476
|
-
def ==(other)
|
477
|
-
@hash == other.to_h
|
478
|
-
end
|
479
|
-
|
480
|
-
alias_method :eql?, :==
|
481
|
-
|
482
|
-
# Returns the hash of the internal @hash
|
483
|
-
#
|
484
|
-
# @return [Fixnum]
|
485
|
-
#
|
486
|
-
# @since 0.3.0
|
487
|
-
# @deprecated
|
488
|
-
def hash
|
489
|
-
@hash.hash
|
490
|
-
end
|
491
|
-
|
492
|
-
# Returns a string describing the internal @hash
|
493
|
-
#
|
494
|
-
# @return [String]
|
495
|
-
#
|
496
|
-
# @since 0.3.0
|
497
|
-
# @deprecated
|
498
|
-
def inspect
|
499
|
-
@hash.inspect
|
500
|
-
end
|
501
|
-
|
502
|
-
# Overrides Ruby's method_missing in order to provide ::Hash interface
|
503
|
-
#
|
504
|
-
# @api private
|
505
|
-
# @since 0.3.0
|
506
|
-
#
|
507
|
-
# @raise [NoMethodError] If doesn't respond to the given method
|
508
|
-
def method_missing(method_name, *args, &blk)
|
509
|
-
unless respond_to?(method_name)
|
510
|
-
raise NoMethodError.new(%(undefined method `#{method_name}' for #{@hash}:#{self.class}))
|
511
|
-
end
|
512
|
-
|
513
|
-
h = @hash.__send__(method_name, *args, &blk)
|
514
|
-
h = self.class.new(h) if h.is_a?(::Hash)
|
515
|
-
h
|
516
|
-
end
|
517
|
-
|
518
|
-
# Overrides Ruby's respond_to_missing? in order to support ::Hash interface
|
519
|
-
#
|
520
|
-
# @api private
|
521
|
-
# @since 0.3.0
|
522
|
-
def respond_to_missing?(method_name, include_private = false)
|
523
|
-
@hash.respond_to?(method_name, include_private)
|
524
|
-
end
|
525
196
|
end
|
526
197
|
end
|
527
198
|
end
|