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,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveSupport.deprecator.warn <<~MSG
4
+ ActiveSupport::Configurable is deprecated without replacement, and will be removed in Rails 8.2.
5
+
6
+ You can emulate the previous behavior with `class_attribute`.
7
+ MSG
8
+
9
+ require "active_support/concern"
10
+ require "active_support/ordered_options"
11
+
12
+ module ActiveSupport
13
+ # = Active Support \Configurable
14
+ #
15
+ # Configurable provides a <tt>config</tt> method to store and retrieve
16
+ # configuration options as an OrderedOptions.
17
+ module Configurable
18
+ extend ActiveSupport::Concern
19
+
20
+ class Configuration < ActiveSupport::InheritableOptions
21
+ def compile_methods!
22
+ self.class.compile_methods!(keys)
23
+ end
24
+
25
+ # Compiles reader methods so we don't have to go through method_missing.
26
+ def self.compile_methods!(keys)
27
+ keys.reject { |m| method_defined?(m) }.each do |key|
28
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
29
+ def #{key}; _get(#{key.inspect}); end
30
+ RUBY
31
+ end
32
+ end
33
+ end
34
+
35
+ module ClassMethods
36
+ # Reads and writes attributes from a configuration OrderedOptions.
37
+ #
38
+ # require "active_support/configurable"
39
+ #
40
+ # class User
41
+ # include ActiveSupport::Configurable
42
+ # end
43
+ #
44
+ # User.config.allowed_access = true
45
+ # User.config.level = 1
46
+ #
47
+ # User.config.allowed_access # => true
48
+ # User.config.level # => 1
49
+ def config
50
+ @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
51
+ superclass.config.inheritable_copy
52
+ else
53
+ # create a new "anonymous" class that will host the compiled reader methods
54
+ Class.new(Configuration).new
55
+ end
56
+ end
57
+
58
+ # Configure values from within the passed block.
59
+ #
60
+ # require "active_support/configurable"
61
+ #
62
+ # class User
63
+ # include ActiveSupport::Configurable
64
+ # end
65
+ #
66
+ # User.allowed_access # => nil
67
+ #
68
+ # User.configure do |config|
69
+ # config.allowed_access = true
70
+ # end
71
+ #
72
+ # User.allowed_access # => true
73
+ def configure
74
+ yield config
75
+ end
76
+
77
+ # Allows you to add shortcut so that you don't have to refer to attribute
78
+ # through config. Also look at the example for config to contrast.
79
+ #
80
+ # Defines both class and instance config accessors.
81
+ #
82
+ # class User
83
+ # include ActiveSupport::Configurable
84
+ # config_accessor :allowed_access
85
+ # end
86
+ #
87
+ # User.allowed_access # => nil
88
+ # User.allowed_access = false
89
+ # User.allowed_access # => false
90
+ #
91
+ # user = User.new
92
+ # user.allowed_access # => false
93
+ # user.allowed_access = true
94
+ # user.allowed_access # => true
95
+ #
96
+ # User.allowed_access # => false
97
+ #
98
+ # The attribute name must be a valid method name in Ruby.
99
+ #
100
+ # class User
101
+ # include ActiveSupport::Configurable
102
+ # config_accessor :"1_Badname"
103
+ # end
104
+ # # => NameError: invalid config attribute name
105
+ #
106
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
107
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
108
+ #
109
+ # class User
110
+ # include ActiveSupport::Configurable
111
+ # config_accessor :allowed_access, instance_reader: false, instance_writer: false
112
+ # end
113
+ #
114
+ # User.allowed_access = false
115
+ # User.allowed_access # => false
116
+ #
117
+ # User.new.allowed_access = true # => NoMethodError
118
+ # User.new.allowed_access # => NoMethodError
119
+ #
120
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
121
+ #
122
+ # class User
123
+ # include ActiveSupport::Configurable
124
+ # config_accessor :allowed_access, instance_accessor: false
125
+ # end
126
+ #
127
+ # User.allowed_access = false
128
+ # User.allowed_access # => false
129
+ #
130
+ # User.new.allowed_access = true # => NoMethodError
131
+ # User.new.allowed_access # => NoMethodError
132
+ #
133
+ # Also you can pass <tt>default</tt> or a block to set up the attribute with a default value.
134
+ #
135
+ # class User
136
+ # include ActiveSupport::Configurable
137
+ # config_accessor :allowed_access, default: false
138
+ # config_accessor :hair_colors do
139
+ # [:brown, :black, :blonde, :red]
140
+ # end
141
+ # end
142
+ #
143
+ # User.allowed_access # => false
144
+ # User.hair_colors # => [:brown, :black, :blonde, :red]
145
+ def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc:
146
+ names.each do |name|
147
+ raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
148
+
149
+ reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
150
+ writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
151
+
152
+ singleton_class.class_eval reader, __FILE__, reader_line
153
+ singleton_class.class_eval writer, __FILE__, writer_line
154
+
155
+ if instance_accessor
156
+ class_eval reader, __FILE__, reader_line if instance_reader
157
+ class_eval writer, __FILE__, writer_line if instance_writer
158
+ end
159
+
160
+ send("#{name}=", block_given? ? yield : default)
161
+ end
162
+ end
163
+ private :config_accessor
164
+
165
+ private
166
+ def inherited(subclass)
167
+ super
168
+ subclass.class_eval do
169
+ @_config = nil
170
+ end
171
+ end
172
+ end
173
+
174
+ # Reads and writes attributes from a configuration OrderedOptions.
175
+ #
176
+ # require "active_support/configurable"
177
+ #
178
+ # class User
179
+ # include ActiveSupport::Configurable
180
+ # end
181
+ #
182
+ # user = User.new
183
+ #
184
+ # user.config.allowed_access = true
185
+ # user.config.level = 1
186
+ #
187
+ # user.config.allowed_access # => true
188
+ # user.config.level # => 1
189
+ def config
190
+ @_config ||= self.class.config.inheritable_copy
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Reads a YAML configuration file, evaluating any ERB, then
5
+ # parsing the resulting YAML.
6
+ #
7
+ # Warns in case of YAML confusing characters, like invisible
8
+ # non-breaking spaces.
9
+ class ConfigurationFile # :nodoc:
10
+ class FormatError < StandardError; end
11
+
12
+ def initialize(content_path)
13
+ @content_path = content_path.to_s
14
+ @content = read content_path
15
+ end
16
+
17
+ def self.parse(content_path, **options)
18
+ new(content_path).parse(**options)
19
+ end
20
+
21
+ def parse(context: nil, **options)
22
+ source = @content.include?("<%") ? render(context) : @content
23
+
24
+ if source == @content
25
+ if YAML.respond_to?(:unsafe_load)
26
+ YAML.unsafe_load_file(@content_path, **options) || {}
27
+ else
28
+ YAML.load_file(@content_path, **options) || {}
29
+ end
30
+ else
31
+ if YAML.respond_to?(:unsafe_load)
32
+ YAML.unsafe_load(source, **options) || {}
33
+ else
34
+ YAML.load(source, **options) || {}
35
+ end
36
+ end
37
+ rescue Psych::SyntaxError => error
38
+ raise "YAML syntax error occurred while parsing #{@content_path}. " \
39
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
40
+ "Error: #{error.message}"
41
+ end
42
+
43
+ private
44
+ def read(content_path)
45
+ require "yaml" unless defined?(YAML)
46
+
47
+ File.read(content_path).tap do |content|
48
+ if content.include?("\u00A0")
49
+ warn "#{content_path} contains invisible non-breaking spaces, you may want to remove those"
50
+ end
51
+ end
52
+ end
53
+
54
+ def render(context)
55
+ require "erb" unless defined?(ERB)
56
+ erb = ERB.new(@content).tap { |e| e.filename = @content_path }
57
+ context ? erb.result(context) : erb.result
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Provides a DSL for declaring a continuous integration workflow that can be run either locally or in the cloud.
5
+ # Each step is timed, reports success/error, and is aggregated into a collective report that reports total runtime,
6
+ # as well as whether the entire run was successful or not.
7
+ #
8
+ # Example:
9
+ #
10
+ # ActiveSupport::ContinuousIntegration.run do
11
+ # step "Setup", "bin/setup --skip-server"
12
+ # step "Style: Ruby", "bin/rubocop"
13
+ # step "Security: Gem audit", "bin/bundler-audit"
14
+ # step "Tests: Rails", "bin/rails test test:system"
15
+ #
16
+ # if success?
17
+ # step "Signoff: Ready for merge and deploy", "gh signoff"
18
+ # else
19
+ # failure "Skipping signoff; CI failed.", "Fix the issues and try again."
20
+ # end
21
+ # end
22
+ #
23
+ # Starting with Rails 8.1, a default `bin/ci` and `config/ci.rb` file are created to provide out-of-the-box CI.
24
+ class ContinuousIntegration
25
+ COLORS = {
26
+ banner: "\033[1;32m", # Green
27
+ title: "\033[1;35m", # Purple
28
+ subtitle: "\033[1;90m", # Medium Gray
29
+ error: "\033[1;31m", # Red
30
+ success: "\033[1;32m" # Green
31
+ }
32
+
33
+ attr_reader :results
34
+
35
+ # Perform a CI run. Execute each step, show their results and runtime, and exit with a non-zero status if there are any failures.
36
+ #
37
+ # Pass an optional title, subtitle, and a block that declares the steps to be executed.
38
+ #
39
+ # Sets the CI environment variable to "true" to allow for conditional behavior in the app, like enabling eager loading and disabling logging.
40
+ #
41
+ # Example:
42
+ #
43
+ # ActiveSupport::ContinuousIntegration.run do
44
+ # step "Setup", "bin/setup --skip-server"
45
+ # step "Style: Ruby", "bin/rubocop"
46
+ # step "Security: Gem audit", "bin/bundler-audit"
47
+ # step "Tests: Rails", "bin/rails test test:system"
48
+ #
49
+ # if success?
50
+ # step "Signoff: Ready for merge and deploy", "gh signoff"
51
+ # else
52
+ # failure "Skipping signoff; CI failed.", "Fix the issues and try again."
53
+ # end
54
+ # end
55
+ def self.run(title = "Continuous Integration", subtitle = "Running tests, style checks, and security audits", &block)
56
+ new.tap do |ci|
57
+ ENV["CI"] = "true"
58
+ ci.heading title, subtitle, padding: false
59
+ ci.report(title, &block)
60
+ abort unless ci.success?
61
+ end
62
+ end
63
+
64
+ def initialize
65
+ @results = []
66
+ end
67
+
68
+ # Declare a step with a title and a command. The command can either be given as a single string or as multiple
69
+ # strings that will be passed to `system` as individual arguments (and therefore correctly escaped for paths etc).
70
+ #
71
+ # Examples:
72
+ #
73
+ # step "Setup", "bin/setup"
74
+ # step "Single test", "bin/rails", "test", "--name", "test_that_is_one"
75
+ def step(title, *command)
76
+ heading title, command.join(" "), type: :title
77
+ report(title) { results << system(*command) }
78
+ end
79
+
80
+ # Returns true if all steps were successful.
81
+ def success?
82
+ results.all?
83
+ end
84
+
85
+ # Display an error heading with the title and optional subtitle to reflect that the run failed.
86
+ def failure(title, subtitle = nil)
87
+ heading title, subtitle, type: :error
88
+ end
89
+
90
+ # Display a colorized heading followed by an optional subtitle.
91
+ #
92
+ # Examples:
93
+ #
94
+ # heading "Smoke Testing", "End-to-end tests verifying key functionality", padding: false
95
+ # heading "Skipping video encoding tests", "Install FFmpeg to run these tests", type: :error
96
+ #
97
+ # See ActiveSupport::ContinuousIntegration::COLORS for a complete list of options.
98
+ def heading(heading, subtitle = nil, type: :banner, padding: true)
99
+ echo "#{padding ? "\n\n" : ""}#{heading}", type: type
100
+ echo "#{subtitle}#{padding ? "\n" : ""}", type: :subtitle if subtitle
101
+ end
102
+
103
+ # Echo text to the terminal in the color corresponding to the type of the text.
104
+ #
105
+ # Examples:
106
+ #
107
+ # echo "This is going to be green!", type: :success
108
+ # echo "This is going to be red!", type: :error
109
+ #
110
+ # See ActiveSupport::ContinuousIntegration::COLORS for a complete list of options.
111
+ def echo(text, type:)
112
+ puts colorize(text, type)
113
+ end
114
+
115
+ # :nodoc:
116
+ def report(title, &block)
117
+ Signal.trap("INT") { abort colorize(:error, "\n❌ #{title} interrupted") }
118
+
119
+ ci = self.class.new
120
+ elapsed = timing { ci.instance_eval(&block) }
121
+
122
+ if ci.success?
123
+ echo "\n✅ #{title} passed in #{elapsed}", type: :success
124
+ else
125
+ echo "\n❌ #{title} failed in #{elapsed}", type: :error
126
+ end
127
+
128
+ results.concat ci.results
129
+ ensure
130
+ Signal.trap("INT", "-")
131
+ end
132
+
133
+ private
134
+ def timing
135
+ started_at = Time.now.to_f
136
+ yield
137
+ min, sec = (Time.now.to_f - started_at).divmod(60)
138
+ "#{"#{min}m" if min > 0}%.2fs" % sec
139
+ end
140
+
141
+ def colorize(text, type)
142
+ "#{COLORS.fetch(type)}#{text}\033[0m"
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Returns the tail of the array from +position+.
5
+ #
6
+ # %w( a b c d ).from(0) # => ["a", "b", "c", "d"]
7
+ # %w( a b c d ).from(2) # => ["c", "d"]
8
+ # %w( a b c d ).from(10) # => []
9
+ # %w().from(0) # => []
10
+ # %w( a b c d ).from(-2) # => ["c", "d"]
11
+ # %w( a b c ).from(-10) # => []
12
+ def from(position)
13
+ self[position, length] || []
14
+ end
15
+
16
+ # Returns the beginning of the array up to +position+.
17
+ #
18
+ # %w( a b c d ).to(0) # => ["a"]
19
+ # %w( a b c d ).to(2) # => ["a", "b", "c"]
20
+ # %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
21
+ # %w().to(0) # => []
22
+ # %w( a b c d ).to(-2) # => ["a", "b", "c"]
23
+ # %w( a b c ).to(-10) # => []
24
+ def to(position)
25
+ if position >= 0
26
+ take position + 1
27
+ else
28
+ self[0..position]
29
+ end
30
+ end
31
+
32
+ # Returns a new array that includes the passed elements.
33
+ #
34
+ # [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
35
+ # [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
36
+ def including(*elements)
37
+ self + elements.flatten(1)
38
+ end
39
+
40
+ # Returns a copy of the Array excluding the specified elements.
41
+ #
42
+ # ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
43
+ # [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
44
+ #
45
+ # Note: This is an optimization of <tt>Enumerable#excluding</tt> that uses <tt>Array#-</tt>
46
+ # instead of <tt>Array#reject</tt> for performance reasons.
47
+ def excluding(*elements)
48
+ self - elements.flatten(1)
49
+ end
50
+ alias :without :excluding
51
+
52
+ # Equal to <tt>self[1]</tt>.
53
+ #
54
+ # %w( a b c d e ).second # => "b"
55
+ def second
56
+ self[1]
57
+ end
58
+
59
+ # Equal to <tt>self[2]</tt>.
60
+ #
61
+ # %w( a b c d e ).third # => "c"
62
+ def third
63
+ self[2]
64
+ end
65
+
66
+ # Equal to <tt>self[3]</tt>.
67
+ #
68
+ # %w( a b c d e ).fourth # => "d"
69
+ def fourth
70
+ self[3]
71
+ end
72
+
73
+ # Equal to <tt>self[4]</tt>.
74
+ #
75
+ # %w( a b c d e ).fifth # => "e"
76
+ def fifth
77
+ self[4]
78
+ end
79
+
80
+ # Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
81
+ #
82
+ # (1..42).to_a.forty_two # => 42
83
+ def forty_two
84
+ self[41]
85
+ end
86
+
87
+ # Equal to <tt>self[-3]</tt>.
88
+ #
89
+ # %w( a b c d e ).third_to_last # => "c"
90
+ def third_to_last
91
+ self[-3]
92
+ end
93
+
94
+ # Equal to <tt>self[-2]</tt>.
95
+ #
96
+ # %w( a b c d e ).second_to_last # => "d"
97
+ def second_to_last
98
+ self[-2]
99
+ end
100
+ end