activesupport 1.2.4 → 8.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concurrency/share_lock"
4
+
5
+ module ActiveSupport # :nodoc:
6
+ module Dependencies # :nodoc:
7
+ class Interlock
8
+ def initialize # :nodoc:
9
+ @lock = ActiveSupport::Concurrency::ShareLock.new
10
+ end
11
+
12
+ def loading(&block)
13
+ ActiveSupport.deprecator.warn(
14
+ "ActiveSupport::Dependencies::Interlock#loading is deprecated and " \
15
+ "will be removed in Rails 9.0. The loading interlock is no longer " \
16
+ "used since Rails switched to Zeitwerk for autoloading."
17
+ )
18
+ yield if block
19
+ end
20
+
21
+ def unloading(&block)
22
+ @lock.exclusive(purpose: :unload, compatible: [:unload], after_compatible: [:unload], &block)
23
+ end
24
+
25
+ def start_unloading
26
+ @lock.start_exclusive(purpose: :unload, compatible: [:unload])
27
+ end
28
+
29
+ def done_unloading
30
+ @lock.stop_exclusive(compatible: [:unload])
31
+ end
32
+
33
+ def start_running
34
+ @lock.start_sharing
35
+ end
36
+
37
+ def done_running
38
+ @lock.stop_sharing
39
+ end
40
+
41
+ def running(&block)
42
+ @lock.sharing(&block)
43
+ end
44
+
45
+ def permit_concurrent_loads(&block)
46
+ # Soft deprecated: no deprecation warning for now, but this is a no-op.
47
+ yield if block
48
+ end
49
+
50
+ def raw_state(&block) # :nodoc:
51
+ @lock.raw_state(&block)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport::Dependencies::RequireDependency
4
+ # <b>Warning:</b> This method is obsolete. The semantics of the autoloader
5
+ # match Ruby's and you do not need to be defensive with load order anymore.
6
+ # Just refer to classes and modules normally.
7
+ #
8
+ # Engines that do not control the mode in which their parent application runs
9
+ # should call +require_dependency+ where needed in case the runtime mode is
10
+ # +:classic+.
11
+ def require_dependency(filename)
12
+ filename = filename.to_path if filename.respond_to?(:to_path)
13
+
14
+ unless filename.is_a?(String)
15
+ raise ArgumentError, "the file name must be either a String or implement #to_path -- you passed #{filename.inspect}"
16
+ end
17
+
18
+ if abspath = ActiveSupport::Dependencies.search_for_file(filename)
19
+ require abspath
20
+ else
21
+ require filename
22
+ end
23
+ end
24
+
25
+ # We could define require_dependency in Object directly, but a module makes
26
+ # the extension apparent if you list ancestors.
27
+ Object.prepend(self)
28
+ end
@@ -1,240 +1,102 @@
1
- require File.dirname(__FILE__) + '/module_attribute_accessors'
2
- require File.dirname(__FILE__) + '/core_ext/load_error'
1
+ # frozen_string_literal: true
3
2
 
4
- module Dependencies #:nodoc:
5
- extend self
3
+ require "active_support/dependencies/interlock"
6
4
 
7
- @@loaded = [ ]
8
- mattr_accessor :loaded
5
+ module ActiveSupport # :nodoc:
6
+ module Dependencies # :nodoc:
7
+ require_relative "dependencies/require_dependency"
9
8
 
10
- @@mechanism = :load
11
- mattr_accessor :mechanism
12
-
13
- def load?
14
- mechanism == :load
15
- end
16
-
17
- def depend_on(file_name, swallow_load_errors = false)
18
- unless loaded.include?(file_name)
19
- loaded << file_name
20
-
21
- begin
22
- require_or_load(file_name)
23
- rescue LoadError
24
- raise unless swallow_load_errors
25
- end
26
- end
27
- end
9
+ singleton_class.attr_accessor :interlock
10
+ @interlock = Interlock.new
28
11
 
