activesupport 5.1.1 → 6.1.1

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 (262) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -442
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -4
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +65 -53
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +68 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +305 -127
  19. data/lib/active_support/callbacks.rb +106 -98
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +46 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -1
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +6 -101
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +7 -2
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +76 -20
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +73 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +208 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  146. data/lib/active_support/dependencies.rb +135 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +30 -15
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +20 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +179 -41
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +84 -117
  164. data/lib/active_support/execution_wrapper.rb +3 -0
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +62 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +134 -37
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +20 -11
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +33 -10
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  186. data/lib/active_support/log_subscriber.rb +46 -13
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +101 -33
  191. data/lib/active_support/message_verifier.rb +85 -14
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +8 -7
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +16 -53
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +41 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +3 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +11 -10
  220. data/lib/active_support/rescuable.rb +7 -6
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -4
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +8 -4
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +55 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +81 -35
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
  require "pathname"
3
5
  require "concurrent/atomic/atomic_boolean"
6
+ require "listen"
7
+ require "active_support/fork_tracker"
4
8
 
5
9
  module ActiveSupport
6
10
  # Allows you to "listen" to changes in a file system.
@@ -36,48 +40,22 @@ module ActiveSupport
36
40
  raise ArgumentError, "A block is required to initialize an EventedFileUpdateChecker"
37
41
  end
38
42
 
39
- @ph = PathHelper.new
40
- @files = files.map { |f| @ph.xpath(f) }.to_set
41
-
42
- @dirs = {}
43
- dirs.each do |dir, exts|
44
- @dirs[@ph.xpath(dir)] = Array(exts).map { |ext| @ph.normalize_extension(ext) }
45
- end
46
-
47
- @block = block
48
- @updated = Concurrent::AtomicBoolean.new(false)
49
- @lcsp = @ph.longest_common_subpath(@dirs.keys)
50
- @pid = Process.pid
51
- @boot_mutex = Mutex.new
52
-
53
- if (@dtw = directories_to_watch).any?
54
- # Loading listen triggers warnings. These are originated by a legit
55
- # usage of attr_* macros for private attributes, but adds a lot of noise
56
- # to our test suite. Thus, we lazy load it and disable warnings locally.
57
- silence_warnings do
58
- begin
59
- require "listen"
60
- rescue LoadError => e
61
- raise LoadError, "Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile", e.backtrace
62
- end
63
- end
64
- end
65
- boot!
43
+ @block = block
44
+ @core = Core.new(files, dirs)
45
+ ObjectSpace.define_finalizer(self, @core.finalizer)
66
46
  end
67
47
 
68
48
  def updated?
69
- @boot_mutex.synchronize do
70
- if @pid != Process.pid
71
- boot!
72
- @pid = Process.pid
73
- @updated.make_true
74
- end
49
+ if @core.restart?
50
+ @core.thread_safely(&:restart)
51
+ @core.updated.make_true
75
52
  end
76
- @updated.true?
53
+
54
+ @core.updated.true?
77
55
  end
78
56
 
79
57
  def execute
80
- @updated.make_false
58
+ @core.updated.make_false
81
59
  @block.call
82
60
  end
83
61
 
@@ -89,115 +67,104 @@ module ActiveSupport
89
67
  end
90
68
  end
91
69
 
92
- private
93
- def boot!
94
- Listen.to(*@dtw, &method(:changed)).start
95
- end
70
+ class Core
71
+ attr_reader :updated
96
72
 
97
- def changed(modified, added, removed)
98
- unless updated?
99
- @updated.make_true if (modified + added + removed).any? { |f| watching?(f) }
73
+ def initialize(files, dirs)
74
+ @files = files.map { |file| Pathname(file).expand_path }.to_set
75
+
76
+ @dirs = dirs.each_with_object({}) do |(dir, exts), hash|
77
+ hash[Pathname(dir).expand_path] = Array(exts).map { |ext| ext.to_s.sub(/\A\.?/, ".") }.to_set
100
78
  end
