activesupport 6.0.4 → 6.1.4
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 +388 -460
- data/MIT-LICENSE +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 +3 -3
- data/lib/active_support/cache/mem_cache_store.rb +28 -18
- data/lib/active_support/cache/memory_store.rb +46 -26
- data/lib/active_support/cache/redis_cache_store.rb +25 -25
- data/lib/active_support/cache/strategy/local_cache.rb +20 -5
- data/lib/active_support/cache.rb +87 -40
- 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 +51 -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 +12 -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/regexp.rb +8 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- 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 +3 -4
- 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 +17 -0
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +5 -1
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +8 -2
- data/lib/active_support/dependencies.rb +37 -18
- 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/fork_tracker.rb +64 -0
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +48 -24
- 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 +32 -5
- 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 +9 -5
- 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 +16 -11
- 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/rescuable.rb +4 -4
- 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 +67 -43
- 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 +33 -35
- 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
@@ -47,9 +47,9 @@ class String
|
|
47
47
|
# iso_str.is_utf8? # => false
|
48
48
|
def is_utf8?
|
49
49
|
case encoding
|
50
|
-
when Encoding::UTF_8
|
50
|
+
when Encoding::UTF_8, Encoding::US_ASCII
|
51
51
|
valid_encoding?
|
52
|
-
when Encoding::ASCII_8BIT
|
52
|
+
when Encoding::ASCII_8BIT
|
53
53
|
dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
54
54
|
else
|
55
55
|
false
|
@@ -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
|
|
@@ -85,7 +84,7 @@ class ERB
|
|
85
84
|
# use inside HTML attributes.
|
86
85
|
#
|
87
86
|
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
88
|
-
# whether or not it is being inserted via
|
87
|
+
# whether or not it is being inserted via <tt>html()</tt>. Most jQuery plugins do this.
|
89
88
|
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
90
89
|
# content returned by your JSON.
|
91
90
|
#
|
@@ -202,7 +201,7 @@ module ActiveSupport #:nodoc:
|
|
202
201
|
end
|
203
202
|
|
204
203
|
def []=(*args)
|
205
|
-
if args.
|
204
|
+
if args.length == 3
|
206
205
|
super(args[0], args[1], html_escape_interpolated_argument(args[2]))
|
207
206
|
else
|
208
207
|
super(args[0], html_escape_interpolated_argument(args[1]))
|
@@ -223,7 +222,7 @@ module ActiveSupport #:nodoc:
|
|
223
222
|
def %(args)
|
224
223
|
case args
|
225
224
|
when Hash
|
226
|
-
escaped_args =
|
225
|
+
escaped_args = args.transform_values { |arg| html_escape_interpolated_argument(arg) }
|
227
226
|
else
|
228
227
|
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
229
228
|
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
|
@@ -55,6 +56,7 @@ class Time
|
|
55
56
|
at_without_coercion(time_or_number)
|
56
57
|
end
|
57
58
|
end
|
59
|
+
ruby2_keywords(:at_with_coercion) if respond_to?(:ruby2_keywords, true)
|
58
60
|
alias_method :at_without_coercion, :at
|
59
61
|
alias_method :at, :at_with_coercion
|
60
62
|
|
@@ -107,6 +109,21 @@ class Time
|
|
107
109
|
subsec
|
108
110
|
end
|
109
111
|
|
112
|
+
unless Time.method_defined?(:floor)
|
113
|
+
def floor(precision = 0)
|
114
|
+
change(nsec: 0) + subsec.floor(precision)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Restricted Ruby version due to a bug in `Time#ceil`
|
119
|
+
# See https://bugs.ruby-lang.org/issues/17025 for more details
|
120
|
+
if RUBY_VERSION <= "2.8"
|
121
|
+
remove_possible_method :ceil
|
122
|
+
def ceil(precision = 0)
|
123
|
+
change(nsec: 0) + subsec.ceil(precision)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
110
127
|
# Returns a new Time where one or more of the elements have been changed according
|
111
128
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
112
129
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "time"
|
3
4
|
require "active_support/inflector/methods"
|
4
5
|
require "active_support/values/time_zone"
|
5
6
|
|
6
7
|
class Time
|
7
8
|
DATE_FORMATS = {
|
8
9
|
db: "%Y-%m-%d %H:%M:%S",
|
10
|
+
inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
|
9
11
|
number: "%Y%m%d%H%M%S",
|
10
12
|
nsec: "%Y%m%d%H%M%S%9N",
|
11
13
|
usec: "%Y%m%d%H%M%S%6N",
|
@@ -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 after_teardown
|
10
|
+
super
|
11
|
+
ActiveSupport::CurrentAttributes.reset_all
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/callbacks"
|
4
|
+
require "active_support/core_ext/enumerable"
|
5
|
+
require "active_support/core_ext/module/delegation"
|
4
6
|
|
5
7
|
module ActiveSupport
|
6
8
|
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
|
@@ -91,7 +93,7 @@ module ActiveSupport
|
|
91
93
|
class << self
|
92
94
|
# Returns singleton instance for this class in this thread. If none exists, one is created.
|
93
95
|
def instance
|
94
|
-
current_instances[
|
96
|
+
current_instances[current_instances_key] ||= new
|
95
97
|
end
|
96
98
|
|
97
99
|
# Declares one or more attributes that will be given both class and instance accessor methods.
|
@@ -150,6 +152,10 @@ module ActiveSupport
|
|
150
152
|
Thread.current[:current_attributes_instances] ||= {}
|
151
153
|
end
|
152
154
|
|
155
|
+
def current_instances_key
|
156
|
+
@current_instances_key ||= name.to_sym
|
157
|
+
end
|
158
|
+
|
153
159
|
def method_missing(name, *args, &block)
|
154
160
|
# Caches the method definition as a singleton method of the receiver.
|
155
161
|
#
|
@@ -197,7 +203,7 @@ module ActiveSupport
|
|
197
203
|
end
|
198
204
|
|
199
205
|
def compute_attributes(keys)
|
200
|
-
keys.
|
206
|
+
keys.index_with { |key| public_send(key) }
|
201
207
|
end
|
202
208
|
end
|
203
209
|
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)
|
@@ -458,7 +466,7 @@ module ActiveSupport #:nodoc:
|
|
458
466
|
|
459
467
|
# Search for a file in autoload_paths matching the provided suffix.
|
460
468
|
def search_for_file(path_suffix)
|
461
|
-
path_suffix += ".rb" unless path_suffix.
|
469
|
+
path_suffix += ".rb" unless path_suffix.end_with?(".rb")
|
462
470
|
|
463
471
|
autoload_paths.each do |root|
|
464
472
|
path = File.join(root, path_suffix)
|
@@ -478,9 +486,9 @@ module ActiveSupport #:nodoc:
|
|
478
486
|
end
|
479
487
|
|
480
488
|
def load_once_path?(path)
|
481
|
-
# to_s works around a ruby issue where String#
|
489
|
+
# to_s works around a ruby issue where String#start_with?(Pathname)
|
482
490
|
# will raise a TypeError: no implicit conversion of Pathname into String
|
483
|
-
autoload_once_paths.any? { |base| path.
|
491
|
+
autoload_once_paths.any? { |base| path.start_with?(base.to_s) }
|
484
492
|
end
|
485
493
|
|
486
494
|
# Attempt to autoload the provided module name by searching for a directory
|
@@ -530,7 +538,8 @@ module ActiveSupport #:nodoc:
|
|
530
538
|
# it is not possible to load the constant into from_mod, try its parent
|
531
539
|
# module using +const_missing+.
|
532
540
|
def load_missing_constant(from_mod, const_name)
|
533
|
-
|
541
|
+
from_mod_name = real_mod_name(from_mod)
|
542
|
+
unless qualified_const_defined?(from_mod_name) && Inflector.constantize(from_mod_name).equal?(from_mod)
|
534
543
|
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
|
535
544
|
end
|
536
545
|
|
@@ -541,7 +550,7 @@ module ActiveSupport #:nodoc:
|
|
541
550
|
|
542
551
|
if file_path
|
543
552
|
expanded = File.expand_path(file_path)
|
544
|
-
expanded.
|
553
|
+
expanded.delete_suffix!(".rb")
|
545
554
|
|
546
555
|
if loading.include?(expanded)
|
547
556
|
raise "Circular dependency detected while autoloading constant #{qualified_name}"
|
@@ -589,8 +598,8 @@ module ActiveSupport #:nodoc:
|
|
589
598
|
end
|
590
599
|
end
|
591
600
|
|
592
|
-
name_error =
|
593
|
-
name_error.set_backtrace(caller.reject { |l| l.
|
601
|
+
name_error = uninitialized_constant(qualified_name, const_name, receiver: from_mod)
|
602
|
+
name_error.set_backtrace(caller.reject { |l| l.start_with? __FILE__ })
|
594
603
|
raise name_error
|
595
604
|
end
|
596
605
|
|
@@ -719,7 +728,7 @@ module ActiveSupport #:nodoc:
|
|
719
728
|
# A module, class, symbol, or string may be provided.
|
720
729
|
def to_constant_name(desc) #:nodoc:
|
721
730
|
case desc
|
722
|
-
when String then desc.
|
731
|
+
when String then desc.delete_prefix("::")
|
723
732
|
when Symbol then desc.to_s
|
724
733
|
when Module
|
725
734
|
real_mod_name(desc) ||
|
@@ -730,7 +739,7 @@ module ActiveSupport #:nodoc:
|
|
730
739
|
|
731
740
|
def remove_constant(const) #:nodoc:
|
732
741
|
# Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo.
|
733
|
-
normalized = const.to_s.
|
742
|
+
normalized = const.to_s.delete_prefix("::")
|
734
743
|
normalized.sub!(/\A(Object::)+/, "")
|
735
744
|
|
736
745
|
constants = normalized.split("::")
|
@@ -740,7 +749,7 @@ module ActiveSupport #:nodoc:
|
|
740
749
|
file_path = search_for_file(const.underscore)
|
741
750
|
if file_path
|
742
751
|
expanded = File.expand_path(file_path)
|
743
|
-
expanded.
|
752
|
+
expanded.delete_suffix!(".rb")
|
744
753
|
loaded.delete(expanded)
|
745
754
|
end
|
746
755
|
|
@@ -798,6 +807,16 @@ module ActiveSupport #:nodoc:
|
|
798
807
|
end
|
799
808
|
|
800
809
|
private
|
810
|
+
if RUBY_VERSION < "2.6"
|
811
|
+
def uninitialized_constant(qualified_name, const_name, receiver:)
|
812
|
+
NameError.new("uninitialized constant #{qualified_name}", const_name)
|
813
|
+
end
|
814
|
+
else
|
815
|
+
def uninitialized_constant(qualified_name, const_name, receiver:)
|
816
|
+
NameError.new("uninitialized constant #{qualified_name}", const_name, receiver: receiver)
|
817
|
+
end
|
818
|
+
end
|
819
|
+
|
801
820
|
# Returns the original name of a class or module even if `name` has been
|
802
821
|
# overridden.
|
803
822
|
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
|
@@ -13,6 +13,7 @@ module ActiveSupport
|
|
13
13
|
descendants = @@direct_descendants[klass]
|
14
14
|
descendants ? descendants.to_a : []
|
15
15
|
end
|
16
|
+
alias_method :subclasses, :direct_descendants
|
16
17
|
|
17
18
|
def descendants(klass)
|
18
19
|
arr = []
|
@@ -59,6 +60,7 @@ module ActiveSupport
|
|
59
60
|
def direct_descendants
|
60
61
|
DescendantsTracker.direct_descendants(self)
|
61
62
|
end
|
63
|
+
alias_method :subclasses, :direct_descendants
|
62
64
|
|
63
65
|
def descendants
|
64
66
|
DescendantsTracker.descendants(self)
|
@@ -77,15 +79,17 @@ module ActiveSupport
|
|
77
79
|
end
|
78
80
|
|
79
81
|
def <<(klass)
|
80
|
-
cleanup!
|
81
82
|
@refs << WeakRef.new(klass)
|
82
83
|
end
|
83
84
|
|
84
85
|
def each
|
85
|
-
@refs.
|
86
|
+
@refs.reject! do |ref|
|
86
87
|
yield ref.__getobj__
|
88
|
+
false
|
87
89
|
rescue WeakRef::RefError
|
90
|
+
true
|
88
91
|
end
|
92
|
+
self
|
89
93
|
end
|
90
94
|
|
91
95
|
def refs_size
|