activesupport 6.0.0

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 (250) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +572 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support.rb +96 -0
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/all.rb +5 -0
  8. data/lib/active_support/array_inquirer.rb +48 -0
  9. data/lib/active_support/backtrace_cleaner.rb +132 -0
  10. data/lib/active_support/benchmarkable.rb +51 -0
  11. data/lib/active_support/builder.rb +8 -0
  12. data/lib/active_support/cache.rb +830 -0
  13. data/lib/active_support/cache/file_store.rb +196 -0
  14. data/lib/active_support/cache/mem_cache_store.rb +212 -0
  15. data/lib/active_support/cache/memory_store.rb +174 -0
  16. data/lib/active_support/cache/null_store.rb +48 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +488 -0
  18. data/lib/active_support/cache/strategy/local_cache.rb +194 -0
  19. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  20. data/lib/active_support/callbacks.rb +856 -0
  21. data/lib/active_support/concern.rb +171 -0
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  23. data/lib/active_support/concurrency/share_lock.rb +227 -0
  24. data/lib/active_support/configurable.rb +146 -0
  25. data/lib/active_support/core_ext.rb +5 -0
  26. data/lib/active_support/core_ext/array.rb +9 -0
  27. data/lib/active_support/core_ext/array/access.rb +104 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +213 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
  34. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  35. data/lib/active_support/core_ext/benchmark.rb +16 -0
  36. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  37. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  38. data/lib/active_support/core_ext/class.rb +4 -0
  39. data/lib/active_support/core_ext/class/attribute.rb +141 -0
  40. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  41. data/lib/active_support/core_ext/class/subclasses.rb +54 -0
  42. data/lib/active_support/core_ext/date.rb +7 -0
  43. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  44. data/lib/active_support/core_ext/date/blank.rb +14 -0
  45. data/lib/active_support/core_ext/date/calculations.rb +146 -0
  46. data/lib/active_support/core_ext/date/conversions.rb +96 -0
  47. data/lib/active_support/core_ext/date/zones.rb +8 -0
  48. data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
  49. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  50. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  51. data/lib/active_support/core_ext/date_time.rb +7 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
  57. data/lib/active_support/core_ext/digest.rb +3 -0
  58. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  59. data/lib/active_support/core_ext/enumerable.rb +188 -0
  60. data/lib/active_support/core_ext/file.rb +3 -0
  61. data/lib/active_support/core_ext/file/atomic.rb +70 -0
  62. data/lib/active_support/core_ext/hash.rb +10 -0
  63. data/lib/active_support/core_ext/hash/compact.rb +5 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +263 -0
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +24 -0
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
  69. data/lib/active_support/core_ext/hash/keys.rb +143 -0
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  71. data/lib/active_support/core_ext/hash/slice.rb +26 -0
  72. data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
  73. data/lib/active_support/core_ext/integer.rb +5 -0
  74. data/lib/active_support/core_ext/integer/inflections.rb +31 -0
  75. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  76. data/lib/active_support/core_ext/integer/time.rb +22 -0
  77. data/lib/active_support/core_ext/kernel.rb +5 -0
  78. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  79. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  80. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  81. data/lib/active_support/core_ext/load_error.rb +9 -0
  82. data/lib/active_support/core_ext/marshal.rb +24 -0
  83. data/lib/active_support/core_ext/module.rb +13 -0
  84. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  85. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  86. data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
  87. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  88. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  89. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  90. data/lib/active_support/core_ext/module/delegation.rb +313 -0
  91. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  92. data/lib/active_support/core_ext/module/introspection.rb +86 -0
  93. data/lib/active_support/core_ext/module/reachable.rb +6 -0
  94. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  95. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  96. data/lib/active_support/core_ext/name_error.rb +38 -0
  97. data/lib/active_support/core_ext/numeric.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
  99. data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
  100. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  101. data/lib/active_support/core_ext/numeric/time.rb +66 -0
  102. data/lib/active_support/core_ext/object.rb +16 -0
  103. data/lib/active_support/core_ext/object/acts_like.rb +21 -0
  104. data/lib/active_support/core_ext/object/blank.rb +155 -0
  105. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  106. data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
  107. data/lib/active_support/core_ext/object/duplicable.rb +49 -0
  108. data/lib/active_support/core_ext/object/inclusion.rb +29 -0
  109. data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
  110. data/lib/active_support/core_ext/object/json.rb +228 -0
  111. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  112. data/lib/active_support/core_ext/object/to_query.rb +89 -0
  113. data/lib/active_support/core_ext/object/try.rb +156 -0
  114. data/lib/active_support/core_ext/object/with_options.rb +82 -0
  115. data/lib/active_support/core_ext/range.rb +7 -0
  116. data/lib/active_support/core_ext/range/compare_range.rb +70 -0
  117. data/lib/active_support/core_ext/range/conversions.rb +41 -0
  118. data/lib/active_support/core_ext/range/each.rb +25 -0
  119. data/lib/active_support/core_ext/range/include_range.rb +9 -0
  120. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  121. data/lib/active_support/core_ext/range/overlaps.rb +10 -0
  122. data/lib/active_support/core_ext/regexp.rb +7 -0
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string.rb +15 -0
  125. data/lib/active_support/core_ext/string/access.rb +114 -0
  126. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  127. data/lib/active_support/core_ext/string/conversions.rb +59 -0
  128. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  129. data/lib/active_support/core_ext/string/filters.rb +145 -0
  130. data/lib/active_support/core_ext/string/indent.rb +45 -0
  131. data/lib/active_support/core_ext/string/inflections.rb +259 -0
  132. data/lib/active_support/core_ext/string/inquiry.rb +15 -0
  133. data/lib/active_support/core_ext/string/multibyte.rb +58 -0
  134. data/lib/active_support/core_ext/string/output_safety.rb +314 -0
  135. data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
  136. data/lib/active_support/core_ext/string/strip.rb +27 -0
  137. data/lib/active_support/core_ext/string/zones.rb +16 -0
  138. data/lib/active_support/core_ext/time.rb +7 -0
  139. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  140. data/lib/active_support/core_ext/time/calculations.rb +344 -0
  141. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  142. data/lib/active_support/core_ext/time/conversions.rb +72 -0
  143. data/lib/active_support/core_ext/time/zones.rb +113 -0
  144. data/lib/active_support/core_ext/uri.rb +25 -0
  145. data/lib/active_support/current_attributes.rb +203 -0
  146. data/lib/active_support/dependencies.rb +806 -0
  147. data/lib/active_support/dependencies/autoload.rb +79 -0
  148. data/lib/active_support/dependencies/interlock.rb +57 -0
  149. data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
  150. data/lib/active_support/deprecation.rb +46 -0
  151. data/lib/active_support/deprecation/behaviors.rb +109 -0
  152. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  153. data/lib/active_support/deprecation/instance_delegator.rb +39 -0
  154. data/lib/active_support/deprecation/method_wrappers.rb +78 -0
  155. data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
  156. data/lib/active_support/deprecation/reporting.rb +114 -0
  157. data/lib/active_support/descendants_tracker.rb +109 -0
  158. data/lib/active_support/digest.rb +20 -0
  159. data/lib/active_support/duration.rb +433 -0
  160. data/lib/active_support/duration/iso8601_parser.rb +124 -0
  161. data/lib/active_support/duration/iso8601_serializer.rb +54 -0
  162. data/lib/active_support/encrypted_configuration.rb +45 -0
  163. data/lib/active_support/encrypted_file.rb +100 -0
  164. data/lib/active_support/evented_file_update_checker.rb +235 -0
  165. data/lib/active_support/execution_wrapper.rb +129 -0
  166. data/lib/active_support/executor.rb +8 -0
  167. data/lib/active_support/file_update_checker.rb +163 -0
  168. data/lib/active_support/gem_version.rb +17 -0
  169. data/lib/active_support/gzip.rb +38 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +399 -0
  171. data/lib/active_support/i18n.rb +16 -0
  172. data/lib/active_support/i18n_railtie.rb +126 -0
  173. data/lib/active_support/inflections.rb +72 -0
  174. data/lib/active_support/inflector.rb +9 -0
  175. data/lib/active_support/inflector/inflections.rb +257 -0
  176. data/lib/active_support/inflector/methods.rb +398 -0
  177. data/lib/active_support/inflector/transliterate.rb +147 -0
  178. data/lib/active_support/json.rb +4 -0
  179. data/lib/active_support/json/decoding.rb +76 -0
  180. data/lib/active_support/json/encoding.rb +134 -0
  181. data/lib/active_support/key_generator.rb +41 -0
  182. data/lib/active_support/lazy_load_hooks.rb +82 -0
  183. data/lib/active_support/locale/en.rb +31 -0
  184. data/lib/active_support/locale/en.yml +135 -0
  185. data/lib/active_support/log_subscriber.rb +135 -0
  186. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  187. data/lib/active_support/logger.rb +93 -0
  188. data/lib/active_support/logger_silence.rb +45 -0
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -0
  190. data/lib/active_support/message_encryptor.rb +227 -0
  191. data/lib/active_support/message_verifier.rb +205 -0
  192. data/lib/active_support/messages/metadata.rb +71 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  194. data/lib/active_support/messages/rotator.rb +56 -0
  195. data/lib/active_support/multibyte.rb +23 -0
  196. data/lib/active_support/multibyte/chars.rb +216 -0
  197. data/lib/active_support/multibyte/unicode.rb +157 -0
  198. data/lib/active_support/notifications.rb +253 -0
  199. data/lib/active_support/notifications/fanout.rb +244 -0
  200. data/lib/active_support/notifications/instrumenter.rb +164 -0
  201. data/lib/active_support/number_helper.rb +378 -0
  202. data/lib/active_support/number_helper/number_converter.rb +184 -0
  203. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  204. data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
  205. data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
  206. data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
  207. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  208. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  209. data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
  210. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  211. data/lib/active_support/option_merger.rb +27 -0
  212. data/lib/active_support/ordered_hash.rb +50 -0
  213. data/lib/active_support/ordered_options.rb +85 -0
  214. data/lib/active_support/parameter_filter.rb +129 -0
  215. data/lib/active_support/per_thread_registry.rb +60 -0
  216. data/lib/active_support/proxy_object.rb +15 -0
  217. data/lib/active_support/rails.rb +29 -0
  218. data/lib/active_support/railtie.rb +80 -0
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +174 -0
  221. data/lib/active_support/security_utils.rb +31 -0
  222. data/lib/active_support/string_inquirer.rb +34 -0
  223. data/lib/active_support/subscriber.rb +169 -0
  224. data/lib/active_support/tagged_logging.rb +88 -0
  225. data/lib/active_support/test_case.rb +163 -0
  226. data/lib/active_support/testing/assertions.rb +228 -0
  227. data/lib/active_support/testing/autorun.rb +7 -0
  228. data/lib/active_support/testing/constant_lookup.rb +51 -0
  229. data/lib/active_support/testing/declarative.rb +28 -0
  230. data/lib/active_support/testing/deprecation.rb +38 -0
  231. data/lib/active_support/testing/file_fixtures.rb +38 -0
  232. data/lib/active_support/testing/isolation.rb +110 -0
  233. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  234. data/lib/active_support/testing/parallelization.rb +128 -0
  235. data/lib/active_support/testing/setup_and_teardown.rb +55 -0
  236. data/lib/active_support/testing/stream.rb +44 -0
  237. data/lib/active_support/testing/tagged_logging.rb +27 -0
  238. data/lib/active_support/testing/time_helpers.rb +200 -0
  239. data/lib/active_support/time.rb +20 -0
  240. data/lib/active_support/time_with_zone.rb +561 -0
  241. data/lib/active_support/values/time_zone.rb +570 -0
  242. data/lib/active_support/version.rb +10 -0
  243. data/lib/active_support/xml_mini.rb +202 -0
  244. data/lib/active_support/xml_mini/jdom.rb +183 -0
  245. data/lib/active_support/xml_mini/libxml.rb +80 -0
  246. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  247. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  248. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  249. data/lib/active_support/xml_mini/rexml.rb +130 -0
  250. metadata +385 -0
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2019 David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ = Active Support -- Utility classes and Ruby extensions from Rails
2
+
3
+ Active Support is a collection of utility classes and standard library
4
+ extensions that were found useful for the Rails framework. These additions
5
+ reside in this package so they can be loaded as needed in Ruby projects
6
+ outside of Rails.
7
+
8
+ You can read more about the extensions in the {Active Support Core Extensions}[https://edgeguides.rubyonrails.org/active_support_core_extensions.html] guide.
9
+
10
+ == Download and installation
11
+
12
+ The latest version of Active Support can be installed with RubyGems:
13
+
14
+ $ gem install activesupport
15
+
16
+ Source code can be downloaded as part of the Rails project on GitHub:
17
+
18
+ * https://github.com/rails/rails/tree/master/activesupport
19
+
20
+
21
+ == License
22
+
23
+ Active Support is released under the MIT license:
24
+
25
+ * https://opensource.org/licenses/MIT
26
+
27
+
28
+ == Support
29
+
30
+ API documentation is at:
31
+
32
+ * https://api.rubyonrails.org
33
+
34
+ Bug reports for the Ruby on Rails project can be filed here:
35
+
36
+ * https://github.com/rails/rails/issues
37
+
38
+ Feature requests should be discussed on the rails-core mailing list here:
39
+
40
+ * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Copyright (c) 2005-2019 David Heinemeier Hansson
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+
26
+ require "securerandom"
27
+ require "active_support/dependencies/autoload"
28
+ require "active_support/version"
29
+ require "active_support/logger"
30
+ require "active_support/lazy_load_hooks"
31
+ require "active_support/core_ext/date_and_time/compatibility"
32
+
33
+ module ActiveSupport
34
+ extend ActiveSupport::Autoload
35
+
36
+ autoload :Concern
37
+ autoload :ActionableError
38
+ autoload :CurrentAttributes
39
+ autoload :Dependencies
40
+ autoload :DescendantsTracker
41
+ autoload :ExecutionWrapper
42
+ autoload :Executor
43
+ autoload :FileUpdateChecker
44
+ autoload :EventedFileUpdateChecker
45
+ autoload :LogSubscriber
46
+ autoload :Notifications
47
+ autoload :Reloader
48
+
49
+ eager_autoload do
50
+ autoload :BacktraceCleaner
51
+ autoload :ProxyObject
52
+ autoload :Benchmarkable
53
+ autoload :Cache
54
+ autoload :Callbacks
55
+ autoload :Configurable
56
+ autoload :Deprecation
57
+ autoload :Digest
58
+ autoload :Gzip
59
+ autoload :Inflector
60
+ autoload :JSON
61
+ autoload :KeyGenerator
62
+ autoload :MessageEncryptor
63
+ autoload :MessageVerifier
64
+ autoload :Multibyte
65
+ autoload :NumberHelper
66
+ autoload :OptionMerger
67
+ autoload :OrderedHash
68
+ autoload :OrderedOptions
69
+ autoload :StringInquirer
70
+ autoload :TaggedLogging
71
+ autoload :XmlMini
72
+ autoload :ArrayInquirer
73
+ end
74
+
75
+ autoload :Rescuable
76
+ autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
77
+ autoload :TestCase
78
+
79
+ def self.eager_load!
80
+ super
81
+
82
+ NumberHelper.eager_load!
83
+ end
84
+
85
+ cattr_accessor :test_order # :nodoc:
86
+
87
+ def self.to_time_preserves_timezone
88
+ DateAndTime::Compatibility.preserve_timezone
89
+ end
90
+
91
+ def self.to_time_preserves_timezone=(value)
92
+ DateAndTime::Compatibility.preserve_timezone = value
93
+ end
94
+ end
95
+
96
+ autoload :I18n, "active_support/i18n"
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Actionable errors let's you define actions to resolve an error.
5
+ #
6
+ # To make an error actionable, include the <tt>ActiveSupport::ActionableError</tt>
7
+ # module and invoke the +action+ class macro to define the action. An action
8
+ # needs a name and a block to execute.
9
+ module ActionableError
10
+ extend Concern
11
+
12
+ class NonActionable < StandardError; end
13
+
14
+ included do
15
+ class_attribute :_actions, default: {}
16
+ end
17
+
18
+ def self.actions(error) # :nodoc:
19
+ case error
20
+ when ActionableError, -> it { Class === it && it < ActionableError }
21
+ error._actions
22
+ else
23
+ {}
24
+ end
25
+ end
26
+
27
+ def self.dispatch(error, name) # :nodoc:
28
+ actions(error).fetch(name).call
29
+ rescue KeyError
30
+ raise NonActionable, "Cannot find action \"#{name}\""
31
+ end
32
+
33
+ module ClassMethods
34
+ # Defines an action that can resolve the error.
35
+ #
36
+ # class PendingMigrationError < MigrationError
37
+ # include ActiveSupport::ActionableError
38
+ #
39
+ # action "Run pending migrations" do
40
+ # ActiveRecord::Tasks::DatabaseTasks.migrate
41
+ # end
42
+ # end
43
+ def action(name, &block)
44
+ _actions[name] = block
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/time"
5
+ require "active_support/core_ext"
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Wrapping an array in an +ArrayInquirer+ gives a friendlier way to check
5
+ # its string-like contents:
6
+ #
7
+ # variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
8
+ #
9
+ # variants.phone? # => true
10
+ # variants.tablet? # => true
11
+ # variants.desktop? # => false
12
+ class ArrayInquirer < Array
13
+ # Passes each element of +candidates+ collection to ArrayInquirer collection.
14
+ # The method returns true if any element from the ArrayInquirer collection
15
+ # is equal to the stringified or symbolized form of any element in the +candidates+ collection.
16
+ #
17
+ # If +candidates+ collection is not given, method returns true.
18
+ #
19
+ # variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
20
+ #
21
+ # variants.any? # => true
22
+ # variants.any?(:phone, :tablet) # => true
23
+ # variants.any?('phone', 'desktop') # => true
24
+ # variants.any?(:desktop, :watch) # => false
25
+ def any?(*candidates)
26
+ if candidates.none?
27
+ super
28
+ else
29
+ candidates.any? do |candidate|
30
+ include?(candidate.to_sym) || include?(candidate.to_s)
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+ def respond_to_missing?(name, include_private = false)
37
+ (name[-1] == "?") || super
38
+ end
39
+
40
+ def method_missing(name, *args)
41
+ if name[-1] == "?"
42
+ any?(name[0..-2])
43
+ else
44
+ super
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Backtraces often include many lines that are not relevant for the context
5
+ # under review. This makes it hard to find the signal amongst the backtrace
6
+ # noise, and adds debugging time. With a BacktraceCleaner, filters and
7
+ # silencers are used to remove the noisy lines, so that only the most relevant
8
+ # lines remain.
9
+ #
10
+ # Filters are used to modify lines of data, while silencers are used to remove
11
+ # lines entirely. The typical filter use case is to remove lengthy path
12
+ # information from the start of each line, and view file paths relevant to the
13
+ # app directory instead of the file system root. The typical silencer use case
14
+ # is to exclude the output of a noisy library from the backtrace, so that you
15
+ # can focus on the rest.
16
+ #
17
+ # bc = ActiveSupport::BacktraceCleaner.new
18
+ # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
19
+ # bc.add_silencer { |line| line =~ /puma|rubygems/ } # skip any lines from puma or rubygems
20
+ # bc.clean(exception.backtrace) # perform the cleanup
21
+ #
22
+ # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
23
+ # and show as much data as possible, you can always call
24
+ # <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
25
+ # backtrace to a pristine state. If you need to reconfigure an existing
26
+ # BacktraceCleaner so that it does not filter or modify the paths of any lines
27
+ # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
28
+ # These two methods will give you a completely untouched backtrace.
29
+ #
30
+ # Inspired by the Quiet Backtrace gem by thoughtbot.
31
+ class BacktraceCleaner
32
+ def initialize
33
+ @filters, @silencers = [], []
34
+ add_gem_filter
35
+ add_gem_silencer
36
+ add_stdlib_silencer
37
+ end
38
+
39
+ # Returns the backtrace after all filters and silencers have been run
40
+ # against it. Filters run first, then silencers.
41
+ def clean(backtrace, kind = :silent)
42
+ filtered = filter_backtrace(backtrace)
43
+
44
+ case kind
45
+ when :silent
46
+ silence(filtered)
47
+ when :noise
48
+ noise(filtered)
49
+ else
50
+ filtered
51
+ end
52
+ end
53
+ alias :filter :clean
54
+
55
+ # Adds a filter from the block provided. Each line in the backtrace will be
56
+ # mapped against this filter.
57
+ #
58
+ # # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
59
+ # backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
60
+ def add_filter(&block)
61
+ @filters << block
62
+ end
63
+
64
+ # Adds a silencer from the block provided. If the silencer returns +true+
65
+ # for a given line, it will be excluded from the clean backtrace.
66
+ #
67
+ # # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb"
68
+ # backtrace_cleaner.add_silencer { |line| line =~ /puma/ }
69
+ def add_silencer(&block)
70
+ @silencers << block
71
+ end
72
+
73
+ # Removes all silencers, but leaves in the filters. Useful if your
74
+ # context of debugging suddenly expands as you suspect a bug in one of
75
+ # the libraries you use.
76
+ def remove_silencers!
77
+ @silencers = []
78
+ end
79
+
80
+ # Removes all filters, but leaves in the silencers. Useful if you suddenly
81
+ # need to see entire filepaths in the backtrace that you had already
82
+ # filtered out.
83
+ def remove_filters!
84
+ @filters = []
85
+ end
86
+
87
+ private
88
+
89
+ FORMATTED_GEMS_PATTERN = /\A[^\/]+ \([\w.]+\) /
90
+
91
+ def add_gem_filter
92
+ gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
93
+ return if gems_paths.empty?
94
+
95
+ gems_regexp = %r{(#{gems_paths.join('|')})/(bundler/)?gems/([^/]+)-([\w.]+)/(.*)}
96
+ gems_result = '\3 (\4) \5'
97
+ add_filter { |line| line.sub(gems_regexp, gems_result) }
98
+ end
99
+
100
+ def add_gem_silencer
101
+ add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) }
102
+ end
103
+
104
+ def add_stdlib_silencer
105
+ add_silencer { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) }
106
+ end
107
+
108
+ def filter_backtrace(backtrace)
109
+ @filters.each do |f|
110
+ backtrace = backtrace.map { |line| f.call(line) }
111
+ end
112
+
113
+ backtrace
114
+ end
115
+
116
+ def silence(backtrace)
117
+ @silencers.each do |s|
118
+ backtrace = backtrace.reject { |line| s.call(line) }
119
+ end
120
+
121
+ backtrace
122
+ end
123
+
124
+ def noise(backtrace)
125
+ backtrace.select do |line|
126
+ @silencers.any? do |s|
127
+ s.call(line)
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/benchmark"
4
+ require "active_support/core_ext/hash/keys"
5
+
6
+ module ActiveSupport
7
+ module Benchmarkable
8
+ # Allows you to measure the execution time of a block in a template and
9
+ # records the result to the log. Wrap this block around expensive operations
10
+ # or possible bottlenecks to get a time reading for the operation. For
11
+ # example, let's say you thought your file processing method was taking too
12
+ # long; you could wrap it in a benchmark block.
13
+ #
14
+ # <% benchmark 'Process data files' do %>
15
+ # <%= expensive_files_operation %>
16
+ # <% end %>
17
+ #
18
+ # That would add something like "Process data files (345.2ms)" to the log,
19
+ # which you can then use to compare timings when optimizing your code.
20
+ #
21
+ # You may give an optional logger level (<tt>:debug</tt>, <tt>:info</tt>,
22
+ # <tt>:warn</tt>, <tt>:error</tt>) as the <tt>:level</tt> option. The
23
+ # default logger level value is <tt>:info</tt>.
24
+ #
25
+ # <% benchmark 'Low-level files', level: :debug do %>
26
+ # <%= lowlevel_files_operation %>
27
+ # <% end %>
28
+ #
29
+ # Finally, you can pass true as the third argument to silence all log
30
+ # activity (other than the timing information) from inside the block. This
31
+ # is great for boiling down a noisy block to just a single statement that
32
+ # produces one log line:
33
+ #
34
+ # <% benchmark 'Process data files', level: :info, silence: true do %>
35
+ # <%= expensive_and_chatty_files_operation %>
36
+ # <% end %>
37
+ def benchmark(message = "Benchmarking", options = {})
38
+ if logger
39
+ options.assert_valid_keys(:level, :silence)
40
+ options[:level] ||= :info
41
+
42
+ result = nil
43
+ ms = Benchmark.ms { result = options[:silence] ? logger.silence { yield } : yield }
44
+ logger.send(options[:level], "%s (%.1fms)" % [ message, ms ])
45
+ result
46
+ else
47
+ yield
48
+ end
49
+ end
50
+ end
51
+ end