101
- end
102
79
 
103
- def watching?(file)
104
- file = @ph.xpath(file)
80
+ @common_path = common_path(@dirs.keys)
105
81
 
106
- if @files.member?(file)
107
- true
108
- elsif file.directory?
109
- false
110
- else
111
- ext = @ph.normalize_extension(file.extname)
82
+ @dtw = directories_to_watch
83
+ @missing = []
112
84
 
113
- file.dirname.ascend do |dir|
114
- if @dirs.fetch(dir, []).include?(ext)
115
- break true
116
- elsif dir == @lcsp || dir.root?
117
- break false
118
- end
119
- end
120
- end
85
+ @updated = Concurrent::AtomicBoolean.new(false)
86
+ @mutex = Mutex.new
87
+
88
+ start
89
+ @after_fork = ActiveSupport::ForkTracker.after_fork { start }
121
90
  end
122
91
 
123
- def directories_to_watch
124
- dtw = (@files + @dirs.keys).map { |f| @ph.existing_parent(f) }
125
- dtw.compact!
126
- dtw.uniq!
92
+ def finalizer
93
+ proc do
94
+ stop
95
+ ActiveSupport::ForkTracker.unregister(@after_fork)
96
+ end
97
+ end
127
98
 
128
- normalized_gem_paths = Gem.path.map { |path| File.join path, "" }
129
- dtw = dtw.reject do |path|
130
- normalized_gem_paths.any? { |gem_path| path.to_s.start_with?(gem_path) }
99
+ def thread_safely
100
+ @mutex.synchronize do
101
+ yield self
131
102
  end
103
+ end
132
104
 
133
- @ph.filter_out_descendants(dtw)
105
+ def start
106
+ normalize_dirs!
107
+ @dtw, @missing = [*@dtw, *@missing].partition(&:exist?)
108
+ @listener = @dtw.any? ? Listen.to(*@dtw, &method(:changed)) : nil
109
+ @listener&.start
134
110
  end
135
111
 
136
- class PathHelper
137
- def xpath(path)
138
- Pathname.new(path).expand_path
139
- end
112
+ def stop
113
+ @listener&.stop
114
+ end
140
115
 
141
- def normalize_extension(ext)
142
- ext.to_s.sub(/\A\./, "")
143
- end
116
+ def restart
117
+ stop
118
+ start
119
+ end
144
120
 
145
- # Given a collection of Pathname objects returns the longest subpath
146
- # common to all of them, or +nil+ if there is none.
147
- def longest_common_subpath(paths)
148
- return if paths.empty?
149
-
150
- lcsp = Pathname.new(paths[0])
151
-
152
- paths[1..-1].each do |path|
153
- until ascendant_of?(lcsp, path)
154
- if lcsp.root?
155
- # If we get here a root directory is not an ascendant of path.
156
- # This may happen if there are paths in different drives on
157
- # Windows.
158
- return
159
- else
160
- lcsp = lcsp.parent
161
- end
162
- end
163
- end
121
+ def restart?
122
+ @missing.any?(&:exist?)
123
+ end
164
124
 
165
- lcsp
125
+ def normalize_dirs!
126
+ @dirs.transform_keys! do |dir|
127
+ dir.exist? ? dir.realpath : dir
166
128
  end
129
+ end
167
130
 
168
- # Returns the deepest existing ascendant, which could be the argument itself.
169
- def existing_parent(dir)
170
- dir.ascend do |ascendant|
171
- break ascendant if ascendant.directory?
172
- end
131
+ def changed(modified, added, removed)
132
+ unless @updated.true?
133
+ @updated.make_true if (modified + added + removed).any? { |f| watching?(f) }
173
134
  end
135
+ end
174
136
 
175
- # Filters out directories which are descendants of others in the collection (stable).
176
- def filter_out_descendants(dirs)
177
- return dirs if dirs.length < 2
137
+ def watching?(file)
138
+ file = Pathname(file)
178
139
 
