activesupport 5.1.7 → 5.2.7

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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +424 -512
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_support/all.rb +2 -0
  6. data/lib/active_support/array_inquirer.rb +2 -0
  7. data/lib/active_support/backtrace_cleaner.rb +2 -0
  8. data/lib/active_support/benchmarkable.rb +2 -0
  9. data/lib/active_support/builder.rb +2 -0
  10. data/lib/active_support/cache/file_store.rb +5 -4
  11. data/lib/active_support/cache/mem_cache_store.rb +39 -38
  12. data/lib/active_support/cache/memory_store.rb +2 -0
  13. data/lib/active_support/cache/null_store.rb +2 -0
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +33 -2
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  17. data/lib/active_support/cache.rb +197 -83
  18. data/lib/active_support/callbacks.rb +28 -39
  19. data/lib/active_support/concern.rb +10 -4
  20. data/lib/active_support/concurrency/share_lock.rb +2 -0
  21. data/lib/active_support/configurable.rb +2 -0
  22. data/lib/active_support/core_ext/array/access.rb +4 -2
  23. data/lib/active_support/core_ext/array/conversions.rb +2 -0
  24. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  25. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  26. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  27. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -2
  28. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  29. data/lib/active_support/core_ext/array.rb +2 -0
  30. data/lib/active_support/core_ext/benchmark.rb +2 -0
  31. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  32. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  33. data/lib/active_support/core_ext/class/attribute.rb +34 -16
  34. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  35. data/lib/active_support/core_ext/class/subclasses.rb +1 -2
  36. data/lib/active_support/core_ext/class.rb +2 -0
  37. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  38. data/lib/active_support/core_ext/date/blank.rb +2 -0
  39. data/lib/active_support/core_ext/date/calculations.rb +2 -0
  40. data/lib/active_support/core_ext/date/conversions.rb +10 -9
  41. data/lib/active_support/core_ext/date/zones.rb +2 -0
  42. data/lib/active_support/core_ext/date.rb +2 -0
  43. data/lib/active_support/core_ext/date_and_time/calculations.rb +50 -16
  44. data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
  45. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
  46. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  47. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  48. data/lib/active_support/core_ext/date_time/calculations.rb +2 -0
  49. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  50. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  51. data/lib/active_support/core_ext/date_time.rb +2 -0
  52. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  53. data/lib/active_support/core_ext/digest.rb +3 -0
  54. data/lib/active_support/core_ext/enumerable.rb +8 -1
  55. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  56. data/lib/active_support/core_ext/file.rb +2 -0
  57. data/lib/active_support/core_ext/hash/compact.rb +2 -0
  58. data/lib/active_support/core_ext/hash/conversions.rb +4 -2
  59. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  60. data/lib/active_support/core_ext/hash/except.rb +2 -0
  61. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  62. data/lib/active_support/core_ext/hash/keys.rb +2 -0
  63. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  64. data/lib/active_support/core_ext/hash/slice.rb +4 -4
  65. data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
  66. data/lib/active_support/core_ext/hash.rb +2 -0
  67. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  68. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  69. data/lib/active_support/core_ext/integer/time.rb +7 -14
  70. data/lib/active_support/core_ext/integer.rb +2 -0
  71. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  72. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  75. data/lib/active_support/core_ext/kernel.rb +2 -0
  76. data/lib/active_support/core_ext/load_error.rb +2 -7
  77. data/lib/active_support/core_ext/marshal.rb +2 -0
  78. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  79. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  80. data/lib/active_support/core_ext/module/attr_internal.rb +2 -0
  81. data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
  82. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
  83. data/lib/active_support/core_ext/module/concerning.rb +7 -8
  84. data/lib/active_support/core_ext/module/delegation.rb +31 -29
  85. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  86. data/lib/active_support/core_ext/module/introspection.rb +2 -0
  87. data/lib/active_support/core_ext/module/reachable.rb +3 -0
  88. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -0
  91. data/lib/active_support/core_ext/name_error.rb +7 -0
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
  94. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
  95. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  96. data/lib/active_support/core_ext/numeric.rb +2 -0
  97. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  98. data/lib/active_support/core_ext/object/blank.rb +12 -1
  99. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  100. data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
  101. data/lib/active_support/core_ext/object/duplicable.rb +10 -8
  102. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  103. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  104. data/lib/active_support/core_ext/object/json.rb +8 -0
  105. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  106. data/lib/active_support/core_ext/object/to_query.rb +2 -0
  107. data/lib/active_support/core_ext/object/try.rb +2 -0
  108. data/lib/active_support/core_ext/object/with_options.rb +3 -1
  109. data/lib/active_support/core_ext/object.rb +2 -0
  110. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  111. data/lib/active_support/core_ext/range/conversions.rb +9 -1
  112. data/lib/active_support/core_ext/range/each.rb +5 -1
  113. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  114. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  115. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  116. data/lib/active_support/core_ext/range.rb +4 -1
  117. data/lib/active_support/core_ext/regexp.rb +2 -0
  118. data/lib/active_support/core_ext/securerandom.rb +2 -0
  119. data/lib/active_support/core_ext/string/access.rb +2 -0
  120. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  121. data/lib/active_support/core_ext/string/conversions.rb +2 -0
  122. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  123. data/lib/active_support/core_ext/string/filters.rb +2 -0
  124. data/lib/active_support/core_ext/string/indent.rb +2 -0
  125. data/lib/active_support/core_ext/string/inflections.rb +26 -12
  126. data/lib/active_support/core_ext/string/inquiry.rb +2 -0
  127. data/lib/active_support/core_ext/string/multibyte.rb +4 -0
  128. data/lib/active_support/core_ext/string/output_safety.rb +6 -7
  129. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  130. data/lib/active_support/core_ext/string/strip.rb +2 -0
  131. data/lib/active_support/core_ext/string/zones.rb +2 -0
  132. data/lib/active_support/core_ext/string.rb +2 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +23 -15
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +6 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes.rb +195 -0
  142. data/lib/active_support/dependencies/autoload.rb +2 -0
  143. data/lib/active_support/dependencies/interlock.rb +2 -0
  144. data/lib/active_support/dependencies.rb +25 -26
  145. data/lib/active_support/deprecation/behaviors.rb +28 -9
  146. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  147. data/lib/active_support/deprecation/instance_delegator.rb +2 -0
  148. data/lib/active_support/deprecation/method_wrappers.rb +30 -17
  149. data/lib/active_support/deprecation/proxy_wrappers.rb +5 -2
  150. data/lib/active_support/deprecation/reporting.rb +5 -3
  151. data/lib/active_support/deprecation.rb +4 -2
  152. data/lib/active_support/descendants_tracker.rb +2 -0
  153. data/lib/active_support/digest.rb +20 -0
  154. data/lib/active_support/duration/iso8601_parser.rb +4 -2
  155. data/lib/active_support/duration/iso8601_serializer.rb +4 -2
  156. data/lib/active_support/duration.rb +22 -14
  157. data/lib/active_support/encrypted_configuration.rb +49 -0
  158. data/lib/active_support/encrypted_file.rb +99 -0
  159. data/lib/active_support/evented_file_update_checker.rb +2 -0
  160. data/lib/active_support/execution_wrapper.rb +18 -13
  161. data/lib/active_support/executor.rb +2 -0
  162. data/lib/active_support/file_update_checker.rb +2 -0
  163. data/lib/active_support/gem_version.rb +3 -1
  164. data/lib/active_support/gzip.rb +2 -0
  165. data/lib/active_support/hash_with_indifferent_access.rb +55 -1
  166. data/lib/active_support/i18n.rb +3 -1
  167. data/lib/active_support/i18n_railtie.rb +4 -6
  168. data/lib/active_support/inflections.rb +2 -0
  169. data/lib/active_support/inflector/inflections.rb +20 -4
  170. data/lib/active_support/inflector/methods.rb +43 -24
  171. data/lib/active_support/inflector/transliterate.rb +17 -8
  172. data/lib/active_support/inflector.rb +2 -0
  173. data/lib/active_support/json/decoding.rb +2 -0
  174. data/lib/active_support/json/encoding.rb +2 -0
  175. data/lib/active_support/json.rb +2 -0
  176. data/lib/active_support/key_generator.rb +3 -1
  177. data/lib/active_support/lazy_load_hooks.rb +2 -0
  178. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  179. data/lib/active_support/log_subscriber.rb +3 -2
  180. data/lib/active_support/logger.rb +2 -0
  181. data/lib/active_support/logger_silence.rb +3 -2
  182. data/lib/active_support/logger_thread_safe_level.rb +4 -1
  183. data/lib/active_support/message_encryptor.rb +95 -22
  184. data/lib/active_support/message_verifier.rb +78 -7
  185. data/lib/active_support/messages/metadata.rb +71 -0
  186. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  187. data/lib/active_support/messages/rotator.rb +56 -0
  188. data/lib/active_support/multibyte/chars.rb +2 -0
  189. data/lib/active_support/multibyte/unicode.rb +4 -2
  190. data/lib/active_support/multibyte.rb +2 -0
  191. data/lib/active_support/notifications/fanout.rb +4 -2
  192. data/lib/active_support/notifications/instrumenter.rb +2 -0
  193. data/lib/active_support/notifications.rb +2 -0
  194. data/lib/active_support/number_helper/number_converter.rb +2 -0
  195. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
  196. data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
  197. data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
  198. data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
  199. data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
  200. data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
  201. data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
  202. data/lib/active_support/number_helper/rounding_helper.rb +6 -4
  203. data/lib/active_support/number_helper.rb +2 -0
  204. data/lib/active_support/option_merger.rb +2 -0
  205. data/lib/active_support/ordered_hash.rb +2 -0
  206. data/lib/active_support/ordered_options.rb +5 -3
  207. data/lib/active_support/per_thread_registry.rb +2 -0
  208. data/lib/active_support/proxy_object.rb +2 -0
  209. data/lib/active_support/rails.rb +2 -0
  210. data/lib/active_support/railtie.rb +37 -8
  211. data/lib/active_support/reloader.rb +8 -6
  212. data/lib/active_support/rescuable.rb +3 -2
  213. data/lib/active_support/security_utils.rb +15 -11
  214. data/lib/active_support/string_inquirer.rb +2 -0
  215. data/lib/active_support/subscriber.rb +8 -2
  216. data/lib/active_support/tagged_logging.rb +2 -0
  217. data/lib/active_support/test_case.rb +3 -2
  218. data/lib/active_support/testing/assertions.rb +31 -14
  219. data/lib/active_support/testing/autorun.rb +2 -0
  220. data/lib/active_support/testing/constant_lookup.rb +2 -0
  221. data/lib/active_support/testing/declarative.rb +2 -0
  222. data/lib/active_support/testing/deprecation.rb +2 -0
  223. data/lib/active_support/testing/file_fixtures.rb +2 -0
  224. data/lib/active_support/testing/isolation.rb +3 -1
  225. data/lib/active_support/testing/method_call_assertions.rb +2 -0
  226. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  227. data/lib/active_support/testing/stream.rb +2 -0
  228. data/lib/active_support/testing/tagged_logging.rb +2 -0
  229. data/lib/active_support/testing/time_helpers.rb +33 -3
  230. data/lib/active_support/time.rb +2 -0
  231. data/lib/active_support/time_with_zone.rb +38 -0
  232. data/lib/active_support/values/time_zone.rb +20 -8
  233. data/lib/active_support/version.rb +2 -0
  234. data/lib/active_support/xml_mini/jdom.rb +4 -2
  235. data/lib/active_support/xml_mini/libxml.rb +3 -1
  236. data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
  237. data/lib/active_support/xml_mini/nokogiri.rb +3 -1
  238. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  239. data/lib/active_support/xml_mini/rexml.rb +3 -1
  240. data/lib/active_support/xml_mini.rb +4 -2
  241. data/lib/active_support.rb +5 -13
  242. metadata +17 -5
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/string/conversions"
2
4
  require "active_support/core_ext/time/zones"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/string/conversions"
