activesupport 7.0.8.7 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +995 -294
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/lib/active_support/actionable_error.rb +3 -1
- data/lib/active_support/array_inquirer.rb +2 -0
- data/lib/active_support/backtrace_cleaner.rb +30 -5
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/broadcast_logger.rb +251 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +37 -10
- data/lib/active_support/cache/mem_cache_store.rb +100 -76
- data/lib/active_support/cache/memory_store.rb +78 -24
- data/lib/active_support/cache/null_store.rb +6 -0
- data/lib/active_support/cache/redis_cache_store.rb +151 -141
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +29 -14
- data/lib/active_support/cache.rb +333 -253
- data/lib/active_support/callbacks.rb +44 -21
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/concern.rb +4 -2
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/configurable.rb +10 -0
- data/lib/active_support/core_ext/array/conversions.rb +2 -1
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/class/subclasses.rb +13 -10
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -2
- data/lib/active_support/core_ext/date_time.rb +0 -1
- data/lib/active_support/core_ext/digest/uuid.rb +1 -10
- data/lib/active_support/core_ext/enumerable.rb +3 -75
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +81 -37
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +0 -1
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +2 -0
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +16 -6
- data/lib/active_support/core_ext/object/with.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +4 -4
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +2 -0
- data/lib/active_support/core_ext/pathname.rb +1 -0
- data/lib/active_support/core_ext/range/conversions.rb +28 -7
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +24 -12
- data/lib/active_support/core_ext/string/filters.rb +20 -14
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -5
- data/lib/active_support/core_ext/string/output_safety.rb +38 -174
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +18 -2
- data/lib/active_support/core_ext/time/conversions.rb +2 -2
- data/lib/active_support/core_ext/time/zones.rb +4 -4
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/current_attributes.rb +15 -6
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- data/lib/active_support/deprecation/behaviors.rb +65 -42
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +3 -5
- data/lib/active_support/deprecation/instance_delegator.rb +31 -4
- data/lib/active_support/deprecation/method_wrappers.rb +6 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +37 -22
- data/lib/active_support/deprecation/reporting.rb +43 -26
- data/lib/active_support/deprecation.rb +32 -5
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +104 -132
- data/lib/active_support/duration/iso8601_serializer.rb +0 -2
- data/lib/active_support/duration.rb +2 -1
- data/lib/active_support/encrypted_configuration.rb +30 -9
- data/lib/active_support/encrypted_file.rb +8 -3
- data/lib/active_support/environment_inquirer.rb +22 -2
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +121 -35
- data/lib/active_support/execution_wrapper.rb +4 -4
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +10 -2
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +35 -17
- data/lib/active_support/html_safe_translation.rb +16 -6
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +20 -13
- data/lib/active_support/inflector/inflections.rb +2 -0
- data/lib/active_support/inflector/methods.rb +23 -11
- data/lib/active_support/inflector/transliterate.rb +3 -1
- data/lib/active_support/isolated_execution_state.rb +26 -22
- data/lib/active_support/json/decoding.rb +2 -1
- data/lib/active_support/json/encoding.rb +25 -43
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +6 -4
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +85 -33
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_thread_safe_level.rb +10 -24
- data/lib/active_support/message_encryptor.rb +197 -53
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +212 -93
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +111 -45
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +34 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +2 -0
- data/lib/active_support/multibyte/unicode.rb +9 -37
- data/lib/active_support/notifications/fanout.rb +245 -81
- data/lib/active_support/notifications/instrumenter.rb +87 -22
- data/lib/active_support/notifications.rb +1 -1
- data/lib/active_support/number_helper/number_converter.rb +14 -5
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
- data/lib/active_support/number_helper.rb +379 -318
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +14 -0
- data/lib/active_support/parameter_filter.rb +84 -69
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/railtie.rb +33 -21
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +2 -0
- data/lib/active_support/secure_compare_rotator.rb +16 -9
- data/lib/active_support/string_inquirer.rb +3 -1
- data/lib/active_support/subscriber.rb +9 -27
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +64 -24
- data/lib/active_support/test_case.rb +153 -6
- data/lib/active_support/testing/assertions.rb +26 -10
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +25 -25
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/testing/method_call_assertions.rb +21 -8
- data/lib/active_support/testing/parallelize_executor.rb +8 -3
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/time_helpers.rb +37 -15
- data/lib/active_support/time_with_zone.rb +4 -14
- data/lib/active_support/values/time_zone.rb +18 -7
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -10
- data/lib/active_support/xml_mini/nokogiri.rb +1 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +2 -2
- data/lib/active_support.rb +14 -3
- metadata +143 -14
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
- data/lib/active_support/core_ext/uri.rb +0 -5
- data/lib/active_support/per_thread_registry.rb +0 -65
@@ -11,34 +11,50 @@ module ActiveSupport
|
|
11
11
|
attr_accessor :gem_name
|
12
12
|
|
13
13
|
# Outputs a deprecation warning to the output configured by
|
14
|
-
#
|
14
|
+
# ActiveSupport::Deprecation#behavior.
|
15
15
|
#
|
16
|
-
# ActiveSupport::Deprecation.warn('something broke!')
|
16
|
+
# ActiveSupport::Deprecation.new.warn('something broke!')
|
17
17
|
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
|
18
18
|
def warn(message = nil, callstack = nil)
|
19
19
|
return if silenced
|
20
20
|
|
21
21
|
callstack ||= caller_locations(2)
|
22
|
-
deprecation_message(callstack, message).tap do |
|
22
|
+
deprecation_message(callstack, message).tap do |full_message|
|
23
23
|
if deprecation_disallowed?(message)
|
24
|
-
disallowed_behavior.each { |b| b.call(
|
24
|
+
disallowed_behavior.each { |b| b.call(full_message, callstack, self) }
|
25
25
|
else
|
26
|
-
behavior.each { |b| b.call(
|
26
|
+
behavior.each { |b| b.call(full_message, callstack, self) }
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
# Silence deprecation warnings within the block.
|
32
32
|
#
|
33
|
-
# ActiveSupport::Deprecation.
|
33
|
+
# deprecator = ActiveSupport::Deprecation.new
|
34
|
+
# deprecator.warn('something broke!')
|
34
35
|
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
|
35
36
|
#
|
36
|
-
#
|
37
|
-
#
|
37
|
+
# deprecator.silence do
|
38
|
+
# deprecator.warn('something broke!')
|
38
39
|
# end
|
39
40
|
# # => nil
|
40
41
|
def silence(&block)
|
41
|
-
|
42
|
+
begin_silence
|
43
|
+
block.call
|
44
|
+
ensure
|
45
|
+
end_silence
|
46
|
+
end
|
47
|
+
|
48
|
+
def begin_silence # :nodoc:
|
49
|
+
@silence_counter.value += 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def end_silence # :nodoc:
|
53
|
+
@silence_counter.value -= 1
|
54
|
+
end
|
55
|
+
|
56
|
+
def silenced
|
57
|
+
@silenced || @silence_counter.value.nonzero?
|
42
58
|
end
|
43
59
|
|
44
60
|
# Allow previously disallowed deprecation warnings within the block.
|
@@ -46,27 +62,28 @@ module ActiveSupport
|
|
46
62
|
# expressions. (Symbols are treated as strings). These are compared against
|
47
63
|
# the text of deprecation warning messages generated within the block.
|
48
64
|
# Matching warnings will be exempt from the rules set by
|
49
|
-
#
|
65
|
+
# ActiveSupport::Deprecation#disallowed_warnings.
|
50
66
|
#
|
51
67
|
# The optional <tt>if:</tt> argument accepts a truthy/falsy value or an object that
|
52
68
|
# responds to <tt>.call</tt>. If truthy, then matching warnings will be allowed.
|
53
69
|
# If falsey then the method yields to the block without allowing the warning.
|
54
70
|
#
|
55
|
-
# ActiveSupport::Deprecation.
|
56
|
-
#
|
71
|
+
# deprecator = ActiveSupport::Deprecation.new
|
72
|
+
# deprecator.disallowed_behavior = :raise
|
73
|
+
# deprecator.disallowed_warnings = [
|
57
74
|
# "something broke"
|
58
75
|
# ]
|
59
76
|
#
|
60
|
-
#
|
77
|
+
# deprecator.warn('something broke!')
|
61
78
|
# # => ActiveSupport::DeprecationException
|
62
79
|
#
|
63
|
-
#
|
64
|
-
#
|
80
|
+
# deprecator.allow ['something broke'] do
|
81
|
+
# deprecator.warn('something broke!')
|
65
82
|
# end
|
66
83
|
# # => nil
|
67
84
|
#
|
68
|
-
#
|
69
|
-
#
|
85
|
+
# deprecator.allow ['something broke'], if: Rails.env.production? do
|
86
|
+
# deprecator.warn('something broke!')
|
70
87
|
# end
|
71
88
|
# # => ActiveSupport::DeprecationException for dev/test, nil for production
|
72
89
|
def allow(allowed_warnings = :all, if: true, &block)
|
@@ -79,10 +96,6 @@ module ActiveSupport
|
|
79
96
|
end
|
80
97
|
end
|
81
98
|
|
82
|
-
def silenced
|
83
|
-
@silenced || @silenced_thread.value
|
84
|
-
end
|
85
|
-
|
86
99
|
def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
|
87
100
|
caller_backtrace ||= caller_locations(2)
|
88
101
|
deprecated_method_warning(deprecated_method_name, message).tap do |msg|
|
@@ -125,10 +138,13 @@ module ActiveSupport
|
|
125
138
|
end
|
126
139
|
|
127
140
|
def extract_callstack(callstack)
|
141
|
+
return [] if callstack.empty?
|
128
142
|
return _extract_callstack(callstack) if callstack.first.is_a? String
|
129
143
|
|
130
144
|
offending_line = callstack.find { |frame|
|
131
|
-
|
145
|
+
# Code generated with `eval` doesn't have an `absolute_path`, e.g. templates.
|
146
|
+
path = frame.absolute_path || frame.path
|
147
|
+
path && !ignored_callstack?(path)
|
132
148
|
} || callstack.first
|
133
149
|
|
134
150
|
[offending_line.path, offending_line.lineno, offending_line.label]
|
@@ -136,7 +152,7 @@ module ActiveSupport
|
|
136
152
|
|
137
153
|
def _extract_callstack(callstack)
|
138
154
|
warn "Please pass `caller_locations` to the deprecation API" if $VERBOSE
|
139
|
-
offending_line = callstack.find { |line| !ignored_callstack(line) } || callstack.first
|
155
|
+
offending_line = callstack.find { |line| !ignored_callstack?(line) } || callstack.first
|
140
156
|
|
141
157
|
if offending_line
|
142
158
|
if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
|
@@ -147,10 +163,11 @@ module ActiveSupport
|
|
147
163
|
end
|
148
164
|
end
|
149
165
|
|
150
|
-
RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/"
|
166
|
+
RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/" # :nodoc:
|
167
|
+
LIB_DIR = RbConfig::CONFIG["libdir"] # :nodoc:
|
151
168
|
|
152
|
-
def ignored_callstack(path)
|
153
|
-
path.start_with?(RAILS_GEM_ROOT
|
169
|
+
def ignored_callstack?(path)
|
170
|
+
path.start_with?(RAILS_GEM_ROOT, LIB_DIR)
|
154
171
|
end
|
155
172
|
end
|
156
173
|
end
|
@@ -3,8 +3,35 @@
|
|
3
3
|
require "singleton"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# = Active Support \Deprecation
|
7
|
+
#
|
8
|
+
# \Deprecation specifies the API used by \Rails to deprecate methods, instance variables, objects, and constants. It's
|
9
|
+
# also available for gems or applications.
|
10
|
+
#
|
11
|
+
# For a gem, use Deprecation.new to create a Deprecation object and store it in your module or class (in order for
|
12
|
+
# users to be able to configure it).
|
13
|
+
#
|
14
|
+
# module MyLibrary
|
15
|
+
# def self.deprecator
|
16
|
+
# @deprecator ||= ActiveSupport::Deprecation.new("2.0", "MyLibrary")
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# For a Railtie or Engine, you may also want to add it to the application's deprecators, so that the application's
|
21
|
+
# configuration can be applied to it.
|
22
|
+
#
|
23
|
+
# module MyLibrary
|
24
|
+
# class Railtie < Rails::Railtie
|
25
|
+
# initializer "my_library.deprecator" do |app|
|
26
|
+
# app.deprecators[:my_library] = MyLibrary.deprecator
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# With the above initializer, configuration settings like the following will affect +MyLibrary.deprecator+:
|
32
|
+
#
|
33
|
+
# # in config/environments/test.rb
|
34
|
+
# config.active_support.deprecation = :raise
|
8
35
|
class Deprecation
|
9
36
|
# active_support.rb sets an autoload for ActiveSupport::Deprecation.
|
10
37
|
#
|
@@ -21,10 +48,10 @@ module ActiveSupport
|
|
21
48
|
require "active_support/deprecation/constant_accessor"
|
22
49
|
require "active_support/deprecation/method_wrappers"
|
23
50
|
require "active_support/deprecation/proxy_wrappers"
|
51
|
+
require "active_support/deprecation/deprecators"
|
24
52
|
require "active_support/core_ext/module/deprecation"
|
25
53
|
require "concurrent/atomic/thread_local_var"
|
26
54
|
|
27
|
-
include Singleton
|
28
55
|
include InstanceDelegator
|
29
56
|
include Behavior
|
30
57
|
include Reporting
|
@@ -38,13 +65,13 @@ module ActiveSupport
|
|
38
65
|
# and the second is a library name.
|
39
66
|
#
|
40
67
|
# ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
|
41
|
-
def initialize(deprecation_horizon = "7.
|
68
|
+
def initialize(deprecation_horizon = "7.2", gem_name = "Rails")
|
42
69
|
self.gem_name = gem_name
|
43
70
|
self.deprecation_horizon = deprecation_horizon
|
44
71
|
# By default, warnings are not silenced and debugging is off.
|
45
72
|
self.silenced = false
|
46
73
|
self.debug = false
|
47
|
-
@
|
74
|
+
@silence_counter = Concurrent::ThreadLocalVar.new(0)
|
48
75
|
@explicitly_allowed_warnings = Concurrent::ThreadLocalVar.new(nil)
|
49
76
|
end
|
50
77
|
end
|
@@ -4,174 +4,116 @@ require "weakref"
|
|
4
4
|
require "active_support/ruby_features"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
+
# = Active Support Descendants Tracker
|
8
|
+
#
|
7
9
|
# This module provides an internal implementation to track descendants
|
8
|
-
# which is faster than iterating through ObjectSpace
|
10
|
+
# which is faster than iterating through +ObjectSpace+.
|
11
|
+
#
|
12
|
+
# However Ruby 3.1 provide a fast native +Class#subclasses+ method,
|
13
|
+
# so if you know your code won't be executed on older rubies, including
|
14
|
+
# +ActiveSupport::DescendantsTracker+ does not provide any benefit.
|
9
15
|
module DescendantsTracker
|
10
|
-
class << self
|
11
|
-
def direct_descendants(klass)
|
12
|
-
ActiveSupport::Deprecation.warn(<<~MSG)
|
13
|
-
ActiveSupport::DescendantsTracker.direct_descendants is deprecated and will be removed in Rails 7.1.
|
14
|
-
Use ActiveSupport::DescendantsTracker.subclasses instead.
|
15
|
-
MSG
|
16
|
-
subclasses(klass)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
16
|
@clear_disabled = false
|
21
17
|
|
22
|
-
if
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
else
|
28
|
-
# On TruffleRuby `ObjectSpace::WeakMap` keys are strong references.
|
29
|
-
# So we use `object_id` as a key and the actual object as a value.
|
30
|
-
#
|
31
|
-
# JRuby for now doesn't have Class#descendant, but when it will, it will likely
|
32
|
-
# have the same WeakMap semantic than Truffle so we future proof this as much as possible.
|
33
|
-
class WeakSet # :nodoc:
|
34
|
-
def initialize
|
35
|
-
@map = ObjectSpace::WeakMap.new
|
36
|
-
end
|
18
|
+
if RUBY_ENGINE == "ruby"
|
19
|
+
# On MRI `ObjectSpace::WeakMap` keys are weak references.
|
20
|
+
# So we can simply use WeakMap as a `Set`.
|
21
|
+
class WeakSet < ObjectSpace::WeakMap # :nodoc:
|
22
|
+
alias_method :to_a, :keys
|
37
23
|
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def []=(object, _present)
|
43
|
-
@map[object.object_id] = object
|
44
|
-
end
|
24
|
+
def <<(object)
|
25
|
+
self[object] = true
|
45
26
|
end
|
46
|
-
WeakSet.new
|
47
27
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
28
|
+
else
|
29
|
+
# On TruffleRuby `ObjectSpace::WeakMap` keys are strong references.
|
30
|
+
# So we use `object_id` as a key and the actual object as a value.
|
31
|
+
#
|
32
|
+
# JRuby for now doesn't have Class#descendant, but when it will, it will likely
|
33
|
+
# have the same WeakMap semantic than Truffle so we future proof this as much as possible.
|
34
|
+
class WeakSet # :nodoc:
|
35
|
+
def initialize
|
36
|
+
@map = ObjectSpace::WeakMap.new
|
56
37
|
end
|
57
38
|
|
58
|
-
def
|
59
|
-
|
39
|
+
def [](object)
|
40
|
+
@map.key?(object.object_id)
|
60
41
|
end
|
42
|
+
alias_method :include?, :[]
|
61
43
|
|
62
|
-
def
|
63
|
-
|
44
|
+
def []=(object, _present)
|
45
|
+
@map[object.object_id] = object
|
64
46
|
end
|
65
47
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
classes.each do |klass|
|
70
|
-
@@excluded_descendants[klass] = true
|
71
|
-
klass.descendants.each do |descendant|
|
72
|
-
@@excluded_descendants[descendant] = true
|
73
|
-
end
|
74
|
-
end
|
48
|
+
def to_a
|
49
|
+
@map.values
|
75
50
|
end
|
76
51
|
|
77
|
-
def
|
78
|
-
true
|
52
|
+
def <<(object)
|
53
|
+
self[object] = true
|
79
54
|
end
|
80
55
|
end
|
56
|
+
end
|
57
|
+
@excluded_descendants = WeakSet.new
|
81
58
|
|
59
|
+
module ReloadedClassesFiltering # :nodoc:
|
82
60
|
def subclasses
|
83
|
-
|
84
|
-
subclasses.reject! { |d| @@excluded_descendants[d] }
|
85
|
-
subclasses
|
61
|
+
DescendantsTracker.reject!(super)
|
86
62
|
end
|
87
63
|
|
88
64
|
def descendants
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
def direct_descendants
|
93
|
-
ActiveSupport::Deprecation.warn(<<~MSG)
|
94
|
-
ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
|
95
|
-
Use #subclasses instead.
|
96
|
-
MSG
|
97
|
-
subclasses
|
65
|
+
DescendantsTracker.reject!(super)
|
98
66
|
end
|
99
|
-
|
100
|
-
@@direct_descendants = {}
|
67
|
+
end
|
101
68
|
|
102
|
-
|
103
|
-
|
69
|
+
class << self
|
70
|
+
def disable_clear! # :nodoc:
|
71
|
+
unless @clear_disabled
|
104
72
|
@clear_disabled = true
|
73
|
+
ReloadedClassesFiltering.remove_method(:subclasses)
|
74
|
+
ReloadedClassesFiltering.remove_method(:descendants)
|
75
|
+
@excluded_descendants = nil
|
105
76
|
end
|
77
|
+
end
|
106
78
|
|
107
|
-
|
108
|
-
|
109
|
-
descendants ? descendants.to_a : []
|
110
|
-
end
|
79
|
+
def clear(classes) # :nodoc:
|
80
|
+
raise "DescendantsTracker.clear was disabled because config.enable_reloading is false" if @clear_disabled
|
111
81
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
def clear(classes) # :nodoc:
|
119
|
-
raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
|
120
|
-
|
121
|
-
@@direct_descendants.each do |klass, direct_descendants_of_klass|
|
122
|
-
if classes.member?(klass)
|
123
|
-
@@direct_descendants.delete(klass)
|
124
|
-
else
|
125
|
-
direct_descendants_of_klass.reject! do |direct_descendant_of_class|
|
126
|
-
classes.member?(direct_descendant_of_class)
|
127
|
-
end
|
128
|
-
end
|
82
|
+
classes.each do |klass|
|
83
|
+
@excluded_descendants << klass
|
84
|
+
klass.descendants.each do |descendant|
|
85
|
+
@excluded_descendants << descendant
|
129
86
|
end
|
130
87
|
end
|
131
|
-
|
132
|
-
def native? # :nodoc:
|
133
|
-
false
|
134
|
-
end
|
135
|
-
|
136
|
-
# This is the only method that is not thread safe, but is only ever called
|
137
|
-
# during the eager loading phase.
|
138
|
-
def store_inherited(klass, descendant)
|
139
|
-
(@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
|
140
|
-
end
|
141
|
-
|
142
|
-
private
|
143
|
-
def accumulate_descendants(klass, acc)
|
144
|
-
if direct_descendants = @@direct_descendants[klass]
|
145
|
-
direct_descendants.each do |direct_descendant|
|
146
|
-
acc << direct_descendant
|
147
|
-
accumulate_descendants(direct_descendant, acc)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
88
|
end
|
152
89
|
|
153
|
-
def
|
154
|
-
|
155
|
-
|
90
|
+
def reject!(classes) # :nodoc:
|
91
|
+
if @excluded_descendants
|
92
|
+
classes.reject! { |d| @excluded_descendants.include?(d) }
|
93
|
+
end
|
94
|
+
classes
|
156
95
|
end
|
96
|
+
end
|
157
97
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
DescendantsTracker.subclasses(self)
|
164
|
-
end
|
98
|
+
if RubyFeatures::CLASS_SUBCLASSES
|
99
|
+
class << self
|
100
|
+
def subclasses(klass)
|
101
|
+
klass.subclasses
|
102
|
+
end
|
165
103
|
|
166
|
-
|
167
|
-
|
104
|
+
def descendants(klass)
|
105
|
+
klass.descendants
|
106
|
+
end
|
168
107
|
end
|
169
108
|
|
170
109
|
def descendants
|
171
|
-
DescendantsTracker.
|
110
|
+
subclasses = DescendantsTracker.reject!(self.subclasses)
|
111
|
+
subclasses.concat(subclasses.flat_map(&:descendants))
|
172
112
|
end
|
173
|
-
|
113
|
+
else
|
174
114
|
# DescendantsArray is an array that contains weak references to classes.
|
115
|
+
# Note: DescendantsArray is redundant with WeakSet, however WeakSet when used
|
116
|
+
# on Ruby 2.7 or 3.0 can trigger a Ruby crash: https://bugs.ruby-lang.org/issues/18928
|
175
117
|
class DescendantsArray # :nodoc:
|
176
118
|
include Enumerable
|
177
119
|
|
@@ -179,10 +121,6 @@ module ActiveSupport
|
|
179
121
|
@refs = []
|
180
122
|
end
|
181
123
|
|
182
|
-
def initialize_copy(orig)
|
183
|
-
@refs = @refs.dup
|
184
|
-
end
|
185
|
-
|
186
124
|
def <<(klass)
|
187
125
|
@refs << WeakRef.new(klass)
|
188
126
|
end
|
@@ -213,6 +151,40 @@ module ActiveSupport
|
|
213
151
|
end
|
214
152
|
end
|
215
153
|
end
|
154
|
+
|
155
|
+
@direct_descendants = {}
|
156
|
+
|
157
|
+
class << self
|
158
|
+
def subclasses(klass)
|
159
|
+
descendants = @direct_descendants[klass]
|
160
|
+
descendants ? DescendantsTracker.reject!(descendants.to_a) : []
|
161
|
+
end
|
162
|
+
|
163
|
+
def descendants(klass)
|
164
|
+
subclasses = self.subclasses(klass)
|
165
|
+
subclasses.concat(subclasses.flat_map { |k| descendants(k) })
|
166
|
+
end
|
167
|
+
|
168
|
+
# This is the only method that is not thread safe, but is only ever called
|
169
|
+
# during the eager loading phase.
|
170
|
+
def store_inherited(klass, descendant) # :nodoc:
|
171
|
+
(@direct_descendants[klass] ||= DescendantsArray.new) << descendant
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def subclasses
|
176
|
+
DescendantsTracker.subclasses(self)
|
177
|
+
end
|
178
|
+
|
179
|
+
def descendants
|
180
|
+
DescendantsTracker.descendants(self)
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
def inherited(base) # :nodoc:
|
185
|
+
DescendantsTracker.store_inherited(self, base)
|
186
|
+
super
|
187
|
+
end
|
216
188
|
end
|
217
189
|
end
|
218
190
|
end
|
@@ -3,9 +3,10 @@
|
|
3
3
|
require "active_support/core_ext/array/conversions"
|
4
4
|
require "active_support/core_ext/module/delegation"
|
5
5
|
require "active_support/core_ext/object/acts_like"
|
6
|
-
require "active_support/core_ext/string/filters"
|
7
6
|
|
8
7
|
module ActiveSupport
|
8
|
+
# = Active Support \Duration
|
9
|
+
#
|
9
10
|
# Provides accurate date and time measurements using Date#advance and
|
10
11
|
# Time#advance, respectively. It mainly supports the methods on Numeric.
|
11
12
|
#
|
@@ -4,9 +4,12 @@ require "yaml"
|
|
4
4
|
require "active_support/encrypted_file"
|
5
5
|
require "active_support/ordered_options"
|
6
6
|
require "active_support/core_ext/object/inclusion"
|
7
|
+
require "active_support/core_ext/hash/keys"
|
7
8
|
require "active_support/core_ext/module/delegation"
|
8
9
|
|
9
10
|
module ActiveSupport
|
11
|
+
# = Encrypted Configuration
|
12
|
+
#
|
10
13
|
# Provides convenience methods on top of EncryptedFile to access values stored
|
11
14
|
# as encrypted YAML.
|
12
15
|
#
|
@@ -30,12 +33,23 @@ module ActiveSupport
|
|
30
33
|
# # => KeyError
|
31
34
|
#
|
32
35
|
class EncryptedConfiguration < EncryptedFile
|
33
|
-
|
36
|
+
class InvalidContentError < RuntimeError
|
37
|
+
def initialize(content_path)
|
38
|
+
super "Invalid YAML in '#{content_path}'."
|
39
|
+
end
|
40
|
+
|
41
|
+
def message
|
42
|
+
cause.is_a?(Psych::SyntaxError) ? "#{super}\n\n #{cause.message}" : super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
34
46
|
delegate_missing_to :options
|
35
47
|
|
36
48
|
def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:)
|
37
49
|
super content_path: config_path, key_path: key_path,
|
38
50
|
env_key: env_key, raise_if_missing_key: raise_if_missing_key
|
51
|
+
@config = nil
|
52
|
+
@options = nil
|
39
53
|
end
|
40
54
|
|
41
55
|
# Reads the file and returns the decrypted content. See EncryptedFile#read.
|
@@ -46,10 +60,8 @@ module ActiveSupport
|
|
46
60
|
""
|
47
61
|
end
|
48
62
|
|
49
|
-
def
|
50
|
-
deserialize(
|
51
|
-
|
52
|
-
super
|
63
|
+
def validate! # :nodoc:
|
64
|
+
deserialize(read)
|
53
65
|
end
|
54
66
|
|
55
67
|
# Returns the decrypted content as a Hash with symbolized keys.
|
@@ -64,11 +76,15 @@ module ActiveSupport
|
|
64
76
|
@config ||= deserialize(read).deep_symbolize_keys
|
65
77
|
end
|
66
78
|
|
79
|
+
def inspect # :nodoc:
|
80
|
+
"#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>"
|
81
|
+
end
|
82
|
+
|
67
83
|
private
|
68
84
|
def deep_transform(hash)
|
69
85
|
return hash unless hash.is_a?(Hash)
|
70
86
|
|
71
|
-
h = ActiveSupport::
|
87
|
+
h = ActiveSupport::OrderedOptions.new
|
72
88
|
hash.each do |k, v|
|
73
89
|
h[k] = deep_transform(v)
|
74
90
|
end
|
@@ -79,9 +95,14 @@ module ActiveSupport
|
|
79
95
|
@options ||= deep_transform(config)
|
80
96
|
end
|
81
97
|
|
82
|
-
def deserialize(
|
83
|
-
|
84
|
-
|
98
|
+
def deserialize(content)
|
99
|
+
config = YAML.respond_to?(:unsafe_load) ?
|
100
|
+
YAML.unsafe_load(content, filename: content_path) :
|
101
|
+
YAML.load(content, filename: content_path)
|
102
|
+
|
103
|
+
config.presence || {}
|
104
|
+
rescue Psych::SyntaxError
|
105
|
+
raise InvalidContentError.new(content_path)
|
85
106
|
end
|
86
107
|
end
|
87
108
|
end
|
@@ -53,6 +53,12 @@ module ActiveSupport
|
|
53
53
|
read_env_key || read_key_file || handle_missing_key
|
54
54
|
end
|
55
55
|
|
56
|
+
# Returns truthy if #key is truthy. Returns falsy otherwise. Unlike #key,
|
57
|
+
# does not raise MissingKeyError when +raise_if_missing_key+ is true.
|
58
|
+
def key?
|
59
|
+
read_env_key || read_key_file
|
60
|
+
end
|
61
|
+
|
56
62
|
# Reads the file and returns the decrypted content.
|
57
63
|
#
|
58
64
|
# Raises:
|
@@ -104,7 +110,7 @@ module ActiveSupport
|
|
104
110
|
end
|
105
111
|
|
106
112
|
def encryptor
|
107
|
-
@encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: CIPHER)
|
113
|
+
@encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: CIPHER, serializer: Marshal)
|
108
114
|
end
|
109
115
|
|
110
116
|
|
@@ -113,8 +119,7 @@ module ActiveSupport
|
|
113
119
|
end
|
114
120
|
|
115
121
|
def read_key_file
|
116
|
-
|
117
|
-
@key_file_contents = (key_path.binread.strip if key_path.exist?)
|
122
|
+
@key_file_contents ||= (key_path.binread.strip if key_path.exist?)
|
118
123
|
end
|
119
124
|
|
120
125
|
def handle_missing_key
|