179
- dirs_sorted_by_nparts = dirs.sort_by { |dir| dir.each_filename.to_a.length }
180
- descendants = []
140
+ if @files.member?(file)
141
+ true
142
+ elsif file.directory?
143
+ false
144
+ else
145
+ ext = file.extname
181
146
 
182
- until dirs_sorted_by_nparts.empty?
183
- dir = dirs_sorted_by_nparts.shift
147
+ file.dirname.ascend do |dir|
148
+ matching = @dirs[dir]
184
149
 
185
- dirs_sorted_by_nparts.reject! do |possible_descendant|
186
- ascendant_of?(dir, possible_descendant) && descendants << possible_descendant
150
+ if matching && (matching.empty? || matching.include?(ext))
151
+ break true
152
+ elsif dir == @common_path || dir.root?
153
+ break false
187
154
  end
188
155
  end
189
-
190
- # Array#- preserves order.
191
- dirs - descendants
192
156
  end
157
+ end
193
158
 
194
- private
159
+ def directories_to_watch
160
+ dtw = @dirs.keys | @files.map(&:dirname)
161
+ accounted_for = dtw.to_set + Gem.path.map { |path| Pathname(path) }
162
+ dtw.reject { |dir| dir.ascend.drop(1).any? { |parent| accounted_for.include?(parent) } }
163
+ end
195
164
 
196
- def ascendant_of?(base, other)
197
- base != other && other.ascend do |ascendant|
198
- break true if base == ascendant
199
- end
200
- end
165
+ def common_path(paths)
166
+ paths.map { |path| path.ascend.to_a }.reduce(&:&)&.first
201
167
  end
168
+ end
202
169
  end
203
170
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/callbacks"
4
+ require "concurrent/hash"
2
5
 
3
6
  module ActiveSupport
4
7
  class ExecutionWrapper
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/execution_wrapper"
2
4
 
3
5
  module ActiveSupport
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/time/calculations"
2
4
 
3
5
  module ActiveSupport
@@ -96,7 +98,6 @@ module ActiveSupport
96
98
  end
97
99
 
98
100
  private
99
-
100
101
  def watched
101
102
  @watched || begin
102
103
  all = @files.select { |f| File.exist?(f) }
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module ForkTracker # :nodoc:
5
+ module CoreExt
6
+ def fork(*)
7
+ if block_given?
8
+ super do
9
+ ForkTracker.check!
10
+ yield
11
+ end
12
+ else
13
+ unless pid = super
14
+ ForkTracker.check!
15
+ end
16
+ pid
17
+ end
18
+ end
19
+ end
20
+
21
+ module CoreExtPrivate
22
+ include CoreExt
23
+
24
+ private
25
+ def fork(*)
26
+ super
27
+ end
28
+ end
29
+
30
+ @pid = Process.pid
31
+ @callbacks = []
32
+
33
+ class << self
34
+ def check!
35
+ if @pid != Process.pid
36
+ @callbacks.each(&:call)
37
+ @pid = Process.pid
38
+ end
39
+ end
40
+
41
+ def hook!
42
+ if Process.respond_to?(:fork)
43
+ ::Object.prepend(CoreExtPrivate)
44
+ ::Kernel.prepend(CoreExtPrivate)
45
+ ::Kernel.singleton_class.prepend(CoreExt)
46
+ ::Process.singleton_class.prepend(CoreExt)
47
+ end
48
+ end
49
+
50
+ def after_fork(&block)
51
+ @callbacks << block
52
+ block
53
+ end
54
+
55
+ def unregister(callback)
56
+ @callbacks.delete(callback)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ ActiveSupport::ForkTracker.hook!
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
3
5
  def self.gem_version
@@ -5,7 +7,7 @@ module ActiveSupport
5
7
  end
6
8
 
7
9
  module VERSION