2
4
  require "active_support/core_ext/string/filters"
3
5
  require "active_support/core_ext/string/multibyte"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/acts_like"
2
4
 
3
5
  class Time
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/duration"
2
4
  require "active_support/core_ext/time/conversions"
3
5
  require "active_support/time_with_zone"
@@ -107,21 +109,22 @@ class Time
107
109
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
108
110
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
109
111
  # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
110
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+
111
- # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
112
- # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
113
- # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
112
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
113
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
114
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
115
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
114
116
  #
115
117
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
116
118
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
117
119
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
118
120
  def change(options)
119
- new_year = options.fetch(:year, year)
120
- new_month = options.fetch(:month, month)
121
- new_day = options.fetch(:day, day)
122
- new_hour = options.fetch(:hour, hour)
123
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
124
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
121
+ new_year = options.fetch(:year, year)
122
+ new_month = options.fetch(:month, month)
123
+ new_day = options.fetch(:day, day)
124
+ new_hour = options.fetch(:hour, hour)
125
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
126
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
127
+ new_offset = options.fetch(:offset, nil)
125
128
 
126
129
  if new_nsec = options[:nsec]
127
130
  raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
@@ -130,13 +133,18 @@ class Time
130
133
  new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
131
134
  end
132
135
 
133
- if utc?
134
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
136
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
137
+
138
+ new_sec += Rational(new_usec, 1000000)
139
+
140
+ if new_offset
141
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
142
+ elsif utc?
143
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
135
144
  elsif zone
