activesupport 5.2.0 → 6.0.3.2

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.

Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +479 -330
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/active_support.rb +2 -1
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +27 -1
  8. data/lib/active_support/cache.rb +104 -84
  9. data/lib/active_support/cache/file_store.rb +29 -30
  10. data/lib/active_support/cache/mem_cache_store.rb +14 -19
  11. data/lib/active_support/cache/memory_store.rb +15 -9
  12. data/lib/active_support/cache/null_store.rb +8 -3
  13. data/lib/active_support/cache/redis_cache_store.rb +73 -34
  14. data/lib/active_support/cache/strategy/local_cache.rb +23 -23
  15. data/lib/active_support/callbacks.rb +16 -8
  16. data/lib/active_support/concern.rb +31 -4
  17. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  18. data/lib/active_support/concurrency/share_lock.rb +0 -1
  19. data/lib/active_support/configurable.rb +7 -11
  20. data/lib/active_support/core_ext/array.rb +1 -1
  21. data/lib/active_support/core_ext/array/access.rb +18 -6
  22. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  23. data/lib/active_support/core_ext/array/extract.rb +21 -0
  24. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
  25. data/lib/active_support/core_ext/class/attribute.rb +11 -16
  26. data/lib/active_support/core_ext/class/subclasses.rb +1 -1
  27. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  28. data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
  29. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  30. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  31. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  32. data/lib/active_support/core_ext/digest.rb +3 -0
  33. data/lib/active_support/core_ext/enumerable.rb +97 -68
  34. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  35. data/lib/active_support/core_ext/hash.rb +1 -2
  36. data/lib/active_support/core_ext/hash/compact.rb +2 -26
  37. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  38. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  39. data/lib/active_support/core_ext/hash/except.rb +1 -1
  40. data/lib/active_support/core_ext/hash/keys.rb +0 -29
  41. data/lib/active_support/core_ext/hash/slice.rb +3 -25
  42. data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
  43. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  44. data/lib/active_support/core_ext/kernel.rb +0 -1
  45. data/lib/active_support/core_ext/load_error.rb +1 -1
  46. data/lib/active_support/core_ext/module.rb +0 -1
  47. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
  48. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
  49. data/lib/active_support/core_ext/module/delegation.rb +41 -8
  50. data/lib/active_support/core_ext/module/introspection.rb +38 -13
  51. data/lib/active_support/core_ext/module/reachable.rb +1 -6
  52. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  53. data/lib/active_support/core_ext/numeric.rb +0 -1
  54. data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
  55. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
  56. data/lib/active_support/core_ext/object/blank.rb +1 -2
  57. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  58. data/lib/active_support/core_ext/object/json.rb +1 -0
  59. data/lib/active_support/core_ext/object/to_query.rb +5 -2
  60. data/lib/active_support/core_ext/object/try.rb +17 -7
  61. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  62. data/lib/active_support/core_ext/range.rb +1 -1
  63. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  64. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  65. data/lib/active_support/core_ext/range/each.rb +0 -1
  66. data/lib/active_support/core_ext/range/include_range.rb +6 -22
  67. data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
  68. data/lib/active_support/core_ext/regexp.rb +0 -4
  69. data/lib/active_support/core_ext/securerandom.rb +23 -3
  70. data/lib/active_support/core_ext/string/access.rb +8 -0
  71. data/lib/active_support/core_ext/string/filters.rb +42 -1
  72. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  73. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  74. data/lib/active_support/core_ext/string/output_safety.rb +63 -6
  75. data/lib/active_support/core_ext/string/strip.rb +3 -1
  76. data/lib/active_support/core_ext/time/calculations.rb +31 -2
  77. data/lib/active_support/core_ext/uri.rb +2 -4
  78. data/lib/active_support/current_attributes.rb +8 -0
  79. data/lib/active_support/dependencies.rb +77 -18
  80. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  81. data/lib/active_support/deprecation.rb +1 -1
  82. data/lib/active_support/deprecation/behaviors.rb +5 -1
  83. data/lib/active_support/deprecation/method_wrappers.rb +20 -13
  84. data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
  85. data/lib/active_support/deprecation/reporting.rb +1 -1
  86. data/lib/active_support/descendants_tracker.rb +55 -9
  87. data/lib/active_support/duration.rb +19 -16
  88. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  89. data/lib/active_support/duration/iso8601_serializer.rb +3 -5
  90. data/lib/active_support/encrypted_configuration.rb +1 -5
  91. data/lib/active_support/encrypted_file.rb +4 -3
  92. data/lib/active_support/evented_file_update_checker.rb +39 -10
  93. data/lib/active_support/execution_wrapper.rb +1 -0
  94. data/lib/active_support/file_update_checker.rb +0 -1
  95. data/lib/active_support/gem_version.rb +4 -4
  96. data/lib/active_support/hash_with_indifferent_access.rb +36 -18
  97. data/lib/active_support/i18n.rb +1 -0
  98. data/lib/active_support/i18n_railtie.rb +18 -2
  99. data/lib/active_support/inflector/inflections.rb +1 -5
  100. data/lib/active_support/inflector/methods.rb +18 -29
  101. data/lib/active_support/inflector/transliterate.rb +47 -18
  102. data/lib/active_support/json/decoding.rb +23 -24
  103. data/lib/active_support/json/encoding.rb +6 -2
  104. data/lib/active_support/key_generator.rb +0 -32
  105. data/lib/active_support/lazy_load_hooks.rb +5 -2
  106. data/lib/active_support/locale/en.rb +33 -0
  107. data/lib/active_support/log_subscriber.rb +31 -9
  108. data/lib/active_support/logger.rb +1 -16
  109. data/lib/active_support/logger_silence.rb +28 -12
  110. data/lib/active_support/logger_thread_safe_level.rb +28 -5
  111. data/lib/active_support/message_encryptor.rb +4 -6
  112. data/lib/active_support/message_verifier.rb +5 -5
  113. data/lib/active_support/messages/metadata.rb +3 -2
  114. data/lib/active_support/messages/rotator.rb +4 -4
  115. data/lib/active_support/multibyte/chars.rb +29 -49
  116. data/lib/active_support/multibyte/unicode.rb +44 -282
  117. data/lib/active_support/notifications.rb +41 -4
  118. data/lib/active_support/notifications/fanout.rb +100 -15
  119. data/lib/active_support/notifications/instrumenter.rb +80 -9
  120. data/lib/active_support/number_helper.rb +11 -0
  121. data/lib/active_support/number_helper/number_converter.rb +4 -5
  122. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -10
  123. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  124. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
  125. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
  126. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  127. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  128. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -4
  129. data/lib/active_support/option_merger.rb +21 -3
  130. data/lib/active_support/ordered_hash.rb +1 -1
  131. data/lib/active_support/ordered_options.rb +5 -1
  132. data/lib/active_support/parameter_filter.rb +128 -0
  133. data/lib/active_support/rails.rb +0 -6
  134. data/lib/active_support/reloader.rb +4 -5
  135. data/lib/active_support/security_utils.rb +1 -1
  136. data/lib/active_support/string_inquirer.rb +0 -1
  137. data/lib/active_support/subscriber.rb +65 -22
  138. data/lib/active_support/tagged_logging.rb +13 -4
  139. data/lib/active_support/test_case.rb +92 -1
  140. data/lib/active_support/testing/assertions.rb +15 -1
  141. data/lib/active_support/testing/deprecation.rb +0 -1
  142. data/lib/active_support/testing/file_fixtures.rb +2 -0
  143. data/lib/active_support/testing/isolation.rb +2 -2
  144. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  145. data/lib/active_support/testing/parallelization.rb +134 -0
  146. data/lib/active_support/testing/setup_and_teardown.rb +5 -9
  147. data/lib/active_support/testing/stream.rb +1 -2
  148. data/lib/active_support/testing/time_helpers.rb +7 -9
  149. data/lib/active_support/time_with_zone.rb +15 -5
  150. data/lib/active_support/values/time_zone.rb +14 -8
  151. data/lib/active_support/xml_mini.rb +2 -10
  152. data/lib/active_support/xml_mini/jdom.rb +2 -3
  153. data/lib/active_support/xml_mini/libxml.rb +2 -2
  154. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  155. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  156. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  157. data/lib/active_support/xml_mini/rexml.rb +2 -2
  158. metadata +42 -13
  159. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  160. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -51,20 +51,45 @@ module ActiveSupport
