hanami-utils 1.3.6 → 1.3.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e6573938b28f1b4f3b8f46aebec53e487d0af4e85087a65d5e081c4fdc2f030
4
- data.tar.gz: e2d13a7d2a675633a7b984882d7c01c5963b3933f1d9339b871ed20838b630c9
3
+ metadata.gz: '02818d90409ea03d89ca587c97fe418bbf17a8694662a2313609c0710466b0f9'
4
+ data.tar.gz: 973ef420992dd9ea30ab880d43e8cc70eee59cae6fb7b1ba17038c5ce8d536a4
5
5
  SHA512:
6
- metadata.gz: f8255168597fd310d075400c0a926b28f7bea6dd2025b1572d065e8df7e7ecfa76f991dc88afa1be37b3dfa57b06e70332015018e724ad7731184329a1cab559
7
- data.tar.gz: 4ff3e862379db3b02d1fecace8336ed0f44df2b98c9588f807f46883b3b0e7a862beac8119da7428b07484802842b09aca509e1d01ee9dc25360438847d94f63
6
+ metadata.gz: d49d6ad21aa25f285c9165c4619d6b2d7fe348513481bf30b8f231211d4e270f7502e2e3594f082789fdf32e9170a33e038329394ae5f43170ab778ebe01892f
7
+ data.tar.gz: 8b8832a39855525d6818de385212fb1c9d7c5c0f79874f60ead95ee1c592377f6bfec0ade5701a4340b87fe920c495889a9586d81fe2091d8691b52b14f297fa
@@ -1,6 +1,14 @@
1
1
  # Hanami::Utils
2
2
  Ruby core extentions and class utilities for Hanami
3
3
 
4
+ ## v1.3.7 - 2021-01-04
5
+ ### Added
6
+ - [Luca Guidi] Official support for Ruby: MRI 3.0
7
+ - [Khai Le] Allow `Hanami::Logger` to filter sensitive data for an array of hashes
8
+
9
+ ### Fixed
10
+ - [Hiếu Nguyễn] Ensure `Hanami::Logger` to not mutate `Hash` input when filtering sensitive data
11
+
4
12
  ## v1.3.6 - 2020-01-07
5
13
  ### Added
6
14
  - [Luca Guidi] Official support for Ruby: MRI 2.7
