activesupport 6.0.6.1 → 7.1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +865 -438
  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 +4 -2
  7. data/lib/active_support/backtrace_cleaner.rb +30 -10
  8. data/lib/active_support/benchmarkable.rb +4 -3
  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 +53 -20
  14. data/lib/active_support/cache/mem_cache_store.rb +208 -63
  15. data/lib/active_support/cache/memory_store.rb +120 -38
  16. data/lib/active_support/cache/null_store.rb +16 -2
  17. data/lib/active_support/cache/redis_cache_store.rb +201 -208
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +73 -66
  20. data/lib/active_support/cache.rb +539 -261
  21. data/lib/active_support/callbacks.rb +273 -142
  22. data/lib/active_support/code_generator.rb +65 -0
  23. data/lib/active_support/concern.rb +53 -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 +19 -6
  28. data/lib/active_support/configuration_file.rb +51 -0
  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/benchmark.rb +2 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  35. data/lib/active_support/core_ext/class/attribute.rb +34 -44
  36. data/lib/active_support/core_ext/class/subclasses.rb +19 -29
  37. data/lib/active_support/core_ext/date/blank.rb +1 -1
  38. data/lib/active_support/core_ext/date/calculations.rb +24 -9
  39. data/lib/active_support/core_ext/date/conversions.rb +18 -16
  40. data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -4
  41. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  42. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  43. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  44. data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
  45. data/lib/active_support/core_ext/digest/uuid.rb +30 -13
  46. data/lib/active_support/core_ext/enumerable.rb +146 -72
  47. data/lib/active_support/core_ext/erb/util.rb +196 -0
  48. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  49. data/lib/active_support/core_ext/hash/conversions.rb +3 -4
  50. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  51. data/lib/active_support/core_ext/hash/deep_transform_values.rb +4 -4
  52. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  53. data/lib/active_support/core_ext/hash/keys.rb +5 -5
  54. data/lib/active_support/core_ext/hash/slice.rb +3 -2
  55. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  56. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  58. data/lib/active_support/core_ext/load_error.rb +1 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +31 -29
  61. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +51 -20
  62. data/lib/active_support/core_ext/module/concerning.rb +14 -8
  63. data/lib/active_support/core_ext/module/delegation.rb +75 -42
  64. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  65. data/lib/active_support/core_ext/module/introspection.rb +1 -26
  66. data/lib/active_support/core_ext/name_error.rb +23 -2
  67. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  68. data/lib/active_support/core_ext/numeric/conversions.rb +82 -73
  69. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  70. data/lib/active_support/core_ext/object/blank.rb +2 -2
  71. data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
  72. data/lib/active_support/core_ext/object/duplicable.rb +15 -4
  73. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  74. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  75. data/lib/active_support/core_ext/object/json.rb +52 -28
  76. data/lib/active_support/core_ext/object/to_query.rb +2 -4
  77. data/lib/active_support/core_ext/object/try.rb +20 -20
  78. data/lib/active_support/core_ext/object/with.rb +44 -0
  79. data/lib/active_support/core_ext/object/with_options.rb +25 -6
  80. data/lib/active_support/core_ext/object.rb +1 -0
  81. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  82. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  83. data/lib/active_support/core_ext/pathname.rb +4 -0
  84. data/lib/active_support/core_ext/range/compare_range.rb +6 -25
  85. data/lib/active_support/core_ext/range/conversions.rb +34 -13
  86. data/lib/active_support/core_ext/range/each.rb +1 -1
  87. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  88. data/lib/active_support/core_ext/range.rb +1 -2
  89. data/lib/active_support/core_ext/regexp.rb +8 -1
  90. data/lib/active_support/core_ext/securerandom.rb +25 -13
  91. data/lib/active_support/core_ext/string/access.rb +5 -24
  92. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  93. data/lib/active_support/core_ext/string/filters.rb +21 -15
  94. data/lib/active_support/core_ext/string/indent.rb +1 -1
  95. data/lib/active_support/core_ext/string/inflections.rb +51 -10
  96. data/lib/active_support/core_ext/string/inquiry.rb +2 -1
  97. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  98. data/lib/active_support/core_ext/string/output_safety.rb +85 -194
  99. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  100. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  101. data/lib/active_support/core_ext/symbol.rb +3 -0
  102. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  103. data/lib/active_support/core_ext/time/calculations.rb +46 -8
  104. data/lib/active_support/core_ext/time/conversions.rb +16 -13
  105. data/lib/active_support/core_ext/time/zones.rb +12 -28
  106. data/lib/active_support/core_ext.rb +2 -1
  107. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  108. data/lib/active_support/current_attributes.rb +54 -22
  109. data/lib/active_support/deep_mergeable.rb +53 -0
  110. data/lib/active_support/dependencies/autoload.rb +17 -12
  111. data/lib/active_support/dependencies/interlock.rb +10 -18
  112. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  113. data/lib/active_support/dependencies.rb +58 -769
  114. data/lib/active_support/deprecation/behaviors.rb +77 -38
  115. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  116. data/lib/active_support/deprecation/deprecators.rb +104 -0
  117. data/lib/active_support/deprecation/disallowed.rb +54 -0
  118. data/lib/active_support/deprecation/instance_delegator.rb +31 -5
  119. data/lib/active_support/deprecation/method_wrappers.rb +12 -28
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +40 -25
  121. data/lib/active_support/deprecation/reporting.rb +76 -16
  122. data/lib/active_support/deprecation.rb +36 -4
  123. data/lib/active_support/deprecator.rb +7 -0
  124. data/lib/active_support/descendants_tracker.rb +150 -68
  125. data/lib/active_support/digest.rb +5 -3
  126. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  127. data/lib/active_support/duration/iso8601_serializer.rb +24 -12
  128. data/lib/active_support/duration.rb +136 -56
  129. data/lib/active_support/encrypted_configuration.rb +72 -9
  130. data/lib/active_support/encrypted_file.rb +46 -13
  131. data/lib/active_support/environment_inquirer.rb +40 -0
  132. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  133. data/lib/active_support/error_reporter.rb +203 -0
  134. data/lib/active_support/evented_file_update_checker.rb +86 -137
  135. data/lib/active_support/execution_context/test_helper.rb +13 -0
  136. data/lib/active_support/execution_context.rb +53 -0
  137. data/lib/active_support/execution_wrapper.rb +31 -12
  138. data/lib/active_support/executor/test_helper.rb +7 -0
  139. data/lib/active_support/file_update_checker.rb +4 -2
  140. data/lib/active_support/fork_tracker.rb +79 -0
  141. data/lib/active_support/gem_version.rb +5 -5
  142. data/lib/active_support/gzip.rb +2 -0
  143. data/lib/active_support/hash_with_indifferent_access.rb +86 -42
  144. data/lib/active_support/html_safe_translation.rb +53 -0
  145. data/lib/active_support/i18n.rb +2 -1
  146. data/lib/active_support/i18n_railtie.rb +29 -27
  147. data/lib/active_support/inflector/inflections.rb +26 -9
  148. data/lib/active_support/inflector/methods.rb +54 -64
  149. data/lib/active_support/inflector/transliterate.rb +7 -5
  150. data/lib/active_support/isolated_execution_state.rb +76 -0
  151. data/lib/active_support/json/decoding.rb +6 -5
  152. data/lib/active_support/json/encoding.rb +31 -45
  153. data/lib/active_support/key_generator.rb +32 -7
  154. data/lib/active_support/lazy_load_hooks.rb +33 -7
  155. data/lib/active_support/locale/en.yml +10 -4
  156. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  157. data/lib/active_support/log_subscriber.rb +101 -32
  158. data/lib/active_support/logger.rb +9 -60
  159. data/lib/active_support/logger_silence.rb +2 -26
  160. data/lib/active_support/logger_thread_safe_level.rb +24 -25
  161. data/lib/active_support/message_encryptor.rb +205 -58
  162. data/lib/active_support/message_encryptors.rb +141 -0
  163. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  164. data/lib/active_support/message_pack/extensions.rb +292 -0
  165. data/lib/active_support/message_pack/serializer.rb +63 -0
  166. data/lib/active_support/message_pack.rb +50 -0
  167. data/lib/active_support/message_verifier.rb +237 -86
  168. data/lib/active_support/message_verifiers.rb +135 -0
  169. data/lib/active_support/messages/codec.rb +65 -0
  170. data/lib/active_support/messages/metadata.rb +112 -46
  171. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  172. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  173. data/lib/active_support/messages/rotator.rb +35 -32
  174. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  175. data/lib/active_support/multibyte/chars.rb +15 -52
  176. data/lib/active_support/multibyte/unicode.rb +8 -122
  177. data/lib/active_support/multibyte.rb +1 -1
  178. data/lib/active_support/notifications/fanout.rb +310 -105
  179. data/lib/active_support/notifications/instrumenter.rb +113 -48
  180. data/lib/active_support/notifications.rb +56 -29
  181. data/lib/active_support/number_helper/number_converter.rb +15 -8
  182. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  183. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  184. data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
  185. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -5
  186. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  187. data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
  188. data/lib/active_support/number_helper/rounding_helper.rb +12 -32
  189. data/lib/active_support/number_helper.rb +379 -304
  190. data/lib/active_support/option_merger.rb +11 -18
  191. data/lib/active_support/ordered_hash.rb +4 -4
  192. data/lib/active_support/ordered_options.rb +23 -3
  193. data/lib/active_support/parameter_filter.rb +104 -75
  194. data/lib/active_support/proxy_object.rb +2 -0
  195. data/lib/active_support/rails.rb +1 -4
  196. data/lib/active_support/railtie.rb +90 -6
  197. data/lib/active_support/reloader.rb +12 -4
  198. data/lib/active_support/rescuable.rb +18 -16
  199. data/lib/active_support/ruby_features.rb +7 -0
  200. data/lib/active_support/secure_compare_rotator.rb +58 -0
  201. data/lib/active_support/security_utils.rb +19 -12
  202. data/lib/active_support/string_inquirer.rb +5 -3
  203. data/lib/active_support/subscriber.rb +23 -47
  204. data/lib/active_support/syntax_error_proxy.rb +70 -0
  205. data/lib/active_support/tagged_logging.rb +84 -23
  206. data/lib/active_support/test_case.rb +166 -27
  207. data/lib/active_support/testing/assertions.rb +73 -20
  208. data/lib/active_support/testing/autorun.rb +0 -2
  209. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  210. data/lib/active_support/testing/deprecation.rb +53 -2
  211. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  212. data/lib/active_support/testing/isolation.rb +30 -29
  213. data/lib/active_support/testing/method_call_assertions.rb +24 -11
  214. data/lib/active_support/testing/parallelization/server.rb +82 -0
  215. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  216. data/lib/active_support/testing/parallelization.rb +16 -95
  217. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  218. data/lib/active_support/testing/stream.rb +4 -6
  219. data/lib/active_support/testing/strict_warnings.rb +39 -0
  220. data/lib/active_support/testing/tagged_logging.rb +1 -1
  221. data/lib/active_support/testing/time_helpers.rb +89 -19
  222. data/lib/active_support/time_with_zone.rb +105 -70
  223. data/lib/active_support/values/time_zone.rb +59 -26
  224. data/lib/active_support/version.rb +1 -1
  225. data/lib/active_support/xml_mini/jdom.rb +4 -11
  226. data/lib/active_support/xml_mini/libxml.rb +5 -5
  227. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  228. data/lib/active_support/xml_mini/nokogiri.rb +5 -5
  229. data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
  230. data/lib/active_support/xml_mini/rexml.rb +9 -2
  231. data/lib/active_support/xml_mini.rb +7 -6
  232. data/lib/active_support.rb +40 -1
  233. metadata +127 -40
  234. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
  235. data/lib/active_support/core_ext/hash/compact.rb +0 -5
  236. data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
  237. data/lib/active_support/core_ext/marshal.rb +0 -24
  238. data/lib/active_support/core_ext/module/reachable.rb +0 -6
  239. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
  240. data/lib/active_support/core_ext/range/include_range.rb +0 -9
  241. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -23
  242. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  243. data/lib/active_support/core_ext/uri.rb +0 -25
  244. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
  245. data/lib/active_support/per_thread_registry.rb +0 -60