51
51
  #
52
52
  # Now you can have different transliterations for each locale:
53
53
  #
54
- # I18n.locale = :en
55
- # transliterate('Jürgen')
54
+ # transliterate('Jürgen', locale: :en)
56
55
  # # => "Jurgen"
57
56
  #
58
- # I18n.locale = :de
59
- # transliterate('Jürgen')
57
+ # transliterate('Jürgen', locale: :de)
60
58
  # # => "Juergen"
61
- def transliterate(string, replacement = "?".freeze)
59
+ #
60
+ # Transliteration is restricted to UTF-8, US-ASCII and GB18030 strings
61
+ # Other encodings will raise an ArgumentError.
62
+ def transliterate(string, replacement = "?", locale: nil)
63
+ string = string.dup if string.frozen?
62
64
  raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
63
65
 
64
- I18n.transliterate(
65
- ActiveSupport::Multibyte::Unicode.normalize(
66
- ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
67
- replacement: replacement)
66
+ allowed_encodings = [Encoding::UTF_8, Encoding::US_ASCII, Encoding::GB18030]
67
+ raise ArgumentError, "Can not transliterate strings with #{string.encoding} encoding" unless allowed_encodings.include?(string.encoding)
68
+
69
+ input_encoding = string.encoding
70
+
71
+ # US-ASCII is a subset of UTF-8 so we'll force encoding as UTF-8 if
72
+ # US-ASCII is given. This way we can let tidy_bytes handle the string
73
+ # in the same way as we do for UTF-8
74
+ string.force_encoding(Encoding::UTF_8) if string.encoding == Encoding::US_ASCII
75
+
76
+ # GB18030 is Unicode compatible but is not a direct mapping so needs to be
77
+ # transcoded. Using invalid/undef :replace will result in loss of data in
78
+ # the event of invalid characters, but since tidy_bytes will replace
79
+ # invalid/undef with a "?" we're safe to do the same beforehand
80
+ string.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) if string.encoding == Encoding::GB18030
81
+
82
+ transliterated = I18n.transliterate(
83
+ ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc),
84
+ replacement: replacement,
85
+ locale: locale
86
+ )
87
+
88
+ # Restore the string encoding of the input if it was not UTF-8.
89
+ # Apply invalid/undef :replace as tidy_bytes does
90
+ transliterated.encode!(input_encoding, invalid: :replace, undef: :replace) if input_encoding != transliterated.encoding
91
+
92
+ transliterated
68
93
  end