8
- MAJOR = 5
10
+ MAJOR = 6
9
11
  MINOR = 1
10
12
  TINY = 1
11
13
  PRE = nil
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "zlib"
2
4
  require "stringio"
3
5
 
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/keys"
2
4
  require "active_support/core_ext/hash/reverse_merge"
5
+ require "active_support/core_ext/hash/except"
3
6
 
4
7
  module ActiveSupport
5
8
  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
@@ -66,7 +69,7 @@ module ActiveSupport
66
69
  super()
67
70
  update(constructor)
68
71
 
69
- hash = constructor.to_hash
72
+ hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
70
73
  self.default = hash.default if hash.default
71
74
  self.default_proc = hash.default_proc if hash.default_proc
72
75
  else
@@ -74,16 +77,6 @@ module ActiveSupport
74
77
  end
75
78
  end
76
79
 
77
- def default(*args)
78
- arg_key = args.first
79
-
80
- if include?(key = convert_key(arg_key))
81
- self[key]
82
- else
83
- super
84
- end
85
- end
86
-
87
80
  def self.[](*args)
88
81
  new.merge!(Hash[*args])
89
82
  end
@@ -98,12 +91,12 @@ module ActiveSupport
98
91
  #
99
92
  # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
100
93
  def []=(key, value)
101
- regular_writer(convert_key(key), convert_value(value, for: :assignment))
94
+ regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
102
95
  end
103
96
 
104
97
  alias_method :store, :[]=
105
98
 
106
- # Updates the receiver in-place, merging in the hash passed as argument:
99
+ # Updates the receiver in-place, merging in the hashes passed as arguments:
107
100
  #
108
101
  # hash_1 = ActiveSupport::HashWithIndifferentAccess.new
109
102
  # hash_1[:key] = 'value'
@@ -113,7 +106,10 @@ module ActiveSupport
113
106
  #
114
107
  # hash_1.update(hash_2) # => {"key"=>"New Value!"}
115
108
  #
116
- # The argument can be either an
109
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
110
+ # hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
111
+ #
112
+ # The arguments can be either an
117
113
  # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
118
114
  # In either case the merge respects the semantics of indifferent access.
119
115
  #
@@ -128,18 +124,15 @@ module ActiveSupport
128
124
  # hash_1[:key] = 10
129
125
  # hash_2['key'] = 12
130
126
  # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
131
- def update(other_hash)
132
- if other_hash.is_a? HashWithIndifferentAccess
133
- super(other_hash)
127
+ def update(*other_hashes, &block)
128
+ if other_hashes.size == 1
129
+ update_with_single_argument(other_hashes.first, block)
134
130
  else
135
- other_hash.to_hash.each_pair do |key, value|
136
- if block_given? && key?(key)
137
- value = yield(convert_key(key), self[key], value)
138
- end
139
- regular_writer(convert_key(key), convert_value(value))
131
+ other_hashes.each do |other_hash|
132
+ update_with_single_argument(other_hash, block)
140
133
  end
141
- self
142
134
  end
135
+ self
143
136
  end
144
137
 
145
138
  alias_method :merge!, :update
@@ -171,6 +164,19 @@ module ActiveSupport
171
164
  super(convert_key(key))
172
165
  end
173
166
 
167
+ # Same as <tt>Hash#assoc</tt> where the key passed as argument can be
168
+ # either a string or a symbol:
169
+ #
170
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
171
+ # counters[:foo] = 1
172
+ #
173
+ # counters.assoc('foo') # => ["foo", 1]
174
+ # counters.assoc(:foo) # => ["foo", 1]
175
+ # counters.assoc(:zoo) # => nil
176
+ def assoc(key)
177
+ super(convert_key(key))
178
+ end
179
+
174
180
  # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
175
181
  # either a string or a symbol:
176
182
  #
@@ -185,14 +191,55 @@ module ActiveSupport
185
191
  super(convert_key(key), *extras)
