activesupport 6.1.7.2 → 7.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +866 -411
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -6
  5. data/lib/active_support/actionable_error.rb +4 -2
  6. data/lib/active_support/array_inquirer.rb +2 -2
  7. data/lib/active_support/backtrace_cleaner.rb +27 -7
  8. data/lib/active_support/benchmarkable.rb +3 -2
  9. data/lib/active_support/broadcast_logger.rb +250 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +52 -19
  14. data/lib/active_support/cache/mem_cache_store.rb +195 -60
  15. data/lib/active_support/cache/memory_store.rb +86 -24
  16. data/lib/active_support/cache/null_store.rb +16 -2
  17. data/lib/active_support/cache/redis_cache_store.rb +186 -193
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +63 -71
  20. data/lib/active_support/cache.rb +478 -247
  21. data/lib/active_support/callbacks.rb +227 -105
  22. data/lib/active_support/code_generator.rb +65 -0
  23. data/lib/active_support/concern.rb +9 -7
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/concurrency/share_lock.rb +2 -2
  27. data/lib/active_support/configurable.rb +18 -5
  28. data/lib/active_support/configuration_file.rb +1 -1
  29. data/lib/active_support/core_ext/array/access.rb +1 -5
  30. data/lib/active_support/core_ext/array/conversions.rb +15 -13
  31. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  33. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  34. data/lib/active_support/core_ext/class/subclasses.rb +37 -26
  35. data/lib/active_support/core_ext/date/blank.rb +1 -1
  36. data/lib/active_support/core_ext/date/calculations.rb +24 -9
  37. data/lib/active_support/core_ext/date/conversions.rb +16 -15
  38. data/lib/active_support/core_ext/date_and_time/calculations.rb +14 -4
  39. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  40. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  41. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  42. data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
  43. data/lib/active_support/core_ext/digest/uuid.rb +30 -14
  44. data/lib/active_support/core_ext/enumerable.rb +85 -83
  45. data/lib/active_support/core_ext/erb/util.rb +196 -0
  46. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  47. data/lib/active_support/core_ext/hash/conversions.rb +1 -2
  48. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  49. data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
  50. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  51. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  52. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  53. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  54. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  55. data/lib/active_support/core_ext/module/attribute_accessors.rb +8 -0
  56. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +49 -22
  57. data/lib/active_support/core_ext/module/concerning.rb +6 -6
  58. data/lib/active_support/core_ext/module/delegation.rb +41 -18
  59. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  60. data/lib/active_support/core_ext/module/introspection.rb +0 -1
  61. data/lib/active_support/core_ext/name_error.rb +2 -8
  62. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  63. data/lib/active_support/core_ext/numeric/conversions.rb +82 -77
  64. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  65. data/lib/active_support/core_ext/object/blank.rb +2 -2
  66. data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
  67. data/lib/active_support/core_ext/object/duplicable.rb +15 -4
  68. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  69. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  70. data/lib/active_support/core_ext/object/json.rb +40 -27
  71. data/lib/active_support/core_ext/object/to_query.rb +2 -4
  72. data/lib/active_support/core_ext/object/try.rb +20 -20
  73. data/lib/active_support/core_ext/object/with.rb +44 -0
  74. data/lib/active_support/core_ext/object/with_options.rb +25 -6
  75. data/lib/active_support/core_ext/object.rb +1 -0
  76. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  77. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  78. data/lib/active_support/core_ext/pathname.rb +4 -0
  79. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  80. data/lib/active_support/core_ext/range/conversions.rb +34 -13
  81. data/lib/active_support/core_ext/range/each.rb +1 -1
  82. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  83. data/lib/active_support/core_ext/range.rb +1 -2
  84. data/lib/active_support/core_ext/securerandom.rb +25 -13
  85. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  86. data/lib/active_support/core_ext/string/filters.rb +21 -15
  87. data/lib/active_support/core_ext/string/indent.rb +1 -1
  88. data/lib/active_support/core_ext/string/inflections.rb +17 -10
  89. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  90. data/lib/active_support/core_ext/string/output_safety.rb +85 -193
  91. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  92. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  93. data/lib/active_support/core_ext/time/calculations.rb +29 -10
  94. data/lib/active_support/core_ext/time/conversions.rb +14 -13
  95. data/lib/active_support/core_ext/time/zones.rb +12 -28
  96. data/lib/active_support/core_ext.rb +1 -0
  97. data/lib/active_support/current_attributes.rb +46 -21
  98. data/lib/active_support/deep_mergeable.rb +53 -0
  99. data/lib/active_support/dependencies/autoload.rb +17 -12
  100. data/lib/active_support/dependencies/interlock.rb +10 -18
  101. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  102. data/lib/active_support/dependencies.rb +58 -788
  103. data/lib/active_support/deprecation/behaviors.rb +66 -40
  104. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  105. data/lib/active_support/deprecation/deprecators.rb +104 -0
  106. data/lib/active_support/deprecation/disallowed.rb +6 -8
  107. data/lib/active_support/deprecation/instance_delegator.rb +31 -4
  108. data/lib/active_support/deprecation/method_wrappers.rb +9 -26
  109. data/lib/active_support/deprecation/proxy_wrappers.rb +38 -23
  110. data/lib/active_support/deprecation/reporting.rb +42 -25
  111. data/lib/active_support/deprecation.rb +32 -5
  112. data/lib/active_support/deprecator.rb +7 -0
  113. data/lib/active_support/descendants_tracker.rb +150 -72
  114. data/lib/active_support/digest.rb +4 -4
  115. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  116. data/lib/active_support/duration/iso8601_serializer.rb +9 -3
  117. data/lib/active_support/duration.rb +79 -49
  118. data/lib/active_support/encrypted_configuration.rb +72 -9
  119. data/lib/active_support/encrypted_file.rb +29 -13
  120. data/lib/active_support/environment_inquirer.rb +23 -3
  121. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  122. data/lib/active_support/error_reporter.rb +203 -0
  123. data/lib/active_support/evented_file_update_checker.rb +20 -7
  124. data/lib/active_support/execution_context/test_helper.rb +13 -0
  125. data/lib/active_support/execution_context.rb +53 -0
  126. data/lib/active_support/execution_wrapper.rb +31 -12
  127. data/lib/active_support/executor/test_helper.rb +7 -0
  128. data/lib/active_support/file_update_checker.rb +4 -2
  129. data/lib/active_support/fork_tracker.rb +28 -13
  130. data/lib/active_support/gem_version.rb +4 -4
  131. data/lib/active_support/gzip.rb +2 -0
  132. data/lib/active_support/hash_with_indifferent_access.rb +38 -18
  133. data/lib/active_support/html_safe_translation.rb +43 -0
  134. data/lib/active_support/i18n.rb +2 -1
  135. data/lib/active_support/i18n_railtie.rb +21 -14
  136. data/lib/active_support/inflector/inflections.rb +25 -7
  137. data/lib/active_support/inflector/methods.rb +50 -63
  138. data/lib/active_support/inflector/transliterate.rb +4 -2
  139. data/lib/active_support/isolated_execution_state.rb +76 -0
  140. data/lib/active_support/json/decoding.rb +2 -1
  141. data/lib/active_support/json/encoding.rb +27 -45
  142. data/lib/active_support/key_generator.rb +31 -6
  143. data/lib/active_support/lazy_load_hooks.rb +33 -7
  144. data/lib/active_support/locale/en.yml +3 -1
  145. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  146. data/lib/active_support/log_subscriber.rb +96 -35
  147. data/lib/active_support/logger.rb +9 -60
  148. data/lib/active_support/logger_thread_safe_level.rb +11 -34
  149. data/lib/active_support/message_encryptor.rb +206 -56
  150. data/lib/active_support/message_encryptors.rb +141 -0
  151. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  152. data/lib/active_support/message_pack/extensions.rb +292 -0
  153. data/lib/active_support/message_pack/serializer.rb +63 -0
  154. data/lib/active_support/message_pack.rb +50 -0
  155. data/lib/active_support/message_verifier.rb +235 -84
  156. data/lib/active_support/message_verifiers.rb +135 -0
  157. data/lib/active_support/messages/codec.rb +65 -0
  158. data/lib/active_support/messages/metadata.rb +112 -46
  159. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  160. data/lib/active_support/messages/rotator.rb +34 -32
  161. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  162. data/lib/active_support/multibyte/chars.rb +12 -11
  163. data/lib/active_support/multibyte/unicode.rb +9 -49
  164. data/lib/active_support/multibyte.rb +1 -1
  165. data/lib/active_support/notifications/fanout.rb +304 -114
  166. data/lib/active_support/notifications/instrumenter.rb +109 -35
  167. data/lib/active_support/notifications.rb +24 -24
  168. data/lib/active_support/number_helper/number_converter.rb +14 -7
  169. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  170. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  171. data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -4
  172. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  173. data/lib/active_support/number_helper/rounding_helper.rb +1 -5
  174. data/lib/active_support/number_helper.rb +379 -319
  175. data/lib/active_support/option_merger.rb +10 -18
  176. data/lib/active_support/ordered_hash.rb +4 -4
  177. data/lib/active_support/ordered_options.rb +15 -1
  178. data/lib/active_support/parameter_filter.rb +104 -80
  179. data/lib/active_support/proxy_object.rb +2 -0
  180. data/lib/active_support/railtie.rb +83 -21
  181. data/lib/active_support/reloader.rb +12 -4
  182. data/lib/active_support/rescuable.rb +14 -12
  183. data/lib/active_support/ruby_features.rb +7 -0
  184. data/lib/active_support/secure_compare_rotator.rb +18 -11
  185. data/lib/active_support/string_inquirer.rb +3 -3
  186. data/lib/active_support/subscriber.rb +11 -40
  187. data/lib/active_support/syntax_error_proxy.rb +70 -0
  188. data/lib/active_support/tagged_logging.rb +60 -24
  189. data/lib/active_support/test_case.rb +166 -27
  190. data/lib/active_support/testing/assertions.rb +60 -14
  191. data/lib/active_support/testing/autorun.rb +0 -2
  192. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  193. data/lib/active_support/testing/deprecation.rb +53 -2
  194. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  195. data/lib/active_support/testing/isolation.rb +30 -29
  196. data/lib/active_support/testing/method_call_assertions.rb +24 -11
  197. data/lib/active_support/testing/parallelization/server.rb +4 -0
  198. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  199. data/lib/active_support/testing/parallelization.rb +4 -0
  200. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  201. data/lib/active_support/testing/stream.rb +4 -6
  202. data/lib/active_support/testing/strict_warnings.rb +39 -0
  203. data/lib/active_support/testing/tagged_logging.rb +1 -1
  204. data/lib/active_support/testing/time_helpers.rb +49 -16
  205. data/lib/active_support/time_with_zone.rb +39 -28
  206. data/lib/active_support/values/time_zone.rb +38 -17
  207. data/lib/active_support/version.rb +1 -1
  208. data/lib/active_support/xml_mini/jdom.rb +4 -11
  209. data/lib/active_support/xml_mini/libxml.rb +5 -5
  210. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  211. data/lib/active_support/xml_mini/nokogiri.rb +5 -5
  212. data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
  213. data/lib/active_support/xml_mini/rexml.rb +2 -2
  214. data/lib/active_support/xml_mini.rb +7 -6
  215. data/lib/active_support.rb +28 -1
  216. metadata +107 -18
  217. data/lib/active_support/core_ext/marshal.rb +0 -26
  218. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -28
  219. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  220. data/lib/active_support/core_ext/uri.rb +0 -29
  221. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -120
  222. data/lib/active_support/per_thread_registry.rb +0 -61
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/hash/deep_merge"
4
- require "active_support/core_ext/symbol/starts_ends_with"
5
4
 