69
94
 
70
95
  # Replaces special characters in a string so that it may be used as part of
@@ -75,8 +100,8 @@ module ActiveSupport
75
100
  #
76
101
  # To use a custom separator, override the +separator+ argument.
77
102
  #
78
- # parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
79
- # parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
103
+ # parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
104
+ # parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
80
105
  #
81
106
  # To preserve the case of the characters in a string, use the +preserve_case+ argument.
82
107
  #
@@ -85,19 +110,23 @@ module ActiveSupport
85
110
  #
86
111
  # It preserves dashes and underscores unless they are used as separators:
87
112
  #
88
- # parameterize("^très|Jolie__ ") # => "tres-jolie__"
89
- # parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
90
- # parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
113
+ # parameterize("^très|Jolie__ ") # => "tres-jolie__"
114
+ # parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
115
+ # parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
91
116
  #
92
- def parameterize(string, separator: "-", preserve_case: false)
117
+ # If the optional parameter +locale+ is specified,
118
+ # the word will be parameterized as a word of that language.
119
+ # By default, this parameter is set to <tt>nil</tt> and it will use
120
+ # the configured <tt>I18n.locale<tt>.
121
+ def parameterize(string, separator: "-", preserve_case: false, locale: nil)
93
122
  # Replace accented chars with their ASCII equivalents.
94
- parameterized_string = transliterate(string)
123
+ parameterized_string = transliterate(string, locale: locale)
95
124
 
96
125
  # Turn unwanted chars into the separator.
97
126
  parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
98
127
 
99
128
  unless separator.nil? || separator.empty?
100
- if separator == "-".freeze
129
+ if separator == "-"
101
130
  re_duplicate_separator = /-{2,}/
102
131
  re_leading_trailing_separator = /^-|-$/i
103
132
  else
@@ -108,7 +137,7 @@ module ActiveSupport
108
137
  # No more than one of the separator in a row.
109
138
  parameterized_string.gsub!(re_duplicate_separator, separator)
110
139
  # Remove leading/trailing separator.
111
- parameterized_string.gsub!(re_leading_trailing_separator, "".freeze)
140
+ parameterized_string.gsub!(re_leading_trailing_separator, "")
112
141
  end