data/README.md CHANGED
@@ -5,8 +5,7 @@ Ruby core extensions and class utilities for [Hanami](http://hanamirb.org)
5
5
  ## Status
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/hanami-utils.svg)](https://badge.fury.io/rb/hanami-utils)
8
- [![Build Status](https://ci.hanamirb.org/api/badges/hanami/utils/status.svg)](https://ci.hanamirb.org/hanami/utils)
9
- [![CircleCI](https://circleci.com/gh/hanami/utils/tree/master.svg?style=svg)](https://circleci.com/gh/hanami/utils/tree/master)
8
+ [![CI](https://github.com/hanami/utils/workflows/ci/badge.svg?branch=master)](https://github.com/hanami/utils/actions?query=workflow%3Aci+branch%3Amaster)
10
9
  [![Test Coverage](https://codecov.io/gh/hanami/utils/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/utils)
11
10
  [![Depfu](https://badges.depfu.com/badges/a8545fb67cf32a2c75b6227bc0821027/overview.svg)](https://depfu.com/github/hanami/utils?project=Bundler)
12
11
  [![Inline Docs](http://inch-ci.org/github/hanami/utils.svg)](http://inch-ci.org/github/hanami/utils)
@@ -150,6 +149,6 @@ __Hanami::Utils__ uses [Semantic Versioning 2.0.0](http://semver.org)
150
149
 
151
150
  ## Copyright
152
151
 
153
- Copyright © 2014-2017 Luca Guidi – Released under MIT License
152
+ Copyright © 2014-2021 Luca Guidi – Released under MIT License
154
153
 
155
154
  This project was formerly known as Lotus (`lotus-utils`).
@@ -1,27 +1,30 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'hanami/utils/version'
5
+ require "hanami/utils/version"
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = 'hanami-utils'
8
+ spec.name = "hanami-utils"
7
9
  spec.version = Hanami::Utils::VERSION
8
- spec.authors = ['Luca Guidi']
9
- spec.email = ['me@lucaguidi.com']
10
- spec.description = 'Hanami utilities'
11
- spec.summary = 'Ruby core extentions and Hanami utilities'
12
- spec.homepage = 'http://hanamirb.org'
13
- spec.license = 'MIT'
10
+ spec.authors = ["Luca Guidi"]
11
+ spec.email = ["me@lucaguidi.com"]
12
+ spec.description = "Hanami utilities"
13
+ spec.summary = "Ruby core extentions and Hanami utilities"
14
+ spec.homepage = "http://hanamirb.org"
15
+ spec.license = "MIT"
14
16
 
15
17
  spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-utils.gemspec`.split($/)
16
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ['lib']
19
- spec.required_ruby_version = '>= 2.3.0'
20
+ spec.require_paths = ["lib"]
21
+ spec.required_ruby_version = ">= 2.3.0"
20
22
 
21
- spec.add_dependency 'transproc', '~> 1.0'
22
- spec.add_dependency 'concurrent-ruby', '~> 1.0'
23
+ spec.add_dependency "transproc", "~> 1.0"
24
+ spec.add_dependency "concurrent-ruby", "~> 1.0"
23
25
 
24
- spec.add_development_dependency 'bundler', '>= 1.6', '< 3'
25
- spec.add_development_dependency 'rake', '~> 13'
26
- spec.add_development_dependency 'rspec', '~> 3.7'
26
+ spec.add_development_dependency "bundler", ">= 1.6", "< 3"
27
+ spec.add_development_dependency "rake", "~> 13"
28
+ spec.add_development_dependency "rspec", "~> 3.9"
29
+ spec.add_development_dependency "rubocop", "0.81" # rubocop 0.81+ removed support for Ruby 2.3
27
30
  end
@@ -1 +1,3 @@
1
- require 'hanami/utils'
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/utils"
@@ -1,6 +1,8 @@
1
- require 'hanami/utils/basic_object'
2
- require 'hanami/utils/class_attribute'
3
- require 'hanami/utils/hash'
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/utils/basic_object"
4
+ require "hanami/utils/class_attribute"
5
+ require "hanami/utils/hash"
4
6
 
5
7
  module Hanami
6
8
  # Hanami Interactor
@@ -17,14 +19,14 @@ module Hanami
17
19
  # @api private
18
20
  #
19
21
  # @see Hanami::Interactor::Result#respond_to_missing?
20
- METHODS = ::Hash[initialize: true,
21
- success?: true,
22
+ METHODS = ::Hash[initialize: true,
23
+ success?: true,
22
24
  successful?: true,
23
- failure?: true,
24
- fail!: true,
25
- prepare!: true,
26
- errors: true,
27
- error: true].freeze
25
+ failure?: true,
26
+ fail!: true,
27
+ prepare!: true,
28
+ errors: true,
29
+ error: true].freeze
28
30
 
29
31
  # Initialize a new result
30
32
  #
@@ -50,7 +52,7 @@ module Hanami
50
52
  end
51
53
 
52
54
  # @since 0.3.5
53
- alias success? successful?
55
+ alias_method :success?, :successful?
54
56
 
55
57
  # Checks if the current status is not successful
56
58
  #
@@ -351,27 +353,51 @@ module Hanami
351
353
  # end
352
354
  #
353
355
  # Signup.new.call # => NoMethodError
354
- def call(*args)
355
- @__result = ::Hanami::Interactor::Result.new
356
- _call(*args) { super }
356
+ if RUBY_VERSION >= "3.0"
357
+ def call(*args, **kwargs)
358
+ @__result = ::Hanami::Interactor::Result.new
359
+ _call(*args, **kwargs) { super }
360
+ end
361
+ else
362
+ def call(*args)
363
+ @__result = ::Hanami::Interactor::Result.new
364
+ _call(*args) { super }
365
+ end
357
366
  end
358
367
 
359
368
  private
360
369
 
361
370
  # @api private
362
371
  # @since 1.1.0
363
- def _call(*args)
364
- catch :fail do
365
- validate!(*args)
366
- yield
372
+ if RUBY_VERSION >= "3.0"
373
+ def _call(*args, **kwargs)
374
+ catch :fail do
375
+ validate!(*args, **kwargs)
376
+ yield
377
+ end
378
+
379
+ _prepare!
367
380
  end
381
+ else
382
+ def _call(*args)
383
+ catch :fail do
384
+ validate!(*args)
385
+ yield
386
+ end
368
387
 
369
- _prepare!
388
+ _prepare!
389
+ end
370
390
  end
371
391
 
372
392
  # @since 1.1.0
373
- def validate!(*args)
374
- fail! unless valid?(*args)
393
+ if RUBY_VERSION >= "3.0"
394
+ def validate!(*args, **kwargs)
395
+ fail! unless valid?(*args, **kwargs)
396
+ end
397
+ else
398
+ def validate!(*args)
399
+ fail! unless valid?(*args)
400
+ end
375
401
  end
376
402
  end
377
403
 
@@ -132,11 +132,11 @@ module Hanami
132
132
  # @since 0.8.0
133
133
  # @api private
134
134
  LEVELS = ::Hash[
135
- "debug" => DEBUG,
136
- "info" => INFO,
137
- "warn" => WARN,
138
- "error" => ERROR,
139
- "fatal" => FATAL,
135
+ "debug" => DEBUG,
136
+ "info" => INFO,
137
+ "warn" => WARN,
138
+ "error" => ERROR,
139
+ "fatal" => FATAL,
140
140
  "unknown" => UNKNOWN
141
141
  ].freeze
142
142
 
@@ -281,7 +281,7 @@ module Hanami
281
281
  # # => {"app":"Hanami","severity":"DEBUG","time":"2017-03-30T13:57:59Z","message":"Hello World"}
282
282
  # rubocop:disable Lint/SuppressedException
283
283
  # rubocop:disable Metrics/ParameterLists
284
- def initialize(application_name = nil, *args, stream: $stdout, level: DEBUG, formatter: nil, filter: [], colorizer: nil)
284
+ def initialize(application_name = nil, *args, stream: $stdout, level: DEBUG, formatter: nil, filter: [], colorizer: nil) # rubocop:disable Layout/LineLength
285
285
  begin
286
286
  Utils::Files.mkdir_p(stream)
287
287
  rescue TypeError
@@ -14,9 +14,9 @@ module Hanami
14
14
  # @api private
15
15
  def call(app, severity, datetime, _progname)
16
16
  ::Hash[
17
- app: app,
17
+ app: app,
18
18
  severity: severity,
19
- time: datetime,
19
+ time: datetime,
20
20
  ]
21
21
  end
22
22
  end
@@ -44,9 +44,9 @@ module Hanami
44
44
  # @return [::Hash] an Hash containing the keys `:app`, `:severity`, and `:time`
45
45
  def call(app, severity, datetime, _progname)
46
46
  ::Hash[
47
- app: app(app),
47
+ app: app(app),
48
48
  severity: severity(severity),
49
- time: datetime(datetime),
49
+ time: datetime(datetime),
50
50
  ]
51
51
  end
52
52
 
@@ -57,18 +57,18 @@ module Hanami
57
57
  # @since 1.2.0
58
58
  # @api private
59
59
  COLORS = ::Hash[
60
- app: :blue,
60
+ app: :blue,
61
61
  datetime: :cyan,
62
62
  ].freeze
63
63
 
64
64
  # @since 1.2.0
65
65
  # @api private
66
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,
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
72
  Hanami::Logger::UNKNOWN => :blue,
73
73
  ].freeze
74
74
 
@@ -9,21 +9,19 @@ module Hanami
9
9
  # @since 1.1.0
10
10
  # @api private
11
11
  class Filter
12
- # @since 1.1.0
12
+ # @since 1.3.7
13
13
  # @api private
14
- def initialize(filters = [])
14
+ FILTERED_VALUE = "[FILTERED]"
15
+
16
+ def initialize(filters = [], mask: FILTERED_VALUE)
15
17
  @filters = filters
18
+ @mask = mask
16
19
  end
17
20
 
18
21
  # @since 1.1.0
19
22
  # @api private
20
- def call(hash)
21
- _filtered_keys(hash).each do |key|
22
- *keys, last = _actual_keys(hash, key.split("."))
23
- keys.inject(hash, :fetch)[last] = "[FILTERED]"
24
- end
25
-
26
- hash
23
+ def call(params)
24
+ _filter(_copy_params(params))
27
25
  end
28
26
 
29
27
  private
@@ -32,6 +30,29 @@ module Hanami
32
30
  # @api private
33
31
  attr_reader :filters
34
32
 
33
+ # @since 1.3.7
34
+ # @api private
35
+ attr_reader :mask
36
+
37
+ # This is a simple deep merge to merge the original input
38
+ # with the filtered hash which contains '[FILTERED]' string.
39
+ #
40
+ # It only deep-merges if the conflict values are both hashes.
41
+ #
42
+ # @since 1.3.7
43
+ # @api private
44
+ def _deep_merge(original_hash, filtered_hash)
45
+ original_hash.merge(filtered_hash) do |_key, original_item, filtered_item|
46
+ if original_item.is_a?(Hash) && filtered_item.is_a?(Hash)
47
+ _deep_merge(original_item, filtered_item)
48
+ elsif filtered_item == FILTERED_VALUE
49
+ filtered_item
50
+ else
51
+ original_item
52
+ end
53
+ end
54
+ end
55
+
35
56
  # @since 1.1.0
36
57
  # @api private
37
58
  def _filtered_keys(hash)
@@ -74,6 +95,53 @@ module Hanami
74
95
  def _key_paths?(value)
75
96
  value.is_a?(Enumerable) && !value.is_a?(File)
76
97
  end
98
+
99
+ # @since 1.3.7
100
+ # @api private
101
+ def _deep_dup(hash)
102
+ hash.map do |key, value|
103
+ [
104
+ key,
105
+ if value.is_a?(Hash)
106
+ _deep_dup(value)
107
+ else
108
+ _key_paths?(value) ? value.dup : value
109
+ end
110
+ ]
111
+ end.to_h
112
+ end
113
+
114
+ # @since 1.3.7
115
+ # @api private
116
+ def _copy_params(params)
117
+ case params
118
+ when Hash
119
+ _deep_dup(params)
120
+ when Array
121
+ params.map { |hash| _deep_dup(hash) }
122
+ end
123
+ end
124
+
125
+ # @since 1.3.7
126
+ # @api private
127
+ def _filter_hash(hash)
128
+ _filtered_keys(hash).each do |key|
129
+ *keys, last = _actual_keys(hash, key.split("."))
130
+ keys.inject(hash, :fetch)[last] = mask
131
+ end
132
+ hash
133
+ end
134
+
135
+ # @since 1.3.7
136
+ # @api private
137
+ def _filter(params)
138
+ case params
139
+ when Hash
140
+ _filter_hash(params)
141
+ when Array
142
+ params.map { |hash| _filter_hash(hash) }
143
+ end
144
+ end
77
145
  end
78
146
  end
79
147
  end
@@ -103,15 +103,15 @@ module Hanami
103
103
 
104
104
  # @since 0.8.0
105
105
  # @api private
106
- def _message_hash(message) # rubocop:disable Metrics/MethodLength
106
+ def _message_hash(message)
107
107
  case message
108
108
  when Hash
109
109
  @filter.call(message)
110
110
  when Exception
111
111
  Hash[
112
- message: message.message,
112
+ message: message.message,
113
113
  backtrace: message.backtrace || [],
114
- error: message.class
114
+ error: message.class
115
115
  ]
116
116
  else
117
117
  Hash[message: message]
@@ -121,7 +121,7 @@ module Hanami
121
121
  # @since 0.8.0
122
122
  # @api private
123
123
  def _format(hash)
124
- "#{_line_front_matter(hash.delete(:app), hash.delete(:severity), hash.delete(:time))}#{SEPARATOR}#{_format_message(hash)}"
124
+ "#{_line_front_matter(hash.delete(:app), hash.delete(:severity), hash.delete(:time))}#{SEPARATOR}#{_format_message(hash)}" # rubocop:disable Layout/LineLength
125
125
  end
126
126
 
127
127
  # @since 1.2.0
@@ -1,11 +1,13 @@
1
- require 'pathname'
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
2
4
 
3
5
  # Hanami - The web, with simplicity
4
6
  #
5
7
  # @since 0.1.0
6
8
  module Hanami
7
- require 'hanami/utils/version'
8
- require 'hanami/utils/file_list'
9
+ require "hanami/utils/version"
10
+ require "hanami/utils/file_list"
9
11
 
10
12
  # Ruby core extentions and Hanami utilities
11
13
  #
@@ -13,11 +15,11 @@ module Hanami
13
15
  module Utils
14
16
  # @since 0.3.1
15
17
  # @api private
16
- HANAMI_JRUBY = 'java'.freeze
18
+ HANAMI_JRUBY = "java"
17
19
 
18
20
  # @since 0.3.1
19
21
  # @api private
20
- HANAMI_RUBINIUS = 'rbx'.freeze
22
+ HANAMI_RUBINIUS = "rbx"
21
23
 
22
24
  # Checks if the current VM is JRuby
23
25
  #
@@ -87,7 +89,7 @@ module Hanami
87
89
  def self.for_each_file_in(directory, &blk)
88
90
  directory = directory.to_s.gsub(%r{(\/|\\)}, File::SEPARATOR)
89
91
  directory = Pathname.new(Dir.pwd).join(directory).to_s
90
- directory = File.join(directory, '**', '*.rb') unless directory =~ /(\*\*)/
92
+ directory = File.join(directory, "**", "*.rb") unless directory =~ /(\*\*)/
91
93
 
92
94
  FileList[directory].each(&blk)
93
95
  end