6
5
  module ActiveSupport
7
- class OptionMerger #:nodoc:
6
+ class OptionMerger # :nodoc:
8
7
  instance_methods.each do |method|
9
8
  undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id")
10
9
  end
@@ -16,8 +15,8 @@ module ActiveSupport
16
15
  private
17
16
  def method_missing(method, *arguments, &block)
18
17
  options = nil
19
- if arguments.first.is_a?(Proc)
20
- proc = arguments.pop
18
+ if arguments.size == 1 && arguments.first.is_a?(Proc)
19
+ proc = arguments.shift
21
20
  arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
22
21
  elsif arguments.last.respond_to?(:to_hash)
23
22
  options = @options.deep_merge(arguments.pop)
@@ -25,22 +24,15 @@ module ActiveSupport
25
24
  options = @options
26
25
  end
27
26
 
28
- invoke_method(method, arguments, options, &block)
29
- end
30
-
31
- if RUBY_VERSION >= "2.7"
32
- def invoke_method(method, arguments, options, &block)
33
- if options
34
- @context.__send__(method, *arguments, **options, &block)
35
- else
36
- @context.__send__(method, *arguments, &block)
37
- end
38
- end
39
- else
40
- def invoke_method(method, arguments, options, &block)
41
- arguments << options.dup if options
27
+ if options
28
+ @context.__send__(method, *arguments, **options, &block)
29
+ else
42
30
  @context.__send__(method, *arguments, &block)