136
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
145
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
137
146
  else
138
- raise ArgumentError, "argument out of range" if new_usec >= 1000000
139
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
147
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
140
148
  end
141
149
  end
142
150
 
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/date_and_time/compatibility"
2
- require "active_support/core_ext/module/remove_method"
4
+ require "active_support/core_ext/module/redefine_method"
3
5
 
4
6
  class Time
5
7
  include DateAndTime::Compatibility
6
8
 
7
- remove_possible_method :to_time
9
+ silence_redefinition_of_method :to_time
8
10
 
9
11
  # Either return +self+ or the time in the local system timezone depending
10
12
  # on the setting of +ActiveSupport.to_time_preserves_timezone+.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/methods"
2
4
  require "active_support/values/time_zone"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/time_with_zone"
2
4
  require "active_support/core_ext/time/acts_like"
3
5
  require "active_support/core_ext/date_and_time/zones"
@@ -53,10 +55,10 @@ class Time
53
55
  # end
54
56
  # end
55
57
  #
56
- # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
57
- # objects that have already been created, e.g. any model timestamp
58
- # attributes that have been read before the block will remain in
59
- # the application's default timezone.
58
+ # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
59
+ # objects that have already been created, e.g. any model timestamp
60
+ # attributes that have been read before the block will remain in
61
+ # the application's default timezone.
60
62
  def use_zone(time_zone)