@@ -3,9 +3,9 @@
3
3
  require "active_support/core_ext/hash/deep_merge"
4
4
 
5
5
  module ActiveSupport
6
- class OptionMerger #:nodoc:
6
+ class OptionMerger # :nodoc:
7
7
  instance_methods.each do |method|
8
- undef_method(method) if !/^(__|instance_eval|class|object_id)/.match?(method)
8
+ undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id")
9
9
  end
10
10
 
11
11
  def initialize(context, options)
@@ -15,8 +15,8 @@ module ActiveSupport
15
15
  private
16
16
  def method_missing(method, *arguments, &block)
17
17
  options = nil
18
- if arguments.first.is_a?(Proc)
19
- proc = arguments.pop
18
+ if arguments.size == 1 && arguments.first.is_a?(Proc)
19
+ proc = arguments.shift
20
20
  arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
21
21
  elsif arguments.last.respond_to?(:to_hash)
22
22
  options = @options.deep_merge(arguments.pop)
@@ -24,22 +24,15 @@ module ActiveSupport
24
24
  options = @options
25
25
  end
26
26
 
27
- invoke_method(method, arguments, options, &block)
28
- end
29
-
30
- if RUBY_VERSION >= "2.7"
31
- def invoke_method(method, arguments, options, &block)
32
- if options
33
- @context.__send__(method, *arguments, **options, &block)
34
- else
35
- @context.__send__(method, *arguments, &block)
36
- end
37
- end
38
- else
39
- def invoke_method(method, arguments, options, &block)
40
- arguments << options.dup if options
27
+ if options
28
+ @context.__send__(method, *arguments, **options, &block)
29
+ else
41
30
  @context.__send__(method, *arguments, &block)