43
31
  end
44
32
  end
33
+
34
+ def respond_to_missing?(*arguments)
35
+ @context.respond_to?(*arguments)
36
+ end
45
37
  end
46
38
  end
@@ -7,7 +7,7 @@ YAML.add_builtin_type("omap") do |type, val|
7
7
  end
8
8
 
9
9
  module ActiveSupport
10
- # DEPRECATED: <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
10
+ # DEPRECATED: +ActiveSupport::OrderedHash+ implements a hash that preserves
11
11
  # insertion order.
12
12
  #
13
13
  # oh = ActiveSupport::OrderedHash.new
@@ -17,11 +17,11 @@ module ActiveSupport
17
17
  #
18
18
  # Also, maps the +omap+ feature for YAML files
19
19
  # (See https://yaml.org/type/omap.html) to support ordered items
20
- # when loading from yaml.
20
+ # when loading from YAML.
21
21
  #
22
- # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
22
+ # +ActiveSupport::OrderedHash+ is namespaced to prevent conflicts
23
23
  # with other implementations.
24
- class OrderedHash < ::Hash
24
+ class OrderedHash < ::Hash # :nodoc:
25
25
  def to_yaml_type
26
26
  "!tag:yaml.org,2002:omap"
27
27
  end
@@ -3,6 +3,8 @@
3
3
  require "active_support/core_ext/object/blank"