29
- def associate_with(file_name)
30
- depend_on(file_name, true)
31
- end
32
-
33
- def clear
34
- self.loaded = [ ]
35
- end
36
-
37
- def require_or_load(file_name)
38
- file_name = "#{file_name}.rb" unless ! load? || file_name[-3..-1] == '.rb'
39
- load? ? load(file_name) : require(file_name)
40
- end
41
-
42
- def remove_subclasses_for(*classes)
43
- Object.remove_subclasses_of(*classes)
44
- end
45
-
46
- # LoadingModules implement namespace-safe dynamic loading.
47
- # They support automatic loading via const_missing, allowing contained items to be automatically
48
- # loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController
49
- # load the relavent files automatically.
50
- #
51
- # Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available.
52
- class LoadingModule < Module #:nodoc:
53
- attr_reader :path
54
- attr_reader :root
55
-
56
- class << self
57
- def root(*load_paths)
58
- RootLoadingModule.new(*load_paths)
59
- end
60
- end
61
-
62
- def initialize(root, path=[])
63
- @path = path.clone.freeze
64
- @root = root
65
- end
66
-
67
- def root?() self.root == self end
68
- def load_paths() self.root.load_paths end
69
-
70
- # Load missing constants if possible.
71
- def const_missing(name)
72
- const_load!(name) ? const_get(name) : super(name)
73
- end
74
-
75
- # Load the controller class or a parent module.
76
- def const_load!(name, file_name = nil)
77
- file_name ||= 'application' if root? && name.to_s == 'ApplicationController'
78
- path = self.path + [file_name || name]
79
-
80
- load_paths.each do |load_path|
81
- fs_path = load_path.filesystem_path(path)
82
- next unless fs_path
83
-
84
- case
85
- when File.directory?(fs_path)
86
- new_module = LoadingModule.new(self.root, self.path + [name])
87
- self.const_set name, new_module
88
- if self.root?
89
- if Object.const_defined?(name)
90
- msg = "Cannot load module #{name}: Object::#{name} is set to #{Object.const_get(name).inspect}"
91
- raise NameError, msg
92
- end
93
- Object.const_set(name, new_module)
94
- end
95
- break
96
- when File.file?(fs_path)
97
- loaded_file = self.root.load_file!(fs_path)
98
-
99
- # Import the loaded constant from Object provided we are the root node.
100
- self.const_set(name, Object.const_get(name)) if self.root? && Object.const_defined?(name)
101
-
102
- # Throw an error if we load the file but we don't find the Object we expect
103
- if loaded_file and not self.const_defined?(name)
104
- msg = "Already loaded file '#{fs_path}' but '#{name.to_s}' was not set, perhaps you need to rename '#{fs_path}'?"
105
- raise LoadError, msg
106
- end
107
- break
108
- end
109
- end
110
-
111
- self.const_defined?(name)
112
- end
113
-
114
- # Is this name present or loadable?
115
- # This method is used by Routes to find valid controllers.
116
- def const_available?(name)
117
- self.const_defined?(name) || load_paths.any? {|lp| lp.filesystem_path(path + [name])}
118
- end
119
- end
120
-
121
- class RootLoadingModule < LoadingModule #:nodoc:
122
- attr_reader :load_paths
12
+ # :doc:
123
13
 
124
- def initialize(*paths)
125
- @load_paths = paths.flatten.collect {|p| p.kind_of?(ConstantLoadPath) ? p : ConstantLoadPath.new(p)}
14
+ # Execute the supplied block without interference from any
15
+ # concurrent loads.
16
+ def self.run_interlock(&block)
17
+ interlock.running(&block)
126
18
  end
127
19
 
128
- def root() self end
129
-
130
- def path() [] end
131
-
132
- # Load the source file at the given file path
133
- def load_file!(file_path)
134
- require_dependency(file_path)
20
+ # Execute the supplied block while holding an exclusive lock,
21
+ # preventing any other thread from being inside a #run_interlock
22
+ # block at the same time.
23
+ def self.load_interlock(&block)
24
+ ActiveSupport.deprecator.warn(
25
+ "ActiveSupport::Dependencies.load_interlock is deprecated and " \
26
+ "will be removed in Rails 9.0. The loading interlock is no longer " \
27
+ "used since Rails switched to Zeitwerk for autoloading."
28
+ )
29
+ yield if block
135
30
  end
136
31
 
137
- # Erase all items in this module
138
- def clear!
139
- constants.each do |name|
140
- Object.send(:remove_const, name) if Object.const_defined?(name) && Object.const_get(name).object_id == self.const_get(name).object_id
141
- self.send(:remove_const, name)
142
- end
32
+ # Execute the supplied block while holding an exclusive lock,
33
+ # preventing any other thread from being inside a #run_interlock
34
+ # block at the same time.
35
+ def self.unload_interlock(&block)
36
+ interlock.unloading(&block)
143
37
  end