113
142
 
114
143
  parameterized_string.downcase! unless preserve_case
@@ -44,33 +44,32 @@ module ActiveSupport
44
44
  end
45
45
 
46
46
  private
47
-
48
- def convert_dates_from(data)
49
- case data
50
- when nil
51
- nil
52
- when DATE_REGEX
53
- begin
54
- Date.parse(data)
55
- rescue ArgumentError
56
- data
57
- end
58
- when DATETIME_REGEX
59
- begin
60
- Time.zone.parse(data)
61
- rescue ArgumentError
47
+ def convert_dates_from(data)
48
+ case data
49
+ when nil
50
+ nil
51
+ when DATE_REGEX
52
+ begin
53
+ Date.parse(data)
54
+ rescue ArgumentError
55
+ data
56
+ end
57
+ when DATETIME_REGEX
58
+ begin
59
+ Time.zone.parse(data)
60
+ rescue ArgumentError
61
+ data
62
+ end
63
+ when Array
64
+ data.map! { |d| convert_dates_from(d) }
65
+ when Hash
66
+ data.each do |key, value|
67
+ data[key] = convert_dates_from(value)
68
+ end
69
+ else
62
70
  data
63
71
  end
64
- when Array
65
- data.map! { |d| convert_dates_from(d) }
66
- when Hash
67
- data.each do |key, value|
68
- data[key] = convert_dates_from(value)
69
- end
70
- else
71
- data
72
72
  end
73
- end
74
73
  end
75
74
  end
76
75
  end
@@ -54,9 +54,13 @@ module ActiveSupport
54
54
  class EscapedString < String #:nodoc:
55
55
  def to_json(*)
56
56
  if Encoding.escape_html_entities_in_json
57
- super.gsub ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS
57
+ s = super
58
+ s.gsub! ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS
59
+ s
58
60
  else
59
- super.gsub ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS
61
+ s = super
62
+ s.gsub! ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS
63
+ s
60
64
  end
61
65
  end
62
66
 
@@ -38,36 +38,4 @@ module ActiveSupport
38
38
  @cache_keys[args.join] ||= @key_generator.generate_key(*args)
39
39
  end
40
40
  end
41
-
42
- class LegacyKeyGenerator # :nodoc:
43
- SECRET_MIN_LENGTH = 30 # Characters
44
-
45
- def initialize(secret)
46
- ensure_secret_secure(secret)
47
- @secret = secret
48
- end
49
-
50
- def generate_key(salt)
51
- @secret
52
- end
53
-
54
- private
55
-
56
- # To prevent users from using something insecure like "Password" we make sure that the
57
- # secret they've provided is at least 30 characters in length.
58
- def ensure_secret_secure(secret)
59
- if secret.blank?
60
- raise ArgumentError, "A secret is required to generate an integrity hash " \
61
- "for cookie session data. Set a secret_key_base of at least " \
62
- "#{SECRET_MIN_LENGTH} characters in via `bin/rails credentials:edit`."
63
- end
64
-
65
- if secret.length < SECRET_MIN_LENGTH
66
- raise ArgumentError, "Secret should be something secure, " \
67
- "like \"#{SecureRandom.hex(16)}\". The value you " \
68
- "provided, \"#{secret}\", is shorter than the minimum length " \
69
- "of #{SECRET_MIN_LENGTH} characters."
70
- end
71
- end
72
- end
73
41
  end
@@ -54,7 +54,6 @@ module ActiveSupport
54
54
  end
55
55
 
56
56
  private
57
-
58
57
  def with_execution_control(name, block, once)
59
58
  unless @run_once[name].include?(block)
60
59
  @run_once[name] << block if once
@@ -68,7 +67,11 @@ module ActiveSupport
68
67
  if options[:yield]
69
68
  block.call(base)
70
69
  else
71
- base.instance_eval(&block)
70
+ if base.is_a?(Module)
71
+ base.class_eval(&block)
72
+ else
73
+ base.instance_eval(&block)
74
+ end
72
75
  end
73
76
  end