61
63
  new_zone = find_zone!(time_zone)
62
64
  begin
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/time/acts_like"
2
4
  require "active_support/core_ext/time/calculations"
3
5
  require "active_support/core_ext/time/compatibility"
@@ -1,16 +1,16 @@
1
- require "uri"
2
- str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
3
- parser = URI::Parser.new
1
+ # frozen_string_literal: true
4
2
 
5
- unless str == parser.unescape(parser.escape(str))
3
+ require "uri"
4
+ if RUBY_VERSION < "2.6.0"
5
+ require "active_support/core_ext/module/redefine_method"
6
6
  URI::Parser.class_eval do
7
- remove_method :unescape
7
+ silence_redefinition_of_method :unescape
8
8
  def unescape(str, escaped = /%[a-fA-F\d]{2}/)
9
9
  # TODO: Are we actually sure that ASCII == UTF-8?
10
10
  # YK: My initial experiments say yes, but let's be sure please
11
11
  enc = str.encoding
12
12
  enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
13
- str.gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
13
+ str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
14
14
  end
15
15
  end
16
16
  end
@@ -1,3 +1,5 @@
1
- (Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"]).each do |path|
1
+ # frozen_string_literal: true
2
+
3
+ Dir.glob(File.expand_path("core_ext/*.rb", __dir__)).each do |path|
2
4
  require path
3
5
  end
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
5
+ # before and after each request. This allows you to keep all the per-request attributes easily
6
+ # available to the whole system.
7
+ #
8
+ # The following full app-like example demonstrates how to use a Current class to
9
+ # facilitate easy access to the global, per-request attributes without passing them deeply
10
+ # around everywhere:
11
+ #
12
+ # # app/models/current.rb
13
+ # class Current < ActiveSupport::CurrentAttributes
14
+ # attribute :account, :user
15
+ # attribute :request_id, :user_agent, :ip_address
16
+ #
17
+ # resets { Time.zone = nil }
18
+ #
19
+ # def user=(user)
20
+ # super
21
+ # self.account = user.account
22
+ # Time.zone = user.time_zone
23
+ # end
24
+ # end
25
+ #
26
+ # # app/controllers/concerns/authentication.rb
27
+ # module Authentication
28
+ # extend ActiveSupport::Concern
29
+ #
30
+ # included do
31
+ # before_action :authenticate
32
+ # end
33
+ #
34
+ # private
35
+ # def authenticate
36
+ # if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
37
+ # Current.user = authenticated_user
38
+ # else
39
+ # redirect_to new_session_url
40
+ # end
41
+ # end
42
+ # end
43
+ #
44
+ # # app/controllers/concerns/set_current_request_details.rb
45
+ # module SetCurrentRequestDetails
46
+ # extend ActiveSupport::Concern
47
+ #
48
+ # included do
49
+ # before_action do
50
+ # Current.request_id = request.uuid
51
+ # Current.user_agent = request.user_agent
52
+ # Current.ip_address = request.ip
53
+ # end
54
+ # end
55
+ # end
56
+ #
57
+ # class ApplicationController < ActionController::Base
58
+ # include Authentication
59
+ # include SetCurrentRequestDetails
60
+ # end
61
+ #
62
+ # class MessagesController < ApplicationController
63
+ # def create
64
+ # Current.account.messages.create(message_params)
65
+ # end
66
+ # end
67
+ #
68
+ # class Message < ApplicationRecord
69
+ # belongs_to :creator, default: -> { Current.user }
70
+ # after_create { |message| Event.create(record: message) }
71
+ # end
72
+ #
73
+ # class Event < ApplicationRecord
74
+ # before_create do
75
+ # self.request_id = Current.request_id
76
+ # self.user_agent = Current.user_agent
77
+ # self.ip_address = Current.ip_address
78
+ # end
79
+ # end
80
+ #
81
+ # A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
82
+ # Current should only be used for a few, top-level globals, like account, user, and request details.
83
+ # The attributes stuck in Current should be used by more or less all actions on all requests. If you start
84
+ # sticking controller-specific attributes in there, you're going to create a mess.
85
+ class CurrentAttributes
86
+ include ActiveSupport::Callbacks
87
+ define_callbacks :reset
88
+
89
+ class << self
90
+ # Returns singleton instance for this class in this thread. If none exists, one is created.
91
+ def instance
92
+ current_instances[name] ||= new
93
+ end
94
+
95
+ # Declares one or more attributes that will be given both class and instance accessor methods.
96
+ def attribute(*names)
97
+ generated_attribute_methods.module_eval do
98
+ names.each do |name|
99
+ define_method(name) do
100
+ attributes[name.to_sym]
101
+ end
102
+
103
+ define_method("#{name}=") do |attribute|
104
+ attributes[name.to_sym] = attribute
105
+ end
106
+ end
107
+ end
108
+
109
+ names.each do |name|
110
+ define_singleton_method(name) do
111
+ instance.public_send(name)
112
+ end
113
+
114
+ define_singleton_method("#{name}=") do |attribute|
115
+ instance.public_send("#{name}=", attribute)
116
+ end
117
+ end
118
+ end
119
+
120
+ # Calls this block after #reset is called on the instance. Used for resetting external collaborators, like Time.zone.
121
+ def resets(&block)
122
+ set_callback :reset, :after, &block
123
+ end
124
+
125
+ delegate :set, :reset, to: :instance
126
+
127
+ def reset_all # :nodoc:
128
+ current_instances.each_value(&:reset)
129
+ end
130
+
131
+ def clear_all # :nodoc:
132
+ reset_all
133
+ current_instances.clear
134
+ end
135
+
136
+ private
137
+ def generated_attribute_methods
138
+ @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
139
+ end
140
+
141
+ def current_instances
142
+ Thread.current[:current_attributes_instances] ||= {}
143
+ end
144
+
145
+ def method_missing(name, *args, &block)
146
+ # Caches the method definition as a singleton method of the receiver.
147
+ #
148
+ # By letting #delegate handle it, we avoid an enclosure that'll capture args.
149
+ singleton_class.delegate name, to: :instance
150
+
151
+ send(name, *args, &block)
152
+ end
153
+ end
154
+
155
+ attr_accessor :attributes
156
+
157
+ def initialize
158
+ @attributes = {}
159
+ end
160
+
161
+ # Expose one or more attributes within a block. Old values are returned after the block concludes.
162
+ # Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
163
+ #
164
+ # class Chat::PublicationJob < ApplicationJob
165
+ # def perform(attributes, room_number, creator)
166
+ # Current.set(person: creator) do
167
+ # Chat::Publisher.publish(attributes: attributes, room_number: room_number)
168
+ # end
169
+ # end
170
+ # end
171
+ def set(set_attributes)
172
+ old_attributes = compute_attributes(set_attributes.keys)
173
+ assign_attributes(set_attributes)
174
+ yield
175
+ ensure
176
+ assign_attributes(old_attributes)
177
+ end
178
+
179
+ # Reset all attributes. Should be called before and after actions, when used as a per-request singleton.
180
+ def reset
181
+ run_callbacks :reset do
182
+ self.attributes = {}
183
+ end
184
+ end
185
+
186
+ private
187
+ def assign_attributes(new_attributes)
188
+ new_attributes.each { |key, value| public_send("#{key}=", value) }
189
+ end
190
+
191
+ def compute_attributes(keys)
192
+ keys.collect { |key| [ key, public_send(key) ] }.to_h
193
+ end
194
+ end
195
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/methods"
2
4
 
3
5
  module ActiveSupport
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concurrency/share_lock"
2
4
 
3
5
  module ActiveSupport #:nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
  require "thread"
3
5
  require "concurrent/map"
@@ -18,8 +20,7 @@ module ActiveSupport #:nodoc:
18
20
  module Dependencies #:nodoc:
19
21
  extend self
20
22
 
21
- mattr_accessor :interlock
22
- self.interlock = Interlock.new
23
+ mattr_accessor :interlock, default: Interlock.new
23
24
 
24
25
  # :doc:
25
26
 
@@ -46,46 +47,37 @@ module ActiveSupport #:nodoc:
46
47
  # :nodoc:
47
48
 
48
49
  # Should we turn on Ruby warnings on the first load of dependent files?
49
- mattr_accessor :warnings_on_first_load
50
- self.warnings_on_first_load = false
50
+ mattr_accessor :warnings_on_first_load, default: false
51
51
 
52
52
  # All files ever loaded.
53
- mattr_accessor :history
54
- self.history = Set.new
53
+ mattr_accessor :history, default: Set.new
55
54
 
56
55
  # All files currently loaded.
57
- mattr_accessor :loaded
58
- self.loaded = Set.new
56
+ mattr_accessor :loaded, default: Set.new
59
57
 
60
58
  # Stack of files being loaded.
61
- mattr_accessor :loading
62
- self.loading = []
59
+ mattr_accessor :loading, default: []
63
60
 
64
61
  # Should we load files or require them?
65
- mattr_accessor :mechanism
66
- self.mechanism = ENV["NO_RELOAD"] ? :require : :load
62
+ mattr_accessor :mechanism, default: ENV["NO_RELOAD"] ? :require : :load
67
63
 
68
64
  # The set of directories from which we may automatically load files. Files
69
65
  # under these directories will be reloaded on each request in development mode,
70
66
  # unless the directory also appears in autoload_once_paths.
71
- mattr_accessor :autoload_paths
72
- self.autoload_paths = []
67
+ mattr_accessor :autoload_paths, default: []
73
68
 
74
69
  # The set of directories from which automatically loaded constants are loaded
75
70
  # only once. All directories in this set must also be present in +autoload_paths+.
76
- mattr_accessor :autoload_once_paths
77
- self.autoload_once_paths = []
71
+ mattr_accessor :autoload_once_paths, default: []
78
72
 
79
73
  # An array of qualified constant names that have been loaded. Adding a name
80
74
  # to this array will cause it to be unloaded the next time Dependencies are
81
75
  # cleared.
82
- mattr_accessor :autoloaded_constants
83
- self.autoloaded_constants = []
76
+ mattr_accessor :autoloaded_constants, default: []
84
77
 
85
78
  # An array of constant names that need to be unloaded on every request. Used
86
79
  # to allow arbitrary constants to be marked for unloading.
87
- mattr_accessor :explicitly_unloadable_constants
88
- self.explicitly_unloadable_constants = []
80
+ mattr_accessor :explicitly_unloadable_constants, default: []
89
81
 
90
82
  # The WatchStack keeps a stack of the modules being watched as files are
91
83
  # loaded. If a file in the process of being loaded (parent.rb) triggers the
@@ -93,7 +85,7 @@ module ActiveSupport #:nodoc:
93
85
  # handles the new constants.
94
86
  #
95
87
  # If child.rb is being autoloaded, its constants will be added to
96
- # autoloaded_constants. If it was being `require`d, they will be discarded.
88
+ # autoloaded_constants. If it was being required, they will be discarded.
97
89
  #
98
90
  # This is handled by walking back up the watch stack and adding the constants
99
91
  # found by child.rb to the list of original constants in parent.rb.
@@ -105,6 +97,8 @@ module ActiveSupport #:nodoc:
105
97
  # parent.rb then requires namespace/child.rb, the stack will look like
106
98
  # [[Object], [Namespace]].
107
99
 
100
+ attr_reader :watching
101
+
108
102
  def initialize
109
103
  @watching = []
110
104
  @stack = Hash.new { |h, k| h[k] = [] }
@@ -175,8 +169,7 @@ module ActiveSupport #:nodoc:
175
169
  end
176
170
 
177
171
  # An internal stack used to record which constants are loaded by any block.
178
- mattr_accessor :constant_watch_stack
179
- self.constant_watch_stack = WatchStack.new
172
+ mattr_accessor :constant_watch_stack, default: WatchStack.new
180
173
 
181
174
  # Module includes this module.
182
175
  module ModuleConstMissing #:nodoc:
@@ -233,6 +226,8 @@ module ActiveSupport #:nodoc:
233
226
  Dependencies.require_or_load(file_name)
234
227
  end
235
228
 
229
+ # :doc:
230
+
236
231
  # Interprets a file using <tt>mechanism</tt> and marks its defined
237
232
  # constants as autoloaded. <tt>file_name</tt> can be either a string or
238
233
  # respond to <tt>to_path</tt>.
@@ -251,9 +246,13 @@ module ActiveSupport #:nodoc:
251
246
  Dependencies.depend_on(file_name, message)
252
247
  end
253
248
 
249
+ # :nodoc:
250
+
254
251
  def load_dependency(file)
255
252
  if Dependencies.load? && Dependencies.constant_watch_stack.watching?
256
- Dependencies.new_constants_in(Object) { yield }
253
+ descs = Dependencies.constant_watch_stack.watching.flatten.uniq
254
+
255
+ Dependencies.new_constants_in(*descs) { yield }
257
256
  else
258
257
  yield
259
258
  end
@@ -625,7 +624,7 @@ module ActiveSupport #:nodoc:
625
624
  return false if desc.is_a?(Module) && desc.anonymous?
626
625
  name = to_constant_name desc
627
626
  return false unless qualified_const_defined?(name)
628
- return autoloaded_constants.include?(name)
627
+ autoloaded_constants.include?(name)
629
628
  end
630
629
 
631
630
  # Will the provided constant descriptor be unloaded?
@@ -680,7 +679,7 @@ module ActiveSupport #:nodoc:
680
679
  when Module
681
680
  desc.name ||
682
681
  raise(ArgumentError, "Anonymous modules have no name to be referenced by")
683
- else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
682
+ else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
684
683
  end
685
684
  end
686
685
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/notifications"
2
4
 
3
5
  module ActiveSupport
@@ -9,18 +11,18 @@ module ActiveSupport
9
11
  class Deprecation
10
12
  # Default warning behaviors per Rails.env.
11
13
  DEFAULT_BEHAVIORS = {
12
- raise: ->(message, callstack) {
14
+ raise: ->(message, callstack, deprecation_horizon, gem_name) {
13
15
  e = DeprecationException.new(message)
14
16
  e.set_backtrace(callstack.map(&:to_s))
15
17
  raise e
16
18
  },
17
19
 
18
- stderr: ->(message, callstack) {
20
+ stderr: ->(message, callstack, deprecation_horizon, gem_name) {
19
21
  $stderr.puts(message)
20
22
  $stderr.puts callstack.join("\n ") if debug
21
23
  },
22
24
 
23
- log: ->(message, callstack) {
25
+ log: ->(message, callstack, deprecation_horizon, gem_name) {
24
26
  logger =
25
27
  if defined?(Rails.logger) && Rails.logger
26
28
  Rails.logger
@@ -32,12 +34,16 @@ module ActiveSupport
32
34
  logger.debug callstack.join("\n ") if debug
33
35
  },
34
36
 
35
- notify: ->(message, callstack) {
36
- ActiveSupport::Notifications.instrument("deprecation.rails",
37
- message: message, callstack: callstack)
37
+ notify: ->(message, callstack, deprecation_horizon, gem_name) {
38
+ notification_name = "deprecation.#{gem_name.underscore.tr('/', '_')}"
39
+ ActiveSupport::Notifications.instrument(notification_name,
40
+ message: message,
41
+ callstack: callstack,
42
+ gem_name: gem_name,
43
+ deprecation_horizon: deprecation_horizon)
38
44
  },
39
45
 
40
- silence: ->(message, callstack) {},
46
+ silence: ->(message, callstack, deprecation_horizon, gem_name) {},
41
47
  }
42
48
 
43
49
  # Behavior module allows to determine how to display deprecation messages.
@@ -79,12 +85,25 @@ module ActiveSupport
79
85
  # ActiveSupport::Deprecation.behavior = :stderr
80
86
  # ActiveSupport::Deprecation.behavior = [:stderr, :log]
81
87
  # ActiveSupport::Deprecation.behavior = MyCustomHandler
82
- # ActiveSupport::Deprecation.behavior = ->(message, callstack) {
88
+ # ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
83
89
  # # custom stuff
84
90
  # }
85
91
  def behavior=(behavior)
86
- @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
92
+ @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
87
93
  end
94
+
95
+ private
96
+ def arity_coerce(behavior)
97
+ unless behavior.respond_to?(:call)
98
+ raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
99
+ end
100
+
101
+ if behavior.arity == 4 || behavior.arity == -1
102
+ behavior
103
+ else
104
+ -> message, callstack, _, _ { behavior.call(message, callstack) }
105
+ end
106
+ end
88
107
  end
89
108
  end
90
109
  end
@@ -1,4 +1,4 @@
1
- require "active_support/inflector/methods"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
4
  class Deprecation
@@ -15,7 +15,7 @@ module ActiveSupport
15
15
  #
16
16
  # PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
17
17
  #
18
- # (In a later update, the original implementation of `PLANETS` has been removed.)
18
+ # # (In a later update, the original implementation of `PLANETS` has been removed.)
19
19
  #
20
20
  # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
21
21
  # include ActiveSupport::Deprecation::DeprecatedConstantAccessor
@@ -27,6 +27,8 @@ module ActiveSupport
27
27
  # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
28
28
  module DeprecatedConstantAccessor
29
29
  def self.included(base)
30
+ require "active_support/inflector/methods"
31
+
30
32
  extension = Module.new do
31
33
  def const_missing(missing_const_name)
32
34
  if class_variable_defined?(:@@_deprecated_constants)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/kernel/singleton_class"
2
4
  require "active_support/core_ext/module/delegation"
3
5