144
- end
145
-
146
- # This object defines a path from which Constants can be loaded.
147
- class ConstantLoadPath #:nodoc:
148
- # Create a new load path with the filesystem path
149
- def initialize(root) @root = root end
150
-
151
- # Return nil if the path does not exist, or the path to a directory
152
- # if the path leads to a module, or the path to a file if it leads to an object.
153
- def filesystem_path(path, allow_module=true)
154
- fs_path = [@root]
155
- fs_path += path[0..-2].map {|name| const_name_to_module_name name}
156
-
157
- if allow_module
158
- result = File.join(fs_path, const_name_to_module_name(path.last))
159
- return result if File.directory? result # Return the module path if one exists
160
- end
161
38
 
162
- result = File.join(fs_path, const_name_to_file_name(path.last))
163
-
164
- File.file?(result) ? result : nil
165
- end
166
-
167
- def const_name_to_file_name(name)
168
- name.to_s.underscore + '.rb'
39
+ # :nodoc:
40
+
41
+ # The array of directories from which we autoload and reload, if reloading
42
+ # is enabled. The public interface to push directories to this collection
43
+ # from applications or engines is config.autoload_paths.
44
+ #
45
+ # This collection is allowed to have intersection with autoload_once_paths.
46
+ # Common directories are not reloaded.
47
+ singleton_class.attr_accessor :autoload_paths
48
+ self.autoload_paths = []
49
+
50
+ # The array of directories from which we autoload and never reload, even if
51
+ # reloading is enabled. The public interface to push directories to this
52
+ # collection from applications or engines is config.autoload_once_paths.
53
+ singleton_class.attr_accessor :autoload_once_paths
54
+ self.autoload_once_paths = []
55
+
56
+ # This is a private set that collects all eager load paths during bootstrap.
57
+ # Useful for Zeitwerk integration. The public interface to push custom
58
+ # directories to this collection from applications or engines is
59
+ # config.eager_load_paths.
60
+ singleton_class.attr_accessor :_eager_load_paths
61
+ self._eager_load_paths = Set.new
62
+
63
+ # If reloading is enabled, this private set holds autoloaded classes tracked
64
+ # by the descendants tracker. It is populated by an on_load callback in the
65
+ # main autoloader. Used to clear state.
66
+ singleton_class.attr_accessor :_autoloaded_tracked_classes
67
+ self._autoloaded_tracked_classes = Set.new
68
+
69
+ # If reloading is enabled, this private attribute stores the main autoloader
70
+ # of a Rails application. It is `nil` otherwise.
71
+ #
72
+ # The public interface for this autoloader is `Rails.autoloaders.main`.
73
+ singleton_class.attr_accessor :autoloader
74
+
75
+ # Private method that reloads constants autoloaded by the main autoloader.
76
+ #
77
+ # Rails.application.reloader.reload! is the public interface for application
78
+ # reload. That involves more things, like deleting unloaded classes from the
79
+ # internal state of the descendants tracker, or reloading routes.
80
+ def self.clear
81
+ unload_interlock do
82
+ _autoloaded_tracked_classes.clear
83
+ autoloader.reload
84
+ end
169
85
  end
170
86
 
171
- def const_name_to_module_name(name)
172
- name.to_s.underscore
87
+ # Private method used by require_dependency.
88
+ def self.search_for_file(relpath)
89
+ relpath += ".rb" unless relpath.end_with?(".rb")
90
+ autoload_paths.each do |autoload_path|
91
+ abspath = File.join(autoload_path, relpath)
92
+ return abspath if File.file?(abspath)
93
+ end
94
+ nil
173
95
  end
174
- end
175
- end
176
-
177
- Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
178
- Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
179
- Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
180
-
181
- class Module #:nodoc:
182
- # Rename the original handler so we can chain it to the new one
183
- alias :rails_original_const_missing :const_missing
184
96
 
185
- # Use const_missing to autoload associations so we don't have to
186
- # require_association when using single-table inheritance.
187
- def const_missing(class_id)
188
- if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id)
189
- return Object::Controllers.const_get(class_id)
97
+ # Private method that helps configuring the autoloaders.
98
+ def self.eager_load?(path)
99
+ _eager_load_paths.member?(path)
190
100
  end