186
192
  end
187
193
 
194
+ # Same as <tt>Hash#dig</tt> where the key passed as argument can be
195
+ # either a string or a symbol:
196
+ #
197
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
198
+ # counters[:foo] = { bar: 1 }
199
+ #
200
+ # counters.dig('foo', 'bar') # => 1
201
+ # counters.dig(:foo, :bar) # => 1
202
+ # counters.dig(:zoo) # => nil
203
+ def dig(*args)
204
+ args[0] = convert_key(args[0]) if args.size > 0
205
+ super(*args)
206
+ end
207
+
208
+ # Same as <tt>Hash#default</tt> where the key passed as argument can be
209
+ # either a string or a symbol:
210
+ #
211
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(1)
212
+ # hash.default # => 1
213
+ #
214
+ # hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
215
+ # hash.default # => nil
216
+ # hash.default('foo') # => 'foo'
217
+ # hash.default(:foo) # => 'foo'
218
+ def default(*args)
219
+ super(*args.map { |arg| convert_key(arg) })
220
+ end
221
+
188
222
  # Returns an array of the values at the specified indices:
189
223
  #
190
224
  # hash = ActiveSupport::HashWithIndifferentAccess.new
191
225
  # hash[:a] = 'x'
192
226
  # hash[:b] = 'y'
193
227
  # hash.values_at('a', 'b') # => ["x", "y"]
194
- def values_at(*indices)
195
- indices.collect { |key| self[convert_key(key)] }
228
+ def values_at(*keys)
229
+ super(*keys.map { |key| convert_key(key) })
230
+ end
231
+
232
+ # Returns an array of the values at the specified indices, but also
233
+ # raises an exception when one of the keys can't be found.
234
+ #
235
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
236
+ # hash[:a] = 'x'
237
+ # hash[:b] = 'y'
238
+ # hash.fetch_values('a', 'b') # => ["x", "y"]
239
+ # hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
240
+ # hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
241
+ def fetch_values(*indices, &block)
242
+ super(*indices.map { |key| convert_key(key) }, &block)
196
243
  end
197
244
 
198
245
  # Returns a shallow copy of the hash.
@@ -201,7 +248,7 @@ module ActiveSupport
201
248
  # dup = hash.dup
202
249
  # dup[:a][:c] = 'c'
203
250
  #
204
- # hash[:a][:c] # => nil
251
+ # hash[:a][:c] # => "c"
205
252
  # dup[:a][:c] # => "c"
206
253
  def dup
207
254
  self.class.new(self).tap do |new_hash|
@@ -212,8 +259,8 @@ module ActiveSupport
212
259
  # This method has the same semantics of +update+, except it does not
213
260
  # modify the receiver but rather returns a new hash with indifferent
214
261
  # access with the result of the merge.
215
- def merge(hash, &block)
216
- dup.update(hash, &block)
262
+ def merge(*hashes, &block)
263
+ dup.update(*hashes, &block)
217
264
  end
218
265
 
219
266
  # Like +merge+ but the other way around: Merges the receiver into the
@@ -225,11 +272,13 @@ module ActiveSupport
225
272
  def reverse_merge(other_hash)
226
273
  super(self.class.new(other_hash))
227
274
  end
275
+ alias_method :with_defaults, :reverse_merge
228
276
 
229
277
  # Same semantics as +reverse_merge+ but modifies the receiver in-place.
230
278
  def reverse_merge!(other_hash)
231
- replace(reverse_merge(other_hash))
279
+ super(self.class.new(other_hash))
232
280
  end
281
+ alias_method :with_defaults!, :reverse_merge!
233
282
 
234
283
  # Replaces the contents of this hash with other_hash.
235
284
  #
@@ -244,6 +293,11 @@ module ActiveSupport
244
293
  super(convert_key(key))
245
294
  end
246
295
 