4
4
 
5
5
  module ActiveSupport
6
+ # = Ordered Options
7
+ #
6
8
  # +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods.
7
9
  #
8
10
  # With a +Hash+, key-value pairs are typically managed like this:
@@ -40,6 +42,10 @@ module ActiveSupport
40
42
  super(key.to_sym)
41
43
  end
42
44
 
45
+ def dig(key, *identifiers)
46
+ super(key.to_sym, *identifiers)
47
+ end
48
+
43
49
  def method_missing(name, *args)
44
50
  name_string = +name.to_s
45
51
  if name_string.chomp!("=")
@@ -68,7 +74,9 @@ module ActiveSupport
68
74
  end
69
75
  end
70
76
 
71
- # +InheritableOptions+ provides a constructor to build an +OrderedOptions+
77
+ # = Inheritable Options
78
+ #
79
+ # +InheritableOptions+ provides a constructor to build an OrderedOptions
72
80
  # hash inherited from another hash.
73
81
  #
74
82
  # Use this if you already have some hash and you want to create a new one based on it.
@@ -76,6 +84,12 @@ module ActiveSupport
76
84
  # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
77
85
  # h.girl # => 'Mary'
78
86
  # h.boy # => 'John'
87
+ #
88
+ # If the existing hash has string keys, call Hash#symbolize_keys on it.
89
+ #
90
+ # h = ActiveSupport::InheritableOptions.new({ 'girl' => 'Mary', 'boy' => 'John' }.symbolize_keys)
91
+ # h.girl # => 'Mary'
92
+ # h.boy # => 'John'
79
93
  class InheritableOptions < OrderedOptions
80
94
  def initialize(parent = nil)
81
95
  if parent.kind_of?(OrderedOptions)
@@ -1,32 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/object/duplicable"
4
+ require "active_support/core_ext/array/extract"
4
5
 
5
6
  module ActiveSupport
6
- # +ParameterFilter+ allows you to specify keys for sensitive data from
7
- # hash-like object and replace corresponding value. Filtering only certain
8
- # sub-keys from a hash is possible by using the dot notation:
9
- # 'credit_card.number'. If a proc is given, each key and value of a hash and
10
- # all sub-hashes are passed to it, where the value or the key can be replaced
11
- # using String#replace or similar methods.
7
+ # = Active Support Parameter Filter
12
8
  #
9
+ # +ParameterFilter+ replaces values in a <tt>Hash</tt>-like object if their
10
+ # keys match one of the specified filters.
11
+ #
12
+ # Matching based on nested keys is possible by using dot notation, e.g.
13
+ # <tt>"credit_card.number"</tt>.
14
+ #
15
+ # If a proc is given as a filter, each key and value of the <tt>Hash</tt>-like
16
+ # and of any nested <tt>Hash</tt>es will be passed to it. The value or key can
17
+ # then be mutated as desired using methods such as <tt>String#replace</tt>.
18
+ #
19
+ # # Replaces values with "[FILTERED]" for keys that match /password/i.
13
20
  # ActiveSupport::ParameterFilter.new([:password])
14
- # => replaces the value to all keys matching /password/i with "[FILTERED]"
15
21
  #
22
+ # # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
16
23
  # ActiveSupport::ParameterFilter.new([:foo, "bar"])
17
- # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
18
24
  #