191
-
192
- file_name = class_id.to_s.demodulize.underscore
193
- begin
194
- require_dependency(file_name)
195
- raise NameError.new("uninitialized constant #{class_id}") unless Object.const_defined?(class_id)
196
- return Object.const_get(class_id)
197
- rescue MissingSourceFile => e
198
- # Convert the exception to a NameError only if the file we are looking for is the missing one.
199
- raise unless e.is_missing? file_name
200
- raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
201
- end
202
- end
203
- end
204
-
205
- class Object #:nodoc:
206
- def load(file, *extras)
207
- super(file, *extras)
208
- rescue Object => exception
209
- exception.blame_file! file
210
- raise
211
- end
212
-
213
- def require(file, *extras)
214
- super(file, *extras)
215
- rescue Object => exception
216
- exception.blame_file! file
217
- raise
218
- end
219
- end
220
-
221
- # Add file-blaming to exceptions
222
- class Exception #:nodoc:
223
- def blame_file!(file)
224
- (@blamed_files ||= []).unshift file
225
- end
226
-
227
- def blamed_files
228
- @blamed_files ||= []
229
- end
230
-
231
- def describe_blame
232
- return nil if blamed_files.empty?
233
- "This error occured while loading the following files:\n #{blamed_files.join "\n "}"
234
- end
235
-
236
- def copy_blame!(exc)
237
- @blamed_files = exc.blamed_files.clone
238
- self
239
101
  end
240
102
  end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/notifications"