42
31
  end
43
32
  end
33
+
34
+ def respond_to_missing?(*arguments)
35
+ @context.respond_to?(*arguments)
36
+ end
44
37
  end
45
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,7 +3,11 @@
3
3
  require "active_support/core_ext/object/blank"
4
4
 
5
5
  module ActiveSupport
6
- # Usually key value pairs are handled something like this:
6
+ # = Ordered Options
7
+ #
8
+ # +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods.
9
+ #
10
+ # With a +Hash+, key-value pairs are typically managed like this:
7
11
  #
8
12
  # h = {}
9
13
  # h[:boy] = 'John'
@@ -12,7 +16,7 @@ module ActiveSupport
12
16
  # h[:girl] # => 'Mary'
13
17
  # h[:dog] # => nil
14
18
  #
15
- # Using +OrderedOptions+, the above code could be reduced to:
19
+ # Using +OrderedOptions+, the above code can be written as:
16
20
  #
17
21
  # h = ActiveSupport::OrderedOptions.new
18
22
  # h.boy = 'John'
@@ -38,6 +42,10 @@ module ActiveSupport
38
42
  super(key.to_sym)
39
43
  end
40
44
 
45
+ def dig(key, *identifiers)
46
+ super(key.to_sym, *identifiers)
47
+ end
48
+
41
49
  def method_missing(name, *args)
