activesupport 6.0.6.1 → 6.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +337 -573
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +3 -3
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +2 -2
- data/lib/active_support/cache/mem_cache_store.rb +20 -14
- data/lib/active_support/cache/memory_store.rb +38 -26
- data/lib/active_support/cache/redis_cache_store.rb +25 -25
- data/lib/active_support/cache/strategy/local_cache.rb +13 -4
- data/lib/active_support/cache.rb +75 -34
- data/lib/active_support/callbacks.rb +65 -56
- data/lib/active_support/concern.rb +46 -2
- data/lib/active_support/configurable.rb +3 -3
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +17 -38
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/enumerable.rb +76 -4
- data/lib/active_support/core_ext/hash/conversions.rb +2 -2
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +23 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -4
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +38 -28
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +29 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +22 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +5 -1
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/range/compare_range.rb +9 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/inflections.rb +38 -4
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +8 -38
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +5 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +7 -2
- data/lib/active_support/dependencies.rb +38 -24
- data/lib/active_support/deprecation/behaviors.rb +15 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +3 -2
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/descendants_tracker.rb +6 -2
- data/lib/active_support/duration/iso8601_serializer.rb +15 -9
- data/lib/active_support/duration.rb +71 -22
- data/lib/active_support/encrypted_file.rb +19 -2
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +69 -133
- data/lib/active_support/execution_wrapper.rb +13 -16
- data/lib/active_support/fork_tracker.rb +58 -0
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +35 -22
- data/lib/active_support/i18n_railtie.rb +14 -19
- data/lib/active_support/inflector/inflections.rb +1 -2
- data/lib/active_support/inflector/methods.rb +35 -31
- data/lib/active_support/inflector/transliterate.rb +4 -4
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +5 -1
- data/lib/active_support/key_generator.rb +1 -1
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber.rb +8 -0
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -12
- data/lib/active_support/message_encryptor.rb +4 -7
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +4 -42
- data/lib/active_support/multibyte/unicode.rb +9 -83
- data/lib/active_support/notifications/fanout.rb +23 -8
- data/lib/active_support/notifications/instrumenter.rb +6 -15
- data/lib/active_support/notifications.rb +31 -4
- data/lib/active_support/number_helper/number_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +3 -3
- data/lib/active_support/number_helper/rounding_helper.rb +12 -28
- data/lib/active_support/number_helper.rb +29 -14
- data/lib/active_support/option_merger.rb +2 -1
- data/lib/active_support/ordered_options.rb +8 -2
- data/lib/active_support/parameter_filter.rb +15 -10
- data/lib/active_support/per_thread_registry.rb +1 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +23 -1
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +12 -7
- data/lib/active_support/tagged_logging.rb +29 -4
- data/lib/active_support/testing/assertions.rb +18 -11
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +12 -95
- data/lib/active_support/testing/time_helpers.rb +40 -3
- data/lib/active_support/time_with_zone.rb +66 -42
- data/lib/active_support/values/time_zone.rb +20 -10
- data/lib/active_support/xml_mini/rexml.rb +8 -1
- data/lib/active_support.rb +13 -1
- metadata +39 -42
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "erb"
|
4
|
-
require "active_support/core_ext/kernel/singleton_class"
|
5
4
|
require "active_support/core_ext/module/redefine_method"
|
6
5
|
require "active_support/multibyte/unicode"
|
7
6
|
|
@@ -12,14 +11,6 @@ class ERB
|
|
12
11
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
13
12
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
14
13
|
|
15
|
-
# Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name
|
16
|
-
TAG_NAME_START_REGEXP_SET = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
|
17
|
-
"\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
|
18
|
-
"\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
|
19
|
-
TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}]/
|
20
|
-
TAG_NAME_FOLLOWING_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}]/
|
21
|
-
TAG_NAME_REPLACEMENT_CHAR = "_"
|
22
|
-
|
23
14
|
# A utility method for escaping HTML tag characters.
|
24
15
|
# This method is also aliased as <tt>h</tt>.
|
25
16
|
#
|
@@ -124,26 +115,6 @@ class ERB
|
|
124
115
|
end
|
125
116
|
|
126
117
|
module_function :json_escape
|
127
|
-
|
128
|
-
# A utility method for escaping XML names of tags and names of attributes.
|
129
|
-
#
|
130
|
-
# xml_name_escape('1 < 2 & 3')
|
131
|
-
# # => "1___2___3"
|
132
|
-
#
|
133
|
-
# It follows the requirements of the specification: https://www.w3.org/TR/REC-xml/#NT-Name
|
134
|
-
def xml_name_escape(name)
|
135
|
-
name = name.to_s
|
136
|
-
return "" if name.blank?
|
137
|
-
|
138
|
-
starting_char = name[0].gsub(TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
139
|
-
|
140
|
-
return starting_char if name.size == 1
|
141
|
-
|
142
|
-
following_chars = name[1..-1].gsub(TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
143
|
-
|
144
|
-
starting_char + following_chars
|
145
|
-
end
|
146
|
-
module_function :xml_name_escape
|
147
118
|
end
|
148
119
|
end
|
149
120
|
|
@@ -163,7 +134,7 @@ module ActiveSupport #:nodoc:
|
|
163
134
|
class SafeBuffer < String
|
164
135
|
UNSAFE_STRING_METHODS = %w(
|
165
136
|
capitalize chomp chop delete delete_prefix delete_suffix
|
166
|
-
downcase lstrip next reverse rstrip
|
137
|
+
downcase lstrip next reverse rstrip slice squeeze strip
|
167
138
|
succ swapcase tr tr_s unicode_normalize upcase
|
168
139
|
)
|
169
140
|
|
@@ -181,12 +152,12 @@ module ActiveSupport #:nodoc:
|
|
181
152
|
|
182
153
|
def [](*args)
|
183
154
|
if html_safe?
|
184
|
-
|
155
|
+
new_safe_buffer = super
|
185
156
|
|
186
|
-
|
157
|
+
if new_safe_buffer
|
158
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
159
|
+
end
|
187
160
|
|
188
|
-
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
189
|
-
new_safe_buffer.instance_variable_set :@html_safe, true
|
190
161
|
new_safe_buffer
|
191
162
|
else
|
192
163
|
to_str[*args]
|
@@ -230,7 +201,7 @@ module ActiveSupport #:nodoc:
|
|
230
201
|
end
|
231
202
|
|
232
203
|
def []=(*args)
|
233
|
-
if args.
|
204
|
+
if args.length == 3
|
234
205
|
super(args[0], args[1], html_escape_interpolated_argument(args[2]))
|
235
206
|
else
|
236
207
|
super(args[0], html_escape_interpolated_argument(args[1]))
|
@@ -242,8 +213,7 @@ module ActiveSupport #:nodoc:
|
|
242
213
|
end
|
243
214
|
|
244
215
|
def *(*)
|
245
|
-
|
246
|
-
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
216
|
+
new_safe_buffer = super
|
247
217
|
new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
|
248
218
|
new_safe_buffer
|
249
219
|
end
|
@@ -251,7 +221,7 @@ module ActiveSupport #:nodoc:
|
|
251
221
|
def %(args)
|
252
222
|
case args
|
253
223
|
when Hash
|
254
|
-
escaped_args =
|
224
|
+
escaped_args = args.transform_values { |arg| html_escape_interpolated_argument(arg) }
|
255
225
|
else
|
256
226
|
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
257
227
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Symbol
|
4
|
+
def start_with?(*prefixes)
|
5
|
+
to_s.start_with?(*prefixes)
|
6
|
+
end unless method_defined?(:start_with?)
|
7
|
+
|
8
|
+
def end_with?(*suffixes)
|
9
|
+
to_s.end_with?(*suffixes)
|
10
|
+
end unless method_defined?(:end_with?)
|
11
|
+
|
12
|
+
alias :starts_with? :start_with?
|
13
|
+
alias :ends_with? :end_with?
|
14
|
+
end
|
@@ -6,6 +6,7 @@ require "active_support/time_with_zone"
|
|
6
6
|
require "active_support/core_ext/time/zones"
|
7
7
|
require "active_support/core_ext/date_and_time/calculations"
|
8
8
|
require "active_support/core_ext/date/calculations"
|
9
|
+
require "active_support/core_ext/module/remove_method"
|
9
10
|
|
10
11
|
class Time
|
11
12
|
include DateAndTime::Calculations
|
@@ -107,6 +108,21 @@ class Time
|
|
107
108
|
subsec
|
108
109
|
end
|
109
110
|
|
111
|
+
unless Time.method_defined?(:floor)
|
112
|
+
def floor(precision = 0)
|
113
|
+
change(nsec: 0) + subsec.floor(precision)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Restricted Ruby version due to a bug in `Time#ceil`
|
118
|
+
# See https://bugs.ruby-lang.org/issues/17025 for more details
|
119
|
+
if RUBY_VERSION <= "2.8"
|
120
|
+
remove_possible_method :ceil
|
121
|
+
def ceil(precision = 0)
|
122
|
+
change(nsec: 0) + subsec.ceil(precision)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
110
126
|
# Returns a new Time where one or more of the elements have been changed according
|
111
127
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
112
128
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
@@ -19,7 +19,11 @@ end
|
|
19
19
|
module URI
|
20
20
|
class << self
|
21
21
|
def parser
|
22
|
-
|
22
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
23
|
+
URI.parser is deprecated and will be removed in Rails 6.2.
|
24
|
+
Use `URI::DEFAULT_PARSER` instead.
|
25
|
+
MSG
|
26
|
+
URI::DEFAULT_PARSER
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
|
4
|
+
def before_setup
|
5
|
+
ActiveSupport::CurrentAttributes.reset_all
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def before_teardown
|
10
|
+
ActiveSupport::CurrentAttributes.reset_all
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/callbacks"
|
4
|
+
require "active_support/core_ext/enumerable"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
|
@@ -91,7 +92,7 @@ module ActiveSupport
|
|
91
92
|
class << self
|
92
93
|
# Returns singleton instance for this class in this thread. If none exists, one is created.
|
93
94
|
def instance
|
94
|
-
current_instances[
|
95
|
+
current_instances[current_instances_key] ||= new
|
95
96
|
end
|
96
97
|
|
97
98
|
# Declares one or more attributes that will be given both class and instance accessor methods.
|
@@ -150,6 +151,10 @@ module ActiveSupport
|
|
150
151
|
Thread.current[:current_attributes_instances] ||= {}
|
151
152
|
end
|
152
153
|
|
154
|
+
def current_instances_key
|
155
|
+
@current_instances_key ||= name.to_sym
|
156
|
+
end
|
157
|
+
|
153
158
|
def method_missing(name, *args, &block)
|
154
159
|
# Caches the method definition as a singleton method of the receiver.
|
155
160
|
#
|
@@ -197,7 +202,7 @@ module ActiveSupport
|
|
197
202
|
end
|
198
203
|
|
199
204
|
def compute_attributes(keys)
|
200
|
-
keys.
|
205
|
+
keys.index_with { |key| public_send(key) }
|
201
206
|
end
|
202
207
|
end
|
203
208
|
end
|
@@ -12,7 +12,6 @@ require "active_support/core_ext/object/blank"
|
|
12
12
|
require "active_support/core_ext/kernel/reporting"
|
13
13
|
require "active_support/core_ext/load_error"
|
14
14
|
require "active_support/core_ext/name_error"
|
15
|
-
require "active_support/core_ext/string/starts_ends_with"
|
16
15
|
require "active_support/dependencies/interlock"
|
17
16
|
require "active_support/inflector"
|
18
17
|
|
@@ -262,15 +261,24 @@ module ActiveSupport #:nodoc:
|
|
262
261
|
|
263
262
|
# :doc:
|
264
263
|
|
265
|
-
#
|
266
|
-
#
|
264
|
+
# <b>Warning:</b> This method is obsolete in +:zeitwerk+ mode. In
|
265
|
+
# +:zeitwerk+ mode semantics match Ruby's and you do not need to be
|
266
|
+
# defensive with load order. Just refer to classes and modules normally.
|
267
|
+
# If the constant name is dynamic, camelize if needed, and constantize.
|
268
|
+
#
|
269
|
+
# In +:classic+ mode, interprets a file using +mechanism+ and marks its
|
270
|
+
# defined constants as autoloaded. +file_name+ can be either a string or
|
267
271
|
# respond to <tt>to_path</tt>.
|
268
272
|
#
|
269
|
-
#
|
270
|
-
# defined at that point. A typical use case is to
|
271
|
-
# resolution deterministic for constants with the same
|
272
|
-
# different namespaces whose evaluation would depend on
|
273
|
-
# otherwise.
|
273
|
+
# In +:classic+ mode, use this method in code that absolutely needs a
|
274
|
+
# certain constant to be defined at that point. A typical use case is to
|
275
|
+
# make constant name resolution deterministic for constants with the same
|
276
|
+
# relative name in different namespaces whose evaluation would depend on
|
277
|
+
# load order otherwise.
|
278
|
+
#
|
279
|
+
# Engines that do not control the mode in which their parent application
|
280
|
+
# runs should call +require_dependency+ where needed in case the runtime
|
281
|
+
# mode is +:classic+.
|
274
282
|
def require_dependency(file_name, message = "No such file to load -- %s.rb")
|
275
283
|
file_name = file_name.to_path if file_name.respond_to?(:to_path)
|
276
284
|
unless file_name.is_a?(String)
|
@@ -367,12 +375,7 @@ module ActiveSupport #:nodoc:
|
|
367
375
|
require_or_load(path || file_name)
|
368
376
|
rescue LoadError => load_error
|
369
377
|
if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
|
370
|
-
|
371
|
-
load_error.original_message
|
372
|
-
else
|
373
|
-
load_error.message
|
374
|
-
end
|
375
|
-
load_error_message.replace(message % file_name)
|
378
|
+
load_error.message.replace(message % file_name)
|
376
379
|
load_error.copy_blame!(load_error)
|
377
380
|
end
|
378
381
|
raise
|
@@ -458,7 +461,7 @@ module ActiveSupport #:nodoc:
|
|
458
461
|
|
459
462
|
# Search for a file in autoload_paths matching the provided suffix.
|
460
463
|
def search_for_file(path_suffix)
|
461
|
-
path_suffix += ".rb" unless path_suffix.
|
464
|
+
path_suffix += ".rb" unless path_suffix.end_with?(".rb")
|
462
465
|
|
463
466
|
autoload_paths.each do |root|
|
464
467
|
path = File.join(root, path_suffix)
|
@@ -478,9 +481,9 @@ module ActiveSupport #:nodoc:
|
|
478
481
|
end
|
479
482
|
|
480
483
|
def load_once_path?(path)
|
481
|
-
# to_s works around a ruby issue where String#
|
484
|
+
# to_s works around a ruby issue where String#start_with?(Pathname)
|
482
485
|
# will raise a TypeError: no implicit conversion of Pathname into String
|
483
|
-
autoload_once_paths.any? { |base| path.
|
486
|
+
autoload_once_paths.any? { |base| path.start_with?(base.to_s) }
|
484
487
|
end
|
485
488
|
|
486
489
|
# Attempt to autoload the provided module name by searching for a directory
|
@@ -530,7 +533,8 @@ module ActiveSupport #:nodoc:
|
|
530
533
|
# it is not possible to load the constant into from_mod, try its parent
|
531
534
|
# module using +const_missing+.
|
532
535
|
def load_missing_constant(from_mod, const_name)
|
533
|
-
|
536
|
+
from_mod_name = real_mod_name(from_mod)
|
537
|
+
unless qualified_const_defined?(from_mod_name) && Inflector.constantize(from_mod_name).equal?(from_mod)
|
534
538
|
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
|
535
539
|
end
|
536
540
|
|
@@ -541,7 +545,7 @@ module ActiveSupport #:nodoc:
|
|
541
545
|
|
542
546
|
if file_path
|
543
547
|
expanded = File.expand_path(file_path)
|
544
|
-
expanded.
|
548
|
+
expanded.delete_suffix!(".rb")
|
545
549
|
|
546
550
|
if loading.include?(expanded)
|
547
551
|
raise "Circular dependency detected while autoloading constant #{qualified_name}"
|
@@ -589,8 +593,8 @@ module ActiveSupport #:nodoc:
|
|
589
593
|
end
|
590
594
|
end
|
591
595
|
|
592
|
-
name_error =
|
593
|
-
name_error.set_backtrace(caller.reject { |l| l.
|
596
|
+
name_error = uninitialized_constant(qualified_name, const_name, receiver: from_mod)
|
597
|
+
name_error.set_backtrace(caller.reject { |l| l.start_with? __FILE__ })
|
594
598
|
raise name_error
|
595
599
|
end
|
596
600
|
|
@@ -719,7 +723,7 @@ module ActiveSupport #:nodoc:
|
|
719
723
|
# A module, class, symbol, or string may be provided.
|
720
724
|
def to_constant_name(desc) #:nodoc:
|
721
725
|
case desc
|
722
|
-
when String then desc.
|
726
|
+
when String then desc.delete_prefix("::")
|
723
727
|
when Symbol then desc.to_s
|
724
728
|
when Module
|
725
729
|
real_mod_name(desc) ||
|
@@ -730,7 +734,7 @@ module ActiveSupport #:nodoc:
|
|
730
734
|
|
731
735
|
def remove_constant(const) #:nodoc:
|
732
736
|
# Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo.
|
733
|
-
normalized = const.to_s.
|
737
|
+
normalized = const.to_s.delete_prefix("::")
|
734
738
|
normalized.sub!(/\A(Object::)+/, "")
|
735
739
|
|
736
740
|
constants = normalized.split("::")
|
@@ -740,7 +744,7 @@ module ActiveSupport #:nodoc:
|
|
740
744
|
file_path = search_for_file(const.underscore)
|
741
745
|
if file_path
|
742
746
|
expanded = File.expand_path(file_path)
|
743
|
-
expanded.
|
747
|
+
expanded.delete_suffix!(".rb")
|
744
748
|
loaded.delete(expanded)
|
745
749
|
end
|
746
750
|
|
@@ -798,6 +802,16 @@ module ActiveSupport #:nodoc:
|
|
798
802
|
end
|
799
803
|
|
800
804
|
private
|
805
|
+
if RUBY_VERSION < "2.6"
|
806
|
+
def uninitialized_constant(qualified_name, const_name, receiver:)
|
807
|
+
NameError.new("uninitialized constant #{qualified_name}", const_name)
|
808
|
+
end
|
809
|
+
else
|
810
|
+
def uninitialized_constant(qualified_name, const_name, receiver:)
|
811
|
+
NameError.new("uninitialized constant #{qualified_name}", const_name, receiver: receiver)
|
812
|
+
end
|
813
|
+
end
|
814
|
+
|
801
815
|
# Returns the original name of a class or module even if `name` has been
|
802
816
|
# overridden.
|
803
817
|
def real_mod_name(mod)
|
@@ -51,7 +51,7 @@ module ActiveSupport
|
|
51
51
|
# constant. Available behaviors are:
|
52
52
|
#
|
53
53
|
# [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
|
54
|
-
# [+stderr+] Log all deprecation warnings to
|
54
|
+
# [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
55
55
|
# [+log+] Log all deprecation warnings to +Rails.logger+.
|
56
56
|
# [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
|
57
57
|
# [+silence+] Do nothing.
|
@@ -67,13 +67,18 @@ module ActiveSupport
|
|
67
67
|
@behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
|
68
68
|
end
|
69
69
|
|
70
|
+
# Returns the current behavior for disallowed deprecations or if one isn't set, defaults to +:raise+.
|
71
|
+
def disallowed_behavior
|
72
|
+
@disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]]
|
73
|
+
end
|
74
|
+
|
70
75
|
# Sets the behavior to the specified value. Can be a single value, array,
|
71
76
|
# or an object that responds to +call+.
|
72
77
|
#
|
73
78
|
# Available behaviors:
|
74
79
|
#
|
75
80
|
# [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
|
76
|
-
# [+stderr+] Log all deprecation warnings to
|
81
|
+
# [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
77
82
|
# [+log+] Log all deprecation warnings to +Rails.logger+.
|
78
83
|
# [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
|
79
84
|
# [+silence+] Do nothing.
|
@@ -92,6 +97,14 @@ module ActiveSupport
|
|
92
97
|
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
93
98
|
end
|
94
99
|
|
100
|
+
# Sets the behavior for disallowed deprecations (those configured by
|
101
|
+
# ActiveSupport::Deprecation.disallowed_warnings=) to the specified
|
102
|
+
# value. As with +behavior=+, this can be a single value, array, or an
|
103
|
+
# object that responds to +call+.
|
104
|
+
def disallowed_behavior=(behavior)
|
105
|
+
@disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
106
|
+
end
|
107
|
+
|
95
108
|
private
|
96
109
|
def arity_coerce(behavior)
|
97
110
|
unless behavior.respond_to?(:call)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
class Deprecation
|
5
|
+
module Disallowed
|
6
|
+
# Sets the criteria used to identify deprecation messages which should be
|
7
|
+
# disallowed. Can be an array containing strings, symbols, or regular
|
8
|
+
# expressions. (Symbols are treated as strings). These are compared against
|
9
|
+
# the text of the generated deprecation warning.
|
10
|
+
#
|
11
|
+
# Additionally the scalar symbol +:all+ may be used to treat all
|
12
|
+
# deprecations as disallowed.
|
13
|
+
#
|
14
|
+
# Deprecations matching a substring or regular expression will be handled
|
15
|
+
# using the configured +ActiveSupport::Deprecation.disallowed_behavior+
|
16
|
+
# rather than +ActiveSupport::Deprecation.behavior+
|
17
|
+
attr_writer :disallowed_warnings
|
18
|
+
|
19
|
+
# Returns the configured criteria used to identify deprecation messages
|
20
|
+
# which should be treated as disallowed.
|
21
|
+
def disallowed_warnings
|
22
|
+
@disallowed_warnings ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def deprecation_disallowed?(message)
|
27
|
+
disallowed = ActiveSupport::Deprecation.disallowed_warnings
|
28
|
+
return false if explicitly_allowed?(message)
|
29
|
+
return true if disallowed == :all
|
30
|
+
disallowed.any? do |rule|
|
31
|
+
case rule
|
32
|
+
when String, Symbol
|
33
|
+
message.include?(rule.to_s)
|
34
|
+
when Regexp
|
35
|
+
rule.match?(message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def explicitly_allowed?(message)
|
41
|
+
allowances = @explicitly_allowed_warnings.value
|
42
|
+
return false unless allowances
|
43
|
+
return true if allowances == :all
|
44
|
+
allowances = [allowances] unless allowances.kind_of?(Array)
|
45
|
+
allowances.any? do |rule|
|
46
|
+
case rule
|
47
|
+
when String, Symbol
|
48
|
+
message.include?(rule.to_s)
|
49
|
+
when Regexp
|
50
|
+
rule.match?(message)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -56,11 +56,12 @@ module ActiveSupport
|
|
56
56
|
mod = nil
|
57
57
|
|
58
58
|
method_names.each do |method_name|
|
59
|
+
message = options[method_name]
|
59
60
|
if target_module.method_defined?(method_name) || target_module.private_method_defined?(method_name)
|
60
61
|
method = target_module.instance_method(method_name)
|
61
62
|
target_module.module_eval do
|
62
63
|
redefine_method(method_name) do |*args, &block|
|
63
|
-
deprecator.deprecation_warning(method_name,
|
64
|
+
deprecator.deprecation_warning(method_name, message)
|
64
65
|
method.bind(self).call(*args, &block)
|
65
66
|
end
|
66
67
|
ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
|
@@ -69,7 +70,7 @@ module ActiveSupport
|
|
69
70
|
mod ||= Module.new
|
70
71
|
mod.module_eval do
|
71
72
|
define_method(method_name) do |*args, &block|
|
72
|
-
deprecator.deprecation_warning(method_name,
|
73
|
+
deprecator.deprecation_warning(method_name, message)
|
73
74
|
super(*args, &block)
|
74
75
|
end
|
75
76
|
ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
|
@@ -121,7 +121,7 @@ module ActiveSupport
|
|
121
121
|
# (Backtrace information…)
|
122
122
|
# ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
|
123
123
|
class DeprecatedConstantProxy < Module
|
124
|
-
def self.new(*args, **
|
124
|
+
def self.new(*args, **options, &block)
|
125
125
|
object = args.first
|
126
126
|
|
127
127
|
return object unless object
|
@@ -129,7 +129,7 @@ module ActiveSupport
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.")
|
132
|
-
require "active_support/inflector/methods"
|
132
|
+
Kernel.require "active_support/inflector/methods"
|
133
133
|
|
134
134
|
@old_const = old_const
|
135
135
|
@new_const = new_const
|
@@ -6,7 +6,7 @@ module ActiveSupport
|
|
6
6
|
class Deprecation
|
7
7
|
module Reporting
|
8
8
|
# Whether to print a message (silent mode)
|
9
|
-
|
9
|
+
attr_writer :silenced
|
10
10
|
# Name of gem where method is deprecated
|
11
11
|
attr_accessor :gem_name
|
12
12
|
|
@@ -20,7 +20,11 @@ module ActiveSupport
|
|
20
20
|
|
21
21
|
callstack ||= caller_locations(2)
|
22
22
|
deprecation_message(callstack, message).tap do |m|
|
23
|
-
|
23
|
+
if deprecation_disallowed?(message)
|
24
|
+
disallowed_behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
|
25
|
+
else
|
26
|
+
behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
@@ -33,11 +37,50 @@ module ActiveSupport
|
|
33
37
|
# ActiveSupport::Deprecation.warn('something broke!')
|
34
38
|
# end
|
35
39
|
# # => nil
|
36
|
-
def silence
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
def silence(&block)
|
41
|
+
@silenced_thread.bind(true, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Allow previously disallowed deprecation warnings within the block.
|
45
|
+
# <tt>allowed_warnings</tt> can be an array containing strings, symbols, or regular
|
46
|
+
# expressions. (Symbols are treated as strings). These are compared against
|
47
|
+
# the text of deprecation warning messages generated within the block.
|
48
|
+
# Matching warnings will be exempt from the rules set by
|
49
|
+
# +ActiveSupport::Deprecation.disallowed_warnings+
|
50
|
+
#
|
51
|
+
# The optional <tt>if:</tt> argument accepts a truthy/falsy value or an object that
|
52
|
+
# responds to <tt>.call</tt>. If truthy, then matching warnings will be allowed.
|
53
|
+
# If falsey then the method yields to the block without allowing the warning.
|
54
|
+
#
|
55
|
+
# ActiveSupport::Deprecation.disallowed_behavior = :raise
|
56
|
+
# ActiveSupport::Deprecation.disallowed_warnings = [
|
57
|
+
# "something broke"
|
58
|
+
# ]
|
59
|
+
#
|
60
|
+
# ActiveSupport::Deprecation.warn('something broke!')
|
61
|
+
# # => ActiveSupport::DeprecationException
|
62
|
+
#
|
63
|
+
# ActiveSupport::Deprecation.allow ['something broke'] do
|
64
|
+
# ActiveSupport::Deprecation.warn('something broke!')
|
65
|
+
# end
|
66
|
+
# # => nil
|
67
|
+
#
|
68
|
+
# ActiveSupport::Deprecation.allow ['something broke'], if: Rails.env.production? do
|
69
|
+
# ActiveSupport::Deprecation.warn('something broke!')
|
70
|
+
# end
|
71
|
+
# # => ActiveSupport::DeprecationException for dev/test, nil for production
|
72
|
+
def allow(allowed_warnings = :all, if: true, &block)
|
73
|
+
conditional = binding.local_variable_get(:if)
|
74
|
+
conditional = conditional.call if conditional.respond_to?(:call)
|
75
|
+
if conditional
|
76
|
+
@explicitly_allowed_warnings.bind(allowed_warnings, &block)
|
77
|
+
else
|
78
|
+
yield
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def silenced
|
83
|
+
@silenced || @silenced_thread.value
|
41
84
|
end
|
42
85
|
|
43
86
|
def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
|
@@ -17,15 +17,18 @@ module ActiveSupport
|
|
17
17
|
require "active_support/deprecation/instance_delegator"
|
18
18
|
require "active_support/deprecation/behaviors"
|
19
19
|
require "active_support/deprecation/reporting"
|
20
|
+
require "active_support/deprecation/disallowed"
|
20
21
|
require "active_support/deprecation/constant_accessor"
|
21
22
|
require "active_support/deprecation/method_wrappers"
|
22
23
|
require "active_support/deprecation/proxy_wrappers"
|
23
24
|
require "active_support/core_ext/module/deprecation"
|
25
|
+
require "concurrent/atomic/thread_local_var"
|
24
26
|
|
25
27
|
include Singleton
|
26
28
|
include InstanceDelegator
|
27
29
|
include Behavior
|
28
30
|
include Reporting
|
31
|
+
include Disallowed
|
29
32
|
include MethodWrapper
|
30
33
|
|
31
34
|
# The version number in which the deprecated behavior will be removed, by default.
|
@@ -35,12 +38,14 @@ module ActiveSupport
|
|
35
38
|
# and the second is a library name.
|
36
39
|
#
|
37
40
|
# ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
|
38
|
-
def initialize(deprecation_horizon = "6.
|
41
|
+
def initialize(deprecation_horizon = "6.2", gem_name = "Rails")
|
39
42
|
self.gem_name = gem_name
|
40
43
|
self.deprecation_horizon = deprecation_horizon
|
41
44
|
# By default, warnings are not silenced and debugging is off.
|
42
45
|
self.silenced = false
|
43
46
|
self.debug = false
|
47
|
+
@silenced_thread = Concurrent::ThreadLocalVar.new(false)
|
48
|
+
@explicitly_allowed_warnings = Concurrent::ThreadLocalVar.new(nil)
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|