74
77
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ {
4
+ en: {
5
+ number: {
6
+ nth: {
7
+ ordinals: lambda do |_key, options|
8
+ number = options[:number]
9
+ case number
10
+ when 1; "st"
11
+ when 2; "nd"
12
+ when 3; "rd"
13
+ when 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; "th"
14
+ else
15
+ num_modulo = number.to_i.abs % 100
16
+ num_modulo %= 10 if num_modulo > 13
17
+ case num_modulo
18
+ when 1; "st"
19
+ when 2; "nd"
20
+ when 3; "rd"
21
+ else "th"
22
+ end
23
+ end
24
+ end,
25
+
26
+ ordinalized: lambda do |_key, options|
27
+ number = options[:number]
28
+ "#{number}#{ActiveSupport::Inflector.ordinal(number)}"
29
+ end
30
+ }
31
+ }
32
+ }
33
+ }
@@ -5,8 +5,8 @@ require "active_support/core_ext/class/attribute"
5
5
  require "active_support/subscriber"
6
6
 
7
7
  module ActiveSupport
8
- # ActiveSupport::LogSubscriber is an object set to consume
9
- # ActiveSupport::Notifications with the sole purpose of logging them.
8
+ # <tt>ActiveSupport::LogSubscriber</tt> is an object set to consume
9
+ # <tt>ActiveSupport::Notifications</tt> with the sole purpose of logging them.
10
10
  # The log subscriber dispatches notifications to a registered object based
11
11
  # on its given namespace.
12
12
  #
@@ -16,7 +16,7 @@ module ActiveSupport
16
16
  # module ActiveRecord
17
17
  # class LogSubscriber < ActiveSupport::LogSubscriber
18
18
  # def sql(event)
19
- # "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
19
+ # info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
20
20
  # end
21
21
  # end
22
22
  # end
@@ -29,13 +29,36 @@ module ActiveSupport
29
29
  # subscriber, the line above should be called after your
30
30
  # <tt>ActiveRecord::LogSubscriber</tt> definition.
31
31
  #
32
- # After configured, whenever a "sql.active_record" notification is published,
33
- # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
34
- # the sql method.
32
+ # After configured, whenever a <tt>"sql.active_record"</tt> notification is published,
33
+ # it will properly dispatch the event
34
+ # (<tt>ActiveSupport::Notifications::Event</tt>) to the sql method.
35
+ #
36
+ # Being an <tt>ActiveSupport::Notifications</tt> consumer,
37
+ # <tt>ActiveSupport::LogSubscriber</tt> exposes a simple interface to check if
38
+ # instrumented code raises an exception. It is common to log a different
39
+ # message in case of an error, and this can be achieved by extending
40
+ # the previous example:
41
+ #
42
+ # module ActiveRecord
43
+ # class LogSubscriber < ActiveSupport::LogSubscriber
44
+ # def sql(event)
45
+ # exception = event.payload[:exception]
46
+ #
47
+ # if exception
48
+ # exception_object = event.payload[:exception_object]
49
+ #
50
+ # error "[ERROR] #{event.payload[:name]}: #{exception.join(', ')} " \
51
+ # "(#{exception_object.backtrace.first})"
52
+ # else
53
+ # # standard logger code
54
+ # end
55
+ # end
56
+ # end
57
+ # end
35
58
  #
36
59
  # Log subscriber also has some helpers to deal with logging and automatically
37
- # flushes all logs when the request finishes (via action_dispatch.callback
38
- # notification) in a Rails environment.
60
+ # flushes all logs when the request finishes
61
+ # (via <tt>action_dispatch.callback</tt> notification) in a Rails environment.
39
62
  class LogSubscriber < Subscriber
40
63
  # Embed in a String to clear all previous ANSI sequences.
41
64
  CLEAR = "\e[0m"
@@ -89,7 +112,6 @@ module ActiveSupport
89
112
  end
90
113
 
91
114
  private
92
-
93
115
  %w(info debug warn error fatal unknown).each do |level|
94
116
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
95
117
  def #{level}(progname = nil, &block)
@@ -6,7 +6,6 @@ require "logger"
6
6
 
7
7
  module ActiveSupport
8
8
  class Logger < ::Logger
9
- include ActiveSupport::LoggerThreadSafeLevel
10
9
  include LoggerSilence
11
10
 
12
11
  # Returns true if the logger destination matches one of the sources
@@ -78,23 +77,9 @@ module ActiveSupport
78
77
  end
79
78
  end
80
79
 
81
- def initialize(*args)
80
+ def initialize(*args, **kwargs)
82
81
  super
83
82
  @formatter = SimpleFormatter.new