42
50
  name_string = +name.to_s
43
51
  if name_string.chomp!("=")
@@ -60,9 +68,15 @@ module ActiveSupport
60
68
  def extractable_options?
61
69
  true
62
70
  end
71
+
72
+ def inspect
73
+ "#<#{self.class.name} #{super}>"
74
+ end
63
75
  end
64
76
 
65
- # +InheritableOptions+ provides a constructor to build an +OrderedOptions+
77
+ # = Inheritable Options
78
+ #
79
+ # +InheritableOptions+ provides a constructor to build an OrderedOptions
66
80
  # hash inherited from another hash.
67
81
  #
68
82
  # Use this if you already have some hash and you want to create a new one based on it.
@@ -70,6 +84,12 @@ module ActiveSupport
70
84
  # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
71
85
  # h.girl # => 'Mary'
72
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'
73
93
  class InheritableOptions < OrderedOptions
74
94
  def initialize(parent = nil)
75
95
  if parent.kind_of?(OrderedOptions)
@@ -4,125 +4,154 @@ require "active_support/core_ext/object/duplicable"
4
4
  require "active_support/core_ext/array/extract"
5
5
 
6
6
  module ActiveSupport
7
- # +ParameterFilter+ allows you to specify keys for sensitive data from
8
- # hash-like object and replace corresponding value. Filtering only certain
9
- # sub-keys from a hash is possible by using the dot notation:
10
- # 'credit_card.number'. If a proc is given, each key and value of a hash and
11
- # all sub-hashes are passed to it, where the value or the key can be replaced
12
- # using String#replace or similar methods.
7
+ # = Active Support Parameter Filter
13
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.
14
20
  # ActiveSupport::ParameterFilter.new([:password])