25
+ # # Replaces values for the exact key "pin" and for keys that begin with
26
+ # # "pin_". Does not match keys that otherwise include "pin" as a
27
+ # # substring, such as "shipping_id".
28
+ # ActiveSupport::ParameterFilter.new([/\Apin\z/, /\Apin_/])
29
+ #
30
+ # # Replaces the value for :code in `{ credit_card: { code: "xxxx" } }`.
31
+ # # Does not change `{ file: { code: "xxxx" } }`.
19
32
  # ActiveSupport::ParameterFilter.new(["credit_card.code"])
20
- # => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
21
- # change { file: { code: "xxxx"} }
22
33
  #
34
+ # # Reverses values for keys that match /secret/i.
23
35
  # ActiveSupport::ParameterFilter.new([-> (k, v) do
24
36
  # v.reverse! if /secret/i.match?(k)
25
37
  # end])
26
- # => reverses the value to all keys matching /secret/i
38
+ #
27
39
  class ParameterFilter
28
40
  FILTERED = "[FILTERED]" # :nodoc:
29
41
 
42
+ # Precompiles an array of filters that otherwise would be passed directly to
43
+ # #initialize. Depending on the quantity and types of filters,
44
+ # precompilation can improve filtering performance, especially in the case
45
+ # where the ParameterFilter instance itself cannot be retained (but the
46
+ # precompiled filters can be retained).
47
+ #
48
+ # filters = [/foo/, :bar, "nested.baz", /nested\.qux/]
49
+ #
50
+ # precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
51
+ # # => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]
52
+ #
53
+ # ActiveSupport::ParameterFilter.new(precompiled)
54
+ #
55
+ def self.precompile_filters(filters)
56
+ filters, patterns = filters.partition { |filter| filter.is_a?(Proc) }
57
+
58
+ patterns.map! do |pattern|
59
+ pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})"
60
+ end
61
+
62
+ deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") }
63
+
64
+ filters << Regexp.new(patterns.join("|")) if patterns.any?
65
+ filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any?
66
+
67
+ filters
68
+ end
69
+
30
70
  # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
31
71
  # Other types of filters are treated as +String+ using +to_s+.
32
72
  # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
@@ -35,99 +75,83 @@ module ActiveSupport
35
75
  #
36
76
  # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
37
77
  def initialize(filters = [], mask: FILTERED)
38
- @filters = filters
39
78
  @mask = mask
79
+ compile_filters!(filters)
40
80
  end
41
81
 
42
82
  # Mask value of +params+ if key matches one of filters.
43
83
  def filter(params)
44
- compiled_filter.call(params)
84
+ @no_filters ? params.dup : call(params)
45
85
  end
46
86
 
47
87
  # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
48
88
  def filter_param(key, value)
49
- @filters.empty? ? value : compiled_filter.value_for_key(key, value)
89
+ @no_filters ? value : value_for_key(key, value)
50
90
  end
51
91
 
52
92
  private
53
- def compiled_filter
54
- @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
55
- end
56
-
57
- class CompiledFilter # :nodoc:
58
- def self.compile(filters, mask:)
59
- return lambda { |params| params.dup } if filters.empty?
60
-
61
- strings, regexps, blocks, deep_regexps, deep_strings = [], [], [], nil, nil
62
-
63
- filters.each do |item|
64
- case item
65
- when Proc
66
- blocks << item
67
- when Regexp
68
- if item.to_s.include?("\\.")
69
- (deep_regexps ||= []) << item
70
- else
71
- regexps << item
72
- end
93
+ def compile_filters!(filters)
94
+ @no_filters = filters.empty?
95
+ return if @no_filters
96
+
97
+ @regexps, strings = [], []
98
+ @deep_regexps, deep_strings = nil, nil
99
+ @blocks = nil
100
+
101
+ filters.each do |item|
102
+ case item
103
+ when Proc
104
+ (@blocks ||= []) << item
105
+ when Regexp
106
+ if item.to_s.include?("\\.")
107
+ (@deep_regexps ||= []) << item
73
108
  else
74
- s = Regexp.escape(item.to_s)
75
- if s.include?("\\.")
76
- (deep_strings ||= []) << s
77
- else
78
- strings << s
79
- end
109
+ @regexps << item
110
+ end
111
+ else
112
+ s = Regexp.escape(item.to_s)
113
+ if s.include?("\\.")
114
+ (deep_strings ||= []) << s
115
+ else
116
+ strings << s
80
117
  end
81
118
  end