4
+
5
+ module ActiveSupport
6
+ # Raised when ActiveSupport::Deprecation::Behavior#behavior is set with <tt>:raise</tt>.
7
+ # You would set <tt>:raise</tt>, as a behavior to raise errors and proactively report exceptions from deprecations.
8
+ class DeprecationException < StandardError
9
+ end
10
+
11
+ class Deprecation
12
+ # Default warning behaviors per Rails.env.
13
+ DEFAULT_BEHAVIORS = {
14
+ raise: ->(message, callstack, deprecator) do
15
+ e = DeprecationException.new(message)
16
+ e.set_backtrace(callstack.map(&:to_s))
17
+ raise e
18
+ end,
19
+
20
+ stderr: ->(message, callstack, deprecator) do
21
+ $stderr.puts(message)
22
+ $stderr.puts callstack.join("\n ") if deprecator.debug
23
+ end,
24
+
25
+ log: ->(message, callstack, deprecator) do
26
+ logger =
27
+ if defined?(Rails.logger) && Rails.logger
28
+ Rails.logger
29
+ else
30
+ require "active_support/logger"
31
+ ActiveSupport::Logger.new($stderr)
32
+ end
33
+ logger.warn message
34
+ logger.debug callstack.join("\n ") if deprecator.debug
35
+ end,
36
+
37
+ notify: ->(message, callstack, deprecator) do
38
+ ActiveSupport::Notifications.instrument(
39
+ "deprecation.#{deprecator.gem_name.underscore.tr("/", "_")}",
40
+ message: message,
41
+ callstack: callstack,
42
+ gem_name: deprecator.gem_name,
43
+ deprecation_horizon: deprecator.deprecation_horizon,
44
+ )
45
+ end,
46
+
47
+ silence: ->(message, callstack, deprecator) { },
48
+
49
+ report: ->(message, callstack, deprecator) do
50
+ error = DeprecationException.new(message)
51
+ error.set_backtrace(callstack.map(&:to_s))
52
+ ActiveSupport.error_reporter.report(error)
53
+ end
54
+ }
55
+
56
+ # Behavior module allows to determine how to display deprecation messages.
57
+ # You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
58
+ # constant. Available behaviors are:
59
+ #
60
+ # [+:raise+] Raise ActiveSupport::DeprecationException.
61
+ # [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
62
+ # [+:log+] Log all deprecation warnings to +Rails.logger+.
63
+ # [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
64
+ # [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
65
+ # [+:silence+] Do nothing. On \Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
66
+ #
67
+ # Setting behaviors only affects deprecations that happen after boot time.
68
+ # For more information you can read the documentation of the #behavior= method.
69
+ module Behavior
70
+ # Whether to print a backtrace along with the warning.
71
+ attr_accessor :debug
72
+
73
+ # Returns the current behavior or if one isn't set, defaults to +:stderr+.
74
+ def behavior
75
+ @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
76
+ end
77
+
78
+ # Returns the current behavior for disallowed deprecations or if one isn't set, defaults to +:raise+.
79
+ def disallowed_behavior
80
+ @disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]]
81
+ end
82
+
83
+ # Sets the behavior to the specified value. Can be a single value, array,
84
+ # or an object that responds to +call+.
85
+ #
86
+ # Available behaviors:
87
+ #
88
+ # [+:raise+] Raise ActiveSupport::DeprecationException.
89
+ # [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
90
+ # [+:log+] Log all deprecation warnings to +Rails.logger+.
91
+ # [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
92
+ # [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
93
+ # [+:silence+] Do nothing.
94
+ #
95
+ # Setting behaviors only affects deprecations that happen after boot time.
96
+ # Deprecation warnings raised by gems are not affected by this setting
97
+ # because they happen before \Rails boots up.
98
+ #
99
+ # deprecator = ActiveSupport::Deprecation.new
100
+ # deprecator.behavior = :stderr
101
+ # deprecator.behavior = [:stderr, :log]
102
+ # deprecator.behavior = MyCustomHandler
103
+ # deprecator.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
104
+ # # custom stuff
105
+ # }
106
+ #
107
+ # If you are using \Rails, you can set
108
+ # <tt>config.active_support.report_deprecations = false</tt> to disable
109
+ # all deprecation behaviors. This is similar to the +:silence+ option but
110
+ # more performant.
111
+ def behavior=(behavior)
112
+ @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
113
+ end
114
+
115
+ # Sets the behavior for disallowed deprecations (those configured by
116
+ # ActiveSupport::Deprecation#disallowed_warnings=) to the specified
117
+ # value. As with #behavior=, this can be a single value, array, or an
118
+ # object that responds to +call+.
119
+ def disallowed_behavior=(behavior)
120
+ @disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
121
+ end
122
+
123
+ private
124
+ def arity_coerce(behavior)
125
+ unless behavior.respond_to?(:call)
126
+ raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
127
+ end
128
+
129
+ case arity_of_callable(behavior)
130
+ when 2
131
+ ->(message, callstack, deprecator) do
132
+ behavior.call(message, callstack)
133
+ end
134
+ when -2..3
135
+ behavior
136
+ else
137
+ ->(message, callstack, deprecator) do
138
+ behavior.call(message, callstack, deprecator.deprecation_horizon, deprecator.gem_name)
139
+ end
140
+ end
141
+ end
142
+
143
+ def arity_of_callable(callable)
144
+ callable.respond_to?(:arity) ? callable.arity : callable.method(:call).arity
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ class Deprecation
5
+ module DeprecatedConstantAccessor
6
+ def self.included(base)
7
+ require "active_support/inflector/methods"
8
+
9
+ extension = Module.new do
10
+ def const_missing(missing_const_name)
11
+ if class_variable_defined?(:@@_deprecated_constants)
12
+ if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s])
13
+ replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations)
14
+ return ActiveSupport::Inflector.constantize(replacement[:new].to_s)
15
+ end
16
+ end
17
+ super
18
+ end
19
+
20
+ # Provides a way to rename constants with a deprecation cycle in which
21
+ # both the old and new names work, but using the old one prints a
22
+ # deprecation message.
23
+ #
24
+ # In order to rename <tt>A::B</tt> to <tt>C::D</tt>, you need to delete the
25
+ # definition of <tt>A::B</tt> and declare the deprecation in +A+:
26
+ #
27
+ # require "active_support/deprecation"
28
+ #
29
+ # module A
30
+ # include ActiveSupport::Deprecation::DeprecatedConstantAccessor
31
+ #
32
+ # deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new
33
+ # end
34
+ #
35
+ # The first argument is a constant name (no colons). It is the name of
36
+ # the constant you want to deprecate in the enclosing class or module.
37
+ #
38
+ # The second argument is the constant path of the replacement. That
39
+ # has to be a full path even if the replacement is defined in the same
40
+ # namespace as the deprecated one was.
41
+ #
42
+ # In both cases, strings and symbols are supported.
43
+ #
44
+ # The +deprecator+ keyword argument is the object that will print the
45
+ # deprecation message, an instance of ActiveSupport::Deprecation.
46
+ #
47
+ # With that in place, references to <tt>A::B</tt> still work, they
48
+ # evaluate to <tt>C::D</tt> now, and trigger a deprecation warning:
49
+ #
50
+ # DEPRECATION WARNING: A::B is deprecated! Use C::D instead.
51
+ # (called from ...)
52
+ #
53
+ # The message can be customized with the optional +message+ keyword
54
+ # argument.
55
+ #
56
+ # For this to work, a +const_missing+ hook is installed. When client
57
+ # code references the deprecated constant, the callback prints the
58
+ # message and constantizes the replacement.
59
+ #
60
+ # Caveat: If the deprecated constant name is reachable in a different
61
+ # namespace and Ruby constant lookup finds it, the hook won't be
62
+ # called and the deprecation won't work as intended. This may happen,
63
+ # for example, if an ancestor of the enclosing namespace has a
64
+ # constant with the same name. This is an unsupported edge case.
65
+ def deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil)
66
+ class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
67
+ class_variable_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator }
68
+ end
69
+ end
70
+ base.singleton_class.prepend extension
71
+ end
72
+ end
73
+ end
74
+ end