15
- # => replaces the value to all keys matching /password/i with "[FILTERED]"
16
21
  #
22
+ # # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
17
23
  # ActiveSupport::ParameterFilter.new([:foo, "bar"])
18
- # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
19
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" } }`.
20
32
  # ActiveSupport::ParameterFilter.new(["credit_card.code"])
21
- # => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
22
- # change { file: { code: "xxxx"} }
23
33
  #
34
+ # # Reverses values for keys that match /secret/i.
24
35
  # ActiveSupport::ParameterFilter.new([-> (k, v) do
25
- # v.reverse! if k =~ /secret/i
36
+ # v.reverse! if /secret/i.match?(k)
26
37
  # end])
27
- # => reverses the value to all keys matching /secret/i
38
+ #
28
39
  class ParameterFilter
29
40
  FILTERED = "[FILTERED]" # :nodoc:
30
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
+
31
70
  # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
32
71
  # Other types of filters are treated as +String+ using +to_s+.
33
72
  # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
34
73
  #
35
74
  # ==== Options
36
75
  #
37
- # * <tt>:mask</tt> - A replaced object when filtered. Defaults to +"[FILTERED]"+
76
+ # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
38
77
  def initialize(filters = [], mask: FILTERED)
39
- @filters = filters
40
78
  @mask = mask
79
+ compile_filters!(filters)
41
80
  end
42
81
 
43
82
  # Mask value of +params+ if key matches one of filters.
44
83
  def filter(params)
45
- compiled_filter.call(params)
84
+ @no_filters ? params.dup : call(params)
46
85
  end
47
86
 
48
87
  # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
49
88
  def filter_param(key, value)
50
- @filters.empty? ? value : compiled_filter.value_for_key(key, value)
89
+ @no_filters ? value : value_for_key(key, value)
51
90
  end
52
91
 
53
92
  private
54
- def compiled_filter
55
- @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
56
- end
57
-
58
- class CompiledFilter # :nodoc:
59
- def self.compile(filters, mask:)
60
- return lambda { |params| params.dup } if filters.empty?
61
-
62
- strings, regexps, blocks = [], [], []
63
-
64
- filters.each do |item|
65
- case item
66
- when Proc
67
- blocks << item
68
- when Regexp
69
- regexps << item
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
108
+ else
109
+ @regexps << item
110
+ end
111
+ else
112
+ s = Regexp.escape(item.to_s)
113
+ if s.include?("\\.")
114
+ (deep_strings ||= []) << s
70
115
  else
71
- strings << Regexp.escape(item.to_s)
116
+ strings << s
72
117
  end
73
118
  end
119
+ end
74
120
 
75
- deep_regexps = regexps.extract! { |r| r.to_s.include?("\\.") }
76
- deep_strings = strings.extract! { |s| s.include?("\\.") }
121
+ @regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
122
+ (@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings
123
+ end
77
124
 
78
- regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
79
- deep_regexps << Regexp.new(deep_strings.join("|"), true) unless deep_strings.empty?
125
+ def call(params, full_parent_key = nil, original_params = params)
126
+ filtered_params = params.class.new
80
127
 
81
- new regexps, deep_regexps, blocks, mask: mask
128
+ params.each do |key, value|
129
+ filtered_params[key] = value_for_key(key, value, full_parent_key, original_params)
82
130
  end
83
131
 
84
- attr_reader :regexps, :deep_regexps, :blocks
132
+ filtered_params
133
+ end
85
134
 
86
- def initialize(regexps, deep_regexps, blocks, mask:)
87
- @regexps = regexps
88
- @deep_regexps = deep_regexps.any? ? deep_regexps : nil
89
- @blocks = blocks
90
- @mask = mask
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
91
138
  end
92
139
 
93
- def call(params, parents = [], original_params = params)
94
- filtered_params = params.class.new
95
-
96
- params.each do |key, value|
97
- filtered_params[key] = value_for_key(key, value, parents, original_params)
98
- end
99
-
100
- filtered_params
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) }
101
152
  end