82
-
83
- regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
84
- (deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings&.any?
85
-
86
- new regexps, deep_regexps, blocks, mask: mask
87
119
  end
88
120
 
89
- attr_reader :regexps, :deep_regexps, :blocks
121
+ @regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
122
+ (@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings
123
+ end
90
124
 
91
- def initialize(regexps, deep_regexps, blocks, mask:)
92
- @regexps = regexps
93
- @deep_regexps = deep_regexps&.any? ? deep_regexps : nil
94
- @blocks = blocks
95
- @mask = mask
96
- end
125
+ def call(params, full_parent_key = nil, original_params = params)
126
+ filtered_params = params.class.new
97
127
 
98
- def call(params, parents = [], original_params = params)
99
- filtered_params = params.class.new
128
+ params.each do |key, value|
129
+ filtered_params[key] = value_for_key(key, value, full_parent_key, original_params)
130
+ end
100
131
 
101
- params.each do |key, value|
102
- filtered_params[key] = value_for_key(key, value, parents, original_params)
103
- end
132
+ filtered_params
133
+ end
104
134
 
105
- filtered_params
135
+ def value_for_key(key, value, full_parent_key = nil, original_params = nil)
136
+ if @deep_regexps
137
+ full_key = full_parent_key ? "#{full_parent_key}.#{key}" : key.to_s
106
138
  end
107
139
 
108
- def value_for_key(key, value, parents = [], original_params = nil)
109
- parents.push(key) if deep_regexps
110
- if regexps.any? { |r| r.match?(key.to_s) }
111
- value = @mask
112
- elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
113
- value = @mask
114
- elsif value.is_a?(Hash)
115
- value = call(value, parents, original_params)
116
- elsif value.is_a?(Array)
117
- # If we don't pop the current parent it will be duplicated as we
118
- # process each array value.
119
- parents.pop if deep_regexps
120
- value = value.map { |v| value_for_key(key, v, parents, original_params) }
121
- # Restore the parent stack after processing the array.
122
- parents.push(key) if deep_regexps
123
- elsif blocks.any?
124
- key = key.dup if key.duplicable?
125
- value = value.dup if value.duplicable?
126
- blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
127
- end
128
- parents.pop if deep_regexps
129
- value
140
+ if @regexps.any? { |r| r.match?(key.to_s) }
141
+ value = @mask
142
+ elsif @deep_regexps&.any? { |r| r.match?(full_key) }
143
+ value = @mask
144
+ elsif value.is_a?(Hash)
145
+ value = call(value, full_key, original_params)
146
+ elsif value.is_a?(Array)
147
+ value = value.map { |v| value_for_key(key, v, full_parent_key, original_params) }
148
+ elsif @blocks
149
+ key = key.dup if key.duplicable?
150
+ value = value.dup if value.duplicable?
151
+ @blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
130
152
  end
153
+
154
+ value
131
155
  end
132
156
  end
133
157
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
+ # = Active Support Proxy \Object
5
+ #
4
6
  # A class with no predefined methods that behaves similarly to Builder's
5
7
  # BlankSlate. Used for proxy classes.
6
8
  class ProxyObject < ::BasicObject
@@ -9,6 +9,26 @@ module ActiveSupport
9
9
 
10
10
  config.eager_load_namespaces << ActiveSupport
11
11
 
12
+ initializer "active_support.deprecator", before: :load_environment_config do |app|
13
+ app.deprecators[:active_support] = ActiveSupport.deprecator
14
+ end
15
+
16
+ initializer "active_support.isolation_level" do |app|
17
+ config.after_initialize do
18
+ if level = app.config.active_support.delete(:isolation_level)
19
+ ActiveSupport::IsolatedExecutionState.isolation_level = level
20
+ end
21
+ end
22
+ end
23
+
24
+ initializer "active_support.raise_on_invalid_cache_expiration_time" do |app|
25
+ config.after_initialize do
26
+ if app.config.active_support.raise_on_invalid_cache_expiration_time
27
+ ActiveSupport::Cache::Store.raise_on_invalid_cache_expiration_time = true
28
+ end
29
+ end
30
+ end
31
+
12
32
  initializer "active_support.set_authenticated_message_encryption" do |app|
13
33
  config.after_initialize do
14
34
  unless app.config.active_support.use_authenticated_message_encryption.nil?
@@ -18,28 +38,48 @@ module ActiveSupport
18
38
  end
19
39
  end
20
40
 
41
+ initializer "active_support.reset_execution_context" do |app|
42
+ app.reloader.before_class_unload { ActiveSupport::ExecutionContext.clear }
43
+ app.executor.to_run { ActiveSupport::ExecutionContext.clear }
44
+ app.executor.to_complete { ActiveSupport::ExecutionContext.clear }
45
+ end
46
+
21
47
  initializer "active_support.reset_all_current_attributes_instances" do |app|
22
48
  app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
23
49
  app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
24
50
  app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
25
51
 
26
52
  ActiveSupport.on_load(:active_support_test_case) do
27
- require "active_support/current_attributes/test_helper"
28
- include ActiveSupport::CurrentAttributes::TestHelper
53
+ if app.config.active_support.executor_around_test_case
54
+ require "active_support/executor/test_helper"
55
+ include ActiveSupport::Executor::TestHelper
56
+ else
57
+ require "active_support/current_attributes/test_helper"
58
+ include ActiveSupport::CurrentAttributes::TestHelper
59
+
60
+ require "active_support/execution_context/test_helper"
61
+ include ActiveSupport::ExecutionContext::TestHelper
62
+ end
29
63
  end
30
64
  end
31
65
 
32
66
  initializer "active_support.deprecation_behavior" do |app|
33
- if deprecation = app.config.active_support.deprecation
34
- ActiveSupport::Deprecation.behavior = deprecation
35
- end
67
+ if app.config.active_support.report_deprecations == false
68
+ app.deprecators.silenced = true
69
+ app.deprecators.behavior = :silence
70
+ app.deprecators.disallowed_behavior = :silence
71
+ else
72
+ if deprecation = app.config.active_support.deprecation
73
+ app.deprecators.behavior = deprecation
74
+ end
36
75
 
37
- if disallowed_deprecation = app.config.active_support.disallowed_deprecation
38
- ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
39
- end
76
+ if disallowed_deprecation = app.config.active_support.disallowed_deprecation
77
+ app.deprecators.disallowed_behavior = disallowed_deprecation
78
+ end
40
79
 
41
- if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
42
- ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
80
+ if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
81
+ app.deprecators.disallowed_warnings = disallowed_warnings
82
+ end
43
83
  end
44
84
  end
45
85
 
@@ -77,26 +117,48 @@ module ActiveSupport
77
117
 
78
118
  initializer "active_support.set_configs" do |app|
79
119
  app.config.active_support.each do |k, v|
80
- k = "#{k}="
81
- ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
120
+ if k == "disable_to_s_conversion"
121
+ ActiveSupport.deprecator.warn("config.active_support.disable_to_s_conversion is deprecated and will be removed in Rails 7.2.")
122
+ elsif k == "remove_deprecated_time_with_zone_name"
123
+ ActiveSupport.deprecator.warn("config.active_support.remove_deprecated_time_with_zone_name is deprecated and will be removed in Rails 7.2.")
124
+ elsif k == "use_rfc4122_namespaced_uuids"
125
+ ActiveSupport.deprecator.warn("config.active_support.use_rfc4122_namespaced_uuids is deprecated and will be removed in Rails 7.2.")
126
+ else
127
+ k = "#{k}="
128
+ ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
129
+ end
82
130
  end
83
131
  end
84
132
 
85
133
  initializer "active_support.set_hash_digest_class" do |app|
86
134
  config.after_initialize do
87
- if app.config.active_support.use_sha1_digests
88
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
89
- config.active_support.use_sha1_digests is deprecated and will
90
- be removed from Rails 7.0. Use
91
- config.active_support.hash_digest_class = ::Digest::SHA1 instead.
92
- MSG
93
- ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
94
- end
95
-
96
135
  if klass = app.config.active_support.hash_digest_class
97
136
  ActiveSupport::Digest.hash_digest_class = klass
98
137
  end
99
138
  end
100
139
  end
140
+
141
+ initializer "active_support.set_key_generator_hash_digest_class" do |app|
142
+ config.after_initialize do
143
+ if klass = app.config.active_support.key_generator_hash_digest_class
144
+ ActiveSupport::KeyGenerator.hash_digest_class = klass
145
+ end
146
+ end
147
+ end
148
+
149
+ initializer "active_support.set_default_message_serializer" do |app|
150
+ config.after_initialize do
151
+ if message_serializer = app.config.active_support.message_serializer
152
+ ActiveSupport::Messages::Codec.default_serializer = message_serializer
153
+ end
154
+ end
155
+ end
156
+
157
+ initializer "active_support.set_use_message_serializer_for_metadata" do |app|
158
+ config.after_initialize do
159
+ ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata =
160
+ app.config.active_support.use_message_serializer_for_metadata
161
+ end
162
+ end
101
163
  end
102
164
  end
@@ -4,7 +4,8 @@ require "active_support/execution_wrapper"
4
4
  require "active_support/executor"
5
5
 
6
6
  module ActiveSupport
7
- #--
7
+ # = Active Support \Reloader
8
+ #
8
9
  # This class defines several callbacks:
9
10
  #
10
11
  # to_prepare -- Run once at application startup, and also from
@@ -67,9 +68,16 @@ module ActiveSupport
67
68
  end
68
69
 
69
70
  # Run the supplied block as a work unit, reloading code as needed
70
- def self.wrap
71
- executor.wrap do
72
- super
71
+ def self.wrap(**kwargs)
72
+ return yield if active?
73
+
74
+ executor.wrap(**kwargs) do
75
+ instance = run!
76
+ begin
77
+ yield
78
+ ensure
79
+ instance.complete!
80
+ end
73
81
  end
74
82
  end
75
83
 
@@ -5,6 +5,8 @@ require "active_support/core_ext/class/attribute"
5
5
  require "active_support/core_ext/string/inflections"
6
6
 
7
7
  module ActiveSupport
8
+ # = Active Support \Rescuable
9
+ #
8
10
  # Rescuable module adds support for easier exception handling.
9
11
  module Rescuable
10
12
  extend Concern
@@ -30,20 +32,20 @@ module ActiveSupport
30
32
  # any.
31
33
  #
32
34
  # class ApplicationController < ActionController::Base
33
- # rescue_from User::NotAuthorized, with: :deny_access # self defined exception
34
- # rescue_from ActiveRecord::RecordInvalid, with: :show_errors
35
+ # rescue_from User::NotAuthorized, with: :deny_access
36
+ # rescue_from ActiveRecord::RecordInvalid, with: :show_record_errors
35
37
  #
36
- # rescue_from 'MyAppError::Base' do |exception|
37
- # render xml: exception, status: 500
38
+ # rescue_from "MyApp::BaseError" do |exception|
39
+ # redirect_to root_url, alert: exception.message
38
40
  # end
39
41
  #
40
42
  # private
41
43
  # def deny_access
42
- # ...
44
+ # head :forbidden
43
45
  # end
44
46
  #
45
- # def show_errors(exception)
46
- # exception.record.new_record? ? ...
47
+ # def show_record_errors(exception)
48
+ # redirect_back_or_to root_url, alert: exception.record.errors.full_messages.to_sentence
47
49
  # end
48
50
  # end
49
51
  #
@@ -74,12 +76,12 @@ module ActiveSupport
74
76
  # Matches an exception to a handler based on the exception class.
75
77
  #
76
78
  # If no handler matches the exception, check for a handler matching the
77
- # (optional) exception.cause. If no handler matches the exception or its
79
+ # (optional) +exception.cause+. If no handler matches the exception or its
78
80
  # cause, this returns +nil+, so you can deal with unhandled exceptions.
79
81
  # Be sure to re-raise unhandled exceptions if this is what you expect.
80
82
  #
81
83
  # begin
82
- #
84
+ # # ...
83
85
  # rescue => exception
84
86
  # rescue_with_handler(exception) || raise
85
87
  # end
@@ -100,7 +102,7 @@ module ActiveSupport
100
102
  end
101
103
  end
102
104
 
103
- def handler_for_rescue(exception, object: self) #:nodoc:
105
+ def handler_for_rescue(exception, object: self) # :nodoc:
104
106
  case rescuer = find_rescue_handler(exception)
105
107
  when Symbol
106
108
  method = object.method(rescuer)
@@ -160,14 +162,14 @@ module ActiveSupport
160
162
  end
161
163
 
162
164
  # Delegates to the class method, but uses the instance as the subject for
163
- # rescue_from handlers (method calls, instance_exec blocks).
165
+ # rescue_from handlers (method calls, +instance_exec+ blocks).
164
166
  def rescue_with_handler(exception)
165
167
  self.class.rescue_with_handler exception, object: self
166
168
  end
167
169
 
168
170
  # Internal handler lookup. Delegates to class method. Some libraries call
169
171
  # this directly, so keeping it around for compatibility.
170
- def handler_for_rescue(exception) #:nodoc:
172
+ def handler_for_rescue(exception) # :nodoc:
171
173
  self.class.handler_for_rescue exception, object: self
172
174
  end
173
175
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module RubyFeatures # :nodoc:
5
+ CLASS_SUBCLASSES = Class.method_defined?(:subclasses) # RUBY_VERSION >= "3.1"
6
+ end
7
+ end