84
- after_initialize if respond_to? :after_initialize
85
- end
86
-
87
- def add(severity, message = nil, progname = nil, &block)
88
- return true if @logdev.nil? || (severity || UNKNOWN) < level
89
- super
90
- end
91
-
92
- Logger::Severity.constants.each do |severity|
93
- class_eval(<<-EOT, __FILE__, __LINE__ + 1)
94
- def #{severity.downcase}? # def debug?
95
- Logger::#{severity} >= level # DEBUG >= level
96
- end # end
97
- EOT
98
83
  end
99
84
 
100
85
  # Simple formatter which only displays the message.
@@ -2,28 +2,44 @@
2
2
 
3
3
  require "active_support/concern"
4
4
  require "active_support/core_ext/module/attribute_accessors"
5
- require "concurrent"
5
+ require "active_support/logger_thread_safe_level"
6
6
 
7
7
  module LoggerSilence
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
- cattr_accessor :silencer, default: true
11
+ ActiveSupport::Deprecation.warn(
12
+ "Including LoggerSilence is deprecated and will be removed in Rails 6.1. " \
13
+ "Please use `ActiveSupport::LoggerSilence` instead"
14
+ )
15
+
16
+ include ActiveSupport::LoggerSilence
12
17
  end
18
+ end
19
+
20
+ module ActiveSupport
21
+ module LoggerSilence
22
+ extend ActiveSupport::Concern
23
+
24
+ included do
25
+ cattr_accessor :silencer, default: true
26
+ include ActiveSupport::LoggerThreadSafeLevel
27
+ end
13
28
 
14
- # Silences the logger for the duration of the block.
15
- def silence(temporary_level = Logger::ERROR)
16
- if silencer
17
- begin
18
- old_local_level = local_level
19
- self.local_level = temporary_level
29
+ # Silences the logger for the duration of the block.
30
+ def silence(temporary_level = Logger::ERROR)
31
+ if silencer
32
+ begin
33
+ old_local_level = local_level
34
+ self.local_level = temporary_level
20
35
 
36
+ yield self
37
+ ensure
38
+ self.local_level = old_local_level
39
+ end
40
+ else
21
41
  yield self
22
- ensure
23
- self.local_level = old_local_level
24
42
  end
25
- else
26
- yield self
27
43
  end
28
44
  end
29
45
  end
@@ -1,33 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/concern"
4
+ require "active_support/core_ext/module/attribute_accessors"
5
+ require "concurrent"
6
+ require "fiber"
4
7
 
5
8
  module ActiveSupport
6
9
  module LoggerThreadSafeLevel # :nodoc:
7
10
  extend ActiveSupport::Concern
8
11
 
12
+ included do
13
+ cattr_accessor :local_levels, default: Concurrent::Map.new(initial_capacity: 2), instance_accessor: false
14
+ end
15
+
16
+ Logger::Severity.constants.each do |severity|
17
+ class_eval(<<-EOT, __FILE__, __LINE__ + 1)
18
+ def #{severity.downcase}? # def debug?
19
+ Logger::#{severity} >= level # DEBUG >= level
20
+ end # end
21
+ EOT
22
+ end
23
+
9
24
  def after_initialize
10
- @local_levels = Concurrent::Map.new(initial_capacity: 2)
25
+ ActiveSupport::Deprecation.warn(
26
+ "Logger don't need to call #after_initialize directly anymore. It will be deprecated without replacement in " \
27
+ "Rails 6.1."
28
+ )
11
29
  end
12
30
 
13
31
  def local_log_id
14
- Thread.current.__id__
32
+ Fiber.current.__id__
15
33
  end
16
34
 
17
35
  def local_level
18
- @local_levels[local_log_id]
36
+ self.class.local_levels[local_log_id]
19
37
  end
20
38
 
21
39
  def local_level=(level)
22
40
  if level
23
- @local_levels[local_log_id] = level
41
+ self.class.local_levels[local_log_id] = level
24
42
  else
25
- @local_levels.delete(local_log_id)
43
+ self.class.local_levels.delete(local_log_id)
26
44
  end
27
45
  end
28
46
 
29
47
  def level
30
48
  local_level || super
31
49
  end
50
+
51
+ def add(severity, message = nil, progname = nil, &block) # :nodoc:
52
+ return true if @logdev.nil? || (severity || UNKNOWN) < level
53
+ super
54
+ end
32
55
  end
33
56
  end