102
153
 
103
- def value_for_key(key, value, parents = [], original_params = nil)
104
- parents.push(key) if deep_regexps
105
- if regexps.any? { |r| r.match?(key.to_s) }
106
- value = @mask
107
- elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
108
- value = @mask
109
- elsif value.is_a?(Hash)
110
- value = call(value, parents, original_params)
111
- elsif value.is_a?(Array)
112
- # If we don't pop the current parent it will be duplicated as we
113
- # process each array value.
114
- parents.pop if deep_regexps
115
- value = value.map { |v| value_for_key(key, v, parents, original_params) }
116
- # Restore the parent stack after processing the array.
117
- parents.push(key) if deep_regexps
118
- elsif blocks.any?
119
- key = key.dup if key.duplicable?
120
- value = value.dup if value.duplicable?
121
- blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
122
- end
123
- parents.pop if deep_regexps
124
- value
125
- end
154
+ value
126
155
  end
127
156
  end
128
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This is private interface.
3
+ # This is a private interface.
4
4
  #
5
5
  # Rails components cherry pick from Active Support as needed, but there are a
6
6
  # few features that are used for sure in some way or another and it is not worth
@@ -13,9 +13,6 @@
13
13
  # Defines Object#blank? and Object#present?.
14
14
  require "active_support/core_ext/object/blank"
15
15
 
16
- # Rails own autoload, eager_load, etc.
17
- require "active_support/dependencies/autoload"
18
-
19
16
  # Support for ClassMethods and the included macro.
20
17
  require "active_support/concern"
21
18
 
@@ -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,15 +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 }
51
+
52
+ ActiveSupport.on_load(:active_support_test_case) do
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
63
+ end
25
64
  end
26
65
 
27
66
  initializer "active_support.deprecation_behavior" do |app|
28
- if deprecation = app.config.active_support.deprecation
29
- ActiveSupport::Deprecation.behavior = deprecation
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
75
+
76
+ if disallowed_deprecation = app.config.active_support.disallowed_deprecation
77
+ app.deprecators.disallowed_behavior = disallowed_deprecation
78
+ end
79
+
80
+ if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
81
+ app.deprecators.disallowed_warnings = disallowed_warnings
82
+ end
30
83
  end
31
84
  end
32
85
 
@@ -64,17 +117,48 @@ module ActiveSupport
64
117
 
65
118
  initializer "active_support.set_configs" do |app|
66
119
  app.config.active_support.each do |k, v|
67
- k = "#{k}="
68
- ActiveSupport.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
69
130
  end
70
131
  end
71
132
 
72
133
  initializer "active_support.set_hash_digest_class" do |app|
73
134
  config.after_initialize do
74
- if app.config.active_support.use_sha1_digests
75
- ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
135
+ if klass = app.config.active_support.hash_digest_class
136
+ ActiveSupport::Digest.hash_digest_class = klass
137
+ end
138
+ end
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
76
145
  end
77
146
  end
78
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
79
163
  end
80
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
@@ -14,12 +16,12 @@ module ActiveSupport
14
16
  end
15
17
 
16
18
  module ClassMethods
17
- # Rescue exceptions raised in controller actions.
19
+ # Registers exception classes with a handler to be called by <tt>rescue_with_handler</tt>.
18
20
  #
19
21
  # <tt>rescue_from</tt> receives a series of exception classes or class
20
- # names, and a trailing <tt>:with</tt> option with the name of a method
21
- # or a Proc object to be called to handle them. Alternatively a block can
22
- # be given.
22
+ # names, and an exception handler specified by a trailing <tt>:with</tt>
23
+ # option containing the name of a method or a Proc object. Alternatively, a block
24
+ # can be given as the handler.
23
25
  #
24
26
  # Handlers that take one argument will be called with the exception, so
25
27
  # that the exception can be inspected when dealing with it.
@@ -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