296
+ def except(*keys)
297
+ slice(*self.keys - keys.map { |key| convert_key(key) })
298
+ end
299
+ alias_method :without, :except
300
+
247
301
  def stringify_keys!; self end
248
302
  def deep_stringify_keys!; self end
249
303
  def stringify_keys; dup end
@@ -251,6 +305,7 @@ module ActiveSupport
251
305
  undef :symbolize_keys!
252
306
  undef :deep_symbolize_keys!
253
307
  def symbolize_keys; to_hash.symbolize_keys! end
308
+ alias_method :to_options, :symbolize_keys
254
309
  def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
255
310
  def to_options!; self end
256
311
 
@@ -269,6 +324,29 @@ module ActiveSupport
269
324
  dup.tap { |hash| hash.transform_values!(*args, &block) }
270
325
  end
271
326
 
327
+ def transform_keys(*args, &block)
328
+ return to_enum(:transform_keys) unless block_given?
329
+ dup.tap { |hash| hash.transform_keys!(*args, &block) }
330
+ end
331
+
332
+ def transform_keys!
333
+ return enum_for(:transform_keys!) { size } unless block_given?
334
+ keys.each do |key|
335
+ self[yield(key)] = delete(key)
336
+ end
337
+ self
338
+ end
339
+
340
+ def slice(*keys)
341
+ keys.map! { |key| convert_key(key) }
342
+ self.class.new(super)
343
+ end
344
+
345
+ def slice!(*keys)
346
+ keys.map! { |key| convert_key(key) }
347
+ super
348
+ end
349
+
272
350
  def compact
273
351
  dup.tap(&:compact!)
274
352
  end
@@ -279,40 +357,59 @@ module ActiveSupport
279
357
  set_defaults(_new_hash)
280
358
 
281
359
  each do |key, value|
282
- _new_hash[key] = convert_value(value, for: :to_hash)
360
+ _new_hash[key] = convert_value(value, conversion: :to_hash)
283
361
  end
284
362
  _new_hash
285
363
  end
286
364
 
287
365
  private
288
- def convert_key(key) # :doc:
289
- key.kind_of?(Symbol) ? key.to_s : key
366
+ if Symbol.method_defined?(:name)
367
+ def convert_key(key)
368
+ key.kind_of?(Symbol) ? key.name : key
369
+ end
370
+ else
371
+ def convert_key(key)
372
+ key.kind_of?(Symbol) ? key.to_s : key
373
+ end
290
374
  end
291
375
 
292
- def convert_value(value, options = {}) # :doc:
376
+ def convert_value(value, conversion: nil)
293
377
  if value.is_a? Hash
294
- if options[:for] == :to_hash
378
+ if conversion == :to_hash
295
379
  value.to_hash
296
380
  else
297
381
  value.nested_under_indifferent_access
298
382
  end
299
383
  elsif value.is_a?(Array)
300
- if options[:for] != :assignment || value.frozen?
384
+ if conversion != :assignment || value.frozen?
301
385
  value = value.dup
302
386
  end
303
- value.map! { |e| convert_value(e, options) }
387
+ value.map! { |e| convert_value(e, conversion: conversion) }
304
388
  else
305
389
  value
306
390
  end
307
391
  end
308
392
 
309
- def set_defaults(target) # :doc:
393
+ def set_defaults(target)
310
394
  if default_proc
311
395
  target.default_proc = default_proc.dup
312
396
  else
313
397
  target.default = default
314
398
  end
315
399
  end
400
+
401
+ def update_with_single_argument(other_hash, block)
402
+ if other_hash.is_a? HashWithIndifferentAccess
403
+ regular_update(other_hash, &block)
404
+ else
405
+ other_hash.to_hash.each_pair do |key, value|
406
+ if block && key?(key)
407
+ value = block.call(convert_key(key), self[key], value)
408
+ end
409
+ regular_writer(convert_key(key), convert_value(value))
410
+ end
411
+ end
412
+ end
316
413
  end
317
414
  end
318
415