activesupport 5.0.7.2 → 5.1.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +464 -694
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_support.rb +8 -4
  6. data/lib/active_support/all.rb +3 -3
  7. data/lib/active_support/array_inquirer.rb +7 -5
  8. data/lib/active_support/backtrace_cleaner.rb +4 -4
  9. data/lib/active_support/benchmarkable.rb +3 -3
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache.rb +41 -48
  12. data/lib/active_support/cache/file_store.rb +11 -20
  13. data/lib/active_support/cache/mem_cache_store.rb +30 -40
  14. data/lib/active_support/cache/memory_store.rb +13 -13
  15. data/lib/active_support/cache/null_store.rb +4 -4
  16. data/lib/active_support/cache/strategy/local_cache.rb +13 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -5
  18. data/lib/active_support/callbacks.rb +649 -584
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  20. data/lib/active_support/concurrency/share_lock.rb +20 -21
  21. data/lib/active_support/configurable.rb +5 -5
  22. data/lib/active_support/core_ext.rb +1 -2
  23. data/lib/active_support/core_ext/array.rb +7 -7
  24. data/lib/active_support/core_ext/array/access.rb +1 -1
  25. data/lib/active_support/core_ext/array/conversions.rb +15 -15
  26. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  27. data/lib/active_support/core_ext/array/inquiry.rb +1 -1
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +1 -1
  29. data/lib/active_support/core_ext/benchmark.rb +1 -1
  30. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  31. data/lib/active_support/core_ext/big_decimal/conversions.rb +4 -6
  32. data/lib/active_support/core_ext/class.rb +2 -2
  33. data/lib/active_support/core_ext/class/attribute.rb +5 -5
  34. data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
  35. data/lib/active_support/core_ext/class/subclasses.rb +18 -4
  36. data/lib/active_support/core_ext/date.rb +5 -5
  37. data/lib/active_support/core_ext/date/acts_like.rb +1 -1
  38. data/lib/active_support/core_ext/date/blank.rb +1 -1
  39. data/lib/active_support/core_ext/date/calculations.rb +8 -8
  40. data/lib/active_support/core_ext/date/conversions.rb +12 -12
  41. data/lib/active_support/core_ext/date/zones.rb +2 -2
  42. data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -22
  43. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  44. data/lib/active_support/core_ext/date_and_time/zones.rb +7 -8
  45. data/lib/active_support/core_ext/date_time.rb +5 -5
  46. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -2
  47. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  48. data/lib/active_support/core_ext/date_time/calculations.rb +20 -10
  49. data/lib/active_support/core_ext/date_time/compatibility.rb +2 -2
  50. data/lib/active_support/core_ext/date_time/conversions.rb +12 -12
  51. data/lib/active_support/core_ext/digest/uuid.rb +4 -4
  52. data/lib/active_support/core_ext/enumerable.rb +23 -12
  53. data/lib/active_support/core_ext/file.rb +1 -1
  54. data/lib/active_support/core_ext/file/atomic.rb +4 -4
  55. data/lib/active_support/core_ext/hash.rb +9 -9
  56. data/lib/active_support/core_ext/hash/compact.rb +12 -9
  57. data/lib/active_support/core_ext/hash/conversions.rb +36 -37
  58. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -2
  59. data/lib/active_support/core_ext/hash/keys.rb +6 -6
  60. data/lib/active_support/core_ext/hash/reverse_merge.rb +1 -1
  61. data/lib/active_support/core_ext/hash/slice.rb +4 -4
  62. data/lib/active_support/core_ext/hash/transform_values.rb +1 -0
  63. data/lib/active_support/core_ext/integer.rb +3 -3
  64. data/lib/active_support/core_ext/integer/inflections.rb +1 -1
  65. data/lib/active_support/core_ext/integer/time.rb +2 -2
  66. data/lib/active_support/core_ext/kernel.rb +4 -4
  67. data/lib/active_support/core_ext/kernel/concern.rb +1 -1
  68. data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
  69. data/lib/active_support/core_ext/load_error.rb +1 -18
  70. data/lib/active_support/core_ext/module.rb +11 -12
  71. data/lib/active_support/core_ext/module/aliasing.rb +3 -48
  72. data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
  73. data/lib/active_support/core_ext/module/attribute_accessors.rb +11 -5
  74. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +20 -13
  75. data/lib/active_support/core_ext/module/concerning.rb +1 -1
  76. data/lib/active_support/core_ext/module/delegation.rb +85 -16
  77. data/lib/active_support/core_ext/module/introspection.rb +3 -11
  78. data/lib/active_support/core_ext/module/reachable.rb +2 -2
  79. data/lib/active_support/core_ext/numeric.rb +4 -4
  80. data/lib/active_support/core_ext/numeric/conversions.rb +3 -9
  81. data/lib/active_support/core_ext/numeric/inquiry.rb +21 -21
  82. data/lib/active_support/core_ext/numeric/time.rb +5 -5
  83. data/lib/active_support/core_ext/object.rb +12 -12
  84. data/lib/active_support/core_ext/object/blank.rb +3 -1
  85. data/lib/active_support/core_ext/object/conversions.rb +4 -4
  86. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  87. data/lib/active_support/core_ext/object/duplicable.rb +34 -4
  88. data/lib/active_support/core_ext/object/inclusion.rb +1 -1
  89. data/lib/active_support/core_ext/object/json.rb +26 -12
  90. data/lib/active_support/core_ext/object/to_param.rb +1 -1
  91. data/lib/active_support/core_ext/object/to_query.rb +8 -5
  92. data/lib/active_support/core_ext/object/try.rb +1 -1
  93. data/lib/active_support/core_ext/object/with_options.rb +12 -1
  94. data/lib/active_support/core_ext/range.rb +4 -4
  95. data/lib/active_support/core_ext/range/conversions.rb +1 -1
  96. data/lib/active_support/core_ext/regexp.rb +4 -0
  97. data/lib/active_support/core_ext/securerandom.rb +3 -3
  98. data/lib/active_support/core_ext/string.rb +13 -13
  99. data/lib/active_support/core_ext/string/access.rb +6 -6
  100. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  101. data/lib/active_support/core_ext/string/filters.rb +3 -3
  102. data/lib/active_support/core_ext/string/indent.rb +4 -4
  103. data/lib/active_support/core_ext/string/inflections.rb +10 -14
  104. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  105. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  106. data/lib/active_support/core_ext/string/output_safety.rb +19 -20
  107. data/lib/active_support/core_ext/string/strip.rb +1 -1
  108. data/lib/active_support/core_ext/string/zones.rb +2 -2
  109. data/lib/active_support/core_ext/time.rb +5 -5
  110. data/lib/active_support/core_ext/time/acts_like.rb +1 -1
  111. data/lib/active_support/core_ext/time/calculations.rb +46 -29
  112. data/lib/active_support/core_ext/time/conversions.rb +15 -12
  113. data/lib/active_support/core_ext/time/zones.rb +3 -3
  114. data/lib/active_support/core_ext/uri.rb +2 -2
  115. data/lib/active_support/dependencies.rb +45 -46
  116. data/lib/active_support/dependencies/interlock.rb +1 -1
  117. data/lib/active_support/deprecation.rb +9 -8
  118. data/lib/active_support/deprecation/behaviors.rb +3 -3
  119. data/lib/active_support/deprecation/constant_accessor.rb +50 -0
  120. data/lib/active_support/deprecation/instance_delegator.rb +2 -2
  121. data/lib/active_support/deprecation/method_wrappers.rb +10 -3
  122. data/lib/active_support/deprecation/proxy_wrappers.rb +6 -4
  123. data/lib/active_support/deprecation/reporting.rb +7 -7
  124. data/lib/active_support/duration.rb +221 -28
  125. data/lib/active_support/duration/iso8601_parser.rb +66 -65
  126. data/lib/active_support/duration/iso8601_serializer.rb +11 -9
  127. data/lib/active_support/evented_file_update_checker.rb +59 -55
  128. data/lib/active_support/execution_wrapper.rb +3 -3
  129. data/lib/active_support/executor.rb +1 -1
  130. data/lib/active_support/file_update_checker.rb +54 -50
  131. data/lib/active_support/gem_version.rb +2 -2
  132. data/lib/active_support/gzip.rb +4 -4
  133. data/lib/active_support/hash_with_indifferent_access.rb +40 -28
  134. data/lib/active_support/i18n.rb +5 -5
  135. data/lib/active_support/i18n_railtie.rb +14 -9
  136. data/lib/active_support/inflections.rb +11 -11
  137. data/lib/active_support/inflector.rb +5 -5
  138. data/lib/active_support/inflector/inflections.rb +11 -9
  139. data/lib/active_support/inflector/methods.rb +52 -51
  140. data/lib/active_support/inflector/transliterate.rb +8 -11
  141. data/lib/active_support/json.rb +2 -2
  142. data/lib/active_support/json/decoding.rb +3 -3
  143. data/lib/active_support/json/encoding.rb +8 -7
  144. data/lib/active_support/key_generator.rb +17 -17
  145. data/lib/active_support/lazy_load_hooks.rb +2 -2
  146. data/lib/active_support/log_subscriber.rb +9 -7
  147. data/lib/active_support/log_subscriber/test_helper.rb +9 -9
  148. data/lib/active_support/logger.rb +3 -3
  149. data/lib/active_support/logger_silence.rb +3 -3
  150. data/lib/active_support/logger_thread_safe_level.rb +1 -1
  151. data/lib/active_support/message_encryptor.rb +77 -35
  152. data/lib/active_support/message_verifier.rb +7 -7
  153. data/lib/active_support/multibyte.rb +2 -2
  154. data/lib/active_support/multibyte/chars.rb +23 -21
  155. data/lib/active_support/multibyte/unicode.rb +68 -89
  156. data/lib/active_support/notifications.rb +7 -5
  157. data/lib/active_support/notifications/fanout.rb +3 -3
  158. data/lib/active_support/notifications/instrumenter.rb +5 -5
  159. data/lib/active_support/number_helper.rb +5 -4
  160. data/lib/active_support/number_helper/number_converter.rb +11 -11
  161. data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -3
  162. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -2
  163. data/lib/active_support/number_helper/number_to_human_converter.rb +8 -10
  164. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -11
  165. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  166. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -3
  167. data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -32
  168. data/lib/active_support/number_helper/rounding_helper.rb +64 -0
  169. data/lib/active_support/option_merger.rb +1 -1
  170. data/lib/active_support/ordered_hash.rb +3 -3
  171. data/lib/active_support/ordered_options.rb +6 -4
  172. data/lib/active_support/per_thread_registry.rb +5 -5
  173. data/lib/active_support/rails.rb +12 -6
  174. data/lib/active_support/railtie.rb +3 -3
  175. data/lib/active_support/reloader.rb +1 -1
  176. data/lib/active_support/rescuable.rb +6 -6
  177. data/lib/active_support/security_utils.rb +1 -1
  178. data/lib/active_support/string_inquirer.rb +8 -2
  179. data/lib/active_support/subscriber.rb +9 -5
  180. data/lib/active_support/tagged_logging.rb +4 -4
  181. data/lib/active_support/test_case.rb +12 -29
  182. data/lib/active_support/testing/assertions.rb +100 -2
  183. data/lib/active_support/testing/autorun.rb +2 -2
  184. data/lib/active_support/testing/constant_lookup.rb +0 -1
  185. data/lib/active_support/testing/declarative.rb +1 -1
  186. data/lib/active_support/testing/deprecation.rb +3 -2
  187. data/lib/active_support/testing/isolation.rb +15 -22
  188. data/lib/active_support/testing/method_call_assertions.rb +1 -1
  189. data/lib/active_support/testing/setup_and_teardown.rb +2 -2
  190. data/lib/active_support/testing/stream.rb +28 -28
  191. data/lib/active_support/testing/tagged_logging.rb +1 -1
  192. data/lib/active_support/testing/time_helpers.rb +45 -11
  193. data/lib/active_support/time.rb +12 -12
  194. data/lib/active_support/time_with_zone.rb +16 -14
  195. data/lib/active_support/values/time_zone.rb +100 -31
  196. data/lib/active_support/values/unicode_tables.dat +0 -0
  197. data/lib/active_support/version.rb +1 -1
  198. data/lib/active_support/xml_mini.rb +34 -36
  199. data/lib/active_support/xml_mini/jdom.rb +112 -112
  200. data/lib/active_support/xml_mini/libxml.rb +12 -11
  201. data/lib/active_support/xml_mini/libxmlsax.rb +13 -14
  202. data/lib/active_support/xml_mini/nokogiri.rb +10 -10
  203. data/lib/active_support/xml_mini/nokogirisax.rb +12 -13
  204. data/lib/active_support/xml_mini/rexml.rb +9 -9
  205. metadata +8 -9
  206. data/lib/active_support/concurrency/latch.rb +0 -26
  207. data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
  208. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
  209. data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
  210. data/lib/active_support/core_ext/struct.rb +0 -3
  211. data/lib/active_support/core_ext/time/marshal.rb +0 -3
@@ -1,4 +1,5 @@
1
- require 'strscan'
1
+ require "strscan"
2
+ require "active_support/core_ext/regexp"
2
3
 
3
4
  module ActiveSupport
4
5
  class Duration
@@ -11,8 +12,8 @@ module ActiveSupport
11
12
  class ParsingError < ::ArgumentError; end
12
13
 
13
14
  PERIOD_OR_COMMA = /\.|,/
14
- PERIOD = '.'.freeze
15
- COMMA = ','.freeze
15
+ PERIOD = ".".freeze
16
+ COMMA = ",".freeze
16
17
 
17
18
  SIGN_MARKER = /\A\-|\+|/
18
19
  DATE_MARKER = /P/
@@ -20,8 +21,8 @@ module ActiveSupport
20
21
  DATE_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
21
22
  TIME_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(H|M|S)/
22
23
 
23
- DATE_TO_PART = { 'Y' => :years, 'M' => :months, 'W' => :weeks, 'D' => :days }
24
- TIME_TO_PART = { 'H' => :hours, 'M' => :minutes, 'S' => :seconds }
24
+ DATE_TO_PART = { "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
25
+ TIME_TO_PART = { "H" => :hours, "M" => :minutes, "S" => :seconds }
25
26
 
26
27
  DATE_COMPONENTS = [:years, :months, :days]
27
28
  TIME_COMPONENTS = [:hours, :minutes, :seconds]
@@ -39,36 +40,36 @@ module ActiveSupport
39
40
  def parse!
40
41
  while !finished?
41
42
  case mode
42
- when :start
43
- if scan(SIGN_MARKER)
44
- self.sign = (scanner.matched == '-') ? -1 : 1
45
- self.mode = :sign
46
- else
47
- raise_parsing_error
48
- end
49
-
50
- when :sign
51
- if scan(DATE_MARKER)
52
- self.mode = :date
53
- else
54
- raise_parsing_error
55
- end
56
-
57
- when :date
58
- if scan(TIME_MARKER)
59
- self.mode = :time
60
- elsif scan(DATE_COMPONENT)
61
- parts[DATE_TO_PART[scanner[2]]] = number * sign
62
- else
63
- raise_parsing_error
64
- end
65
-
66
- when :time
67
- if scan(TIME_COMPONENT)
68
- parts[TIME_TO_PART[scanner[2]]] = number * sign
69
- else
70
- raise_parsing_error
71
- end
43
+ when :start
44
+ if scan(SIGN_MARKER)
45
+ self.sign = (scanner.matched == "-") ? -1 : 1
46
+ self.mode = :sign
47
+ else
48
+ raise_parsing_error
49
+ end
50
+
51
+ when :sign
52
+ if scan(DATE_MARKER)
53
+ self.mode = :date
54
+ else
55
+ raise_parsing_error
56
+ end
57
+
58
+ when :date
59
+ if scan(TIME_MARKER)
60
+ self.mode = :time
61
+ elsif scan(DATE_COMPONENT)
62
+ parts[DATE_TO_PART[scanner[2]]] = number * sign
63
+ else
64
+ raise_parsing_error
65
+ end
66
+
67
+ when :time
68
+ if scan(TIME_COMPONENT)
69
+ parts[TIME_TO_PART[scanner[2]]] = number * sign
70
+ else
71
+ raise_parsing_error
72
+ end
72
73
 
73
74
  end
74
75
  end
@@ -79,44 +80,44 @@ module ActiveSupport
79
80
 
80
81
  private
81
82
 
82
- def finished?
83
- scanner.eos?
84
- end
83
+ def finished?
84
+ scanner.eos?
85
+ end
85
86
 
86
- # Parses number which can be a float with either comma or period.
87
- def number
88
- scanner[1] =~ PERIOD_OR_COMMA ? scanner[1].tr(COMMA, PERIOD).to_f : scanner[1].to_i
89
- end
87
+ # Parses number which can be a float with either comma or period.
88
+ def number
89
+ PERIOD_OR_COMMA.match?(scanner[1]) ? scanner[1].tr(COMMA, PERIOD).to_f : scanner[1].to_i
90
+ end
90
91
 
91
- def scan(pattern)
92
- scanner.scan(pattern)
93
- end
92
+ def scan(pattern)
93
+ scanner.scan(pattern)
94
+ end
94
95
 
95
- def raise_parsing_error(reason = nil)
96
- raise ParsingError, "Invalid ISO 8601 duration: #{scanner.string.inspect} #{reason}".strip
97
- end
96
+ def raise_parsing_error(reason = nil)
97
+ raise ParsingError, "Invalid ISO 8601 duration: #{scanner.string.inspect} #{reason}".strip
98
+ end
98
99
 
99
- # Checks for various semantic errors as stated in ISO 8601 standard.
100
- def validate!
101
- raise_parsing_error('is empty duration') if parts.empty?
100
+ # Checks for various semantic errors as stated in ISO 8601 standard.
101
+ def validate!
102
+ raise_parsing_error("is empty duration") if parts.empty?
102
103
 
103
- # Mixing any of Y, M, D with W is invalid.
104
- if parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
105
- raise_parsing_error('mixing weeks with other date parts not allowed')
106
- end
104
+ # Mixing any of Y, M, D with W is invalid.
105
+ if parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
106
+ raise_parsing_error("mixing weeks with other date parts not allowed")
107
+ end
107
108
 
108
- # Specifying an empty T part is invalid.
109
- if mode == :time && (parts.keys & TIME_COMPONENTS).empty?
110
- raise_parsing_error('time part marker is present but time part is empty')
111
- end
109
+ # Specifying an empty T part is invalid.
110
+ if mode == :time && (parts.keys & TIME_COMPONENTS).empty?
111
+ raise_parsing_error("time part marker is present but time part is empty")
112
+ end
112
113
 
113
- fractions = parts.values.reject(&:zero?).select { |a| (a % 1) != 0 }
114
- unless fractions.empty? || (fractions.size == 1 && fractions.last == @parts.values.reject(&:zero?).last)
115
- raise_parsing_error '(only last part can be fractional)'
116
- end
114
+ fractions = parts.values.reject(&:zero?).select { |a| (a % 1) != 0 }
115
+ unless fractions.empty? || (fractions.size == 1 && fractions.last == @parts.values.reject(&:zero?).last)
116
+ raise_parsing_error "(only last part can be fractional)"
117
+ end
117
118
 
118
- return true
119
- end
119
+ return true
120
+ end
120
121
  end
121
122
  end
122
123
  end
@@ -1,10 +1,10 @@
1
- require 'active_support/core_ext/object/blank'
2
- require 'active_support/core_ext/hash/transform_values'
1
+ require "active_support/core_ext/object/blank"
2
+ require "active_support/core_ext/hash/transform_values"
3
3
 
4
4
  module ActiveSupport
5
5
  class Duration
6
6
  # Serializes duration to string according to ISO 8601 Duration format.
7
- class ISO8601Serializer
7
+ class ISO8601Serializer # :nodoc:
8
8
  def initialize(duration, precision: nil)
9
9
  @duration = duration
10
10
  @precision = precision
@@ -12,19 +12,21 @@ module ActiveSupport
12
12
 
13
13
  # Builds and returns output string.
14
14
  def serialize
15
- output = 'P'
16
15
  parts, sign = normalize
16
+ return "PT0S".freeze if parts.empty?
17
+
18
+ output = "P"
17
19
  output << "#{parts[:years]}Y" if parts.key?(:years)
18
20
  output << "#{parts[:months]}M" if parts.key?(:months)
19
21
  output << "#{parts[:weeks]}W" if parts.key?(:weeks)
20
22
  output << "#{parts[:days]}D" if parts.key?(:days)
21
- time = ''
23
+ time = ""
22
24
  time << "#{parts[:hours]}H" if parts.key?(:hours)
23
25
  time << "#{parts[:minutes]}M" if parts.key?(:minutes)
24
26
  if parts.key?(:seconds)
25
27
  time << "#{sprintf(@precision ? "%0.0#{@precision}f" : '%g', parts[:seconds])}S"
26
28
  end
27
- output << "T#{time}" if time.present?
29
+ output << "T#{time}" unless time.empty?
28
30
  "#{sign}#{output}"
29
31
  end
30
32
 
@@ -35,13 +37,13 @@ module ActiveSupport
35
37
  # Zero parts are removed as not significant.
36
38
  # If all parts are negative it will negate all of them and return minus as a sign.
37
39
  def normalize
38
- parts = @duration.parts.each_with_object(Hash.new(0)) do |(k,v),p|
40
+ parts = @duration.parts.each_with_object(Hash.new(0)) do |(k, v), p|
39
41
  p[k] += v unless v.zero?
40
42
  end
41
43
  # If all parts are negative - let's make a negative duration
42
- sign = ''
44
+ sign = ""
43
45
  if parts.values.all? { |v| v < 0 }
44
- sign = '-'
46
+ sign = "-"
45
47
  parts.transform_values!(&:-@)
46
48
  end
47
49
  [parts, sign]
@@ -1,6 +1,6 @@
1
- require 'set'
2
- require 'pathname'
3
- require 'concurrent/atomic/atomic_boolean'
1
+ require "set"
2
+ require "pathname"
3
+ require "concurrent/atomic/atomic_boolean"
4
4
 
5
5
  module ActiveSupport
6
6
  # Allows you to "listen" to changes in a file system.
@@ -17,7 +17,7 @@ module ActiveSupport
17
17
  #
18
18
  # Example:
19
19
  #
20
- # checker = EventedFileUpdateChecker.new(["/tmp/foo"], -> { puts "changed" })
20
+ # checker = ActiveSupport::EventedFileUpdateChecker.new(["/tmp/foo"]) { puts "changed" }
21
21
  # checker.updated?
22
22
  # # => false
23
23
  # checker.execute_if_updated
@@ -32,6 +32,10 @@ module ActiveSupport
32
32
  #
33
33
  class EventedFileUpdateChecker #:nodoc: all
34
34
  def initialize(files, dirs = {}, &block)
35
+ unless block
36
+ raise ArgumentError, "A block is required to initialize an EventedFileUpdateChecker"
37
+ end
38
+
35
39
  @ph = PathHelper.new
36
40
  @files = files.map { |f| @ph.xpath(f) }.to_set
37
41
 
@@ -52,7 +56,7 @@ module ActiveSupport
52
56
  # to our test suite. Thus, we lazy load it and disable warnings locally.
53
57
  silence_warnings do
54
58
  begin
55
- require 'listen'
59
+ require "listen"
56
60
  rescue LoadError => e
57
61
  raise LoadError, "Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile", e.backtrace
58
62
  end
@@ -129,71 +133,71 @@ module ActiveSupport
129
133
  @ph.filter_out_descendants(dtw)
130
134
  end
131
135
 
132
- class PathHelper
133
- def xpath(path)
134
- Pathname.new(path).expand_path
135
- end
136
+ class PathHelper
137
+ def xpath(path)
138
+ Pathname.new(path).expand_path
139
+ end
136
140
 
137
- def normalize_extension(ext)
138
- ext.to_s.sub(/\A\./, '')
139
- end
141
+ def normalize_extension(ext)
142
+ ext.to_s.sub(/\A\./, "")
143
+ end
140
144
 
141
- # Given a collection of Pathname objects returns the longest subpath
142
- # common to all of them, or +nil+ if there is none.
143
- def longest_common_subpath(paths)
144
- return if paths.empty?
145
-
146
- lcsp = Pathname.new(paths[0])
147
-
148
- paths[1..-1].each do |path|
149
- until ascendant_of?(lcsp, path)
150
- if lcsp.root?
151
- # If we get here a root directory is not an ascendant of path.
152
- # This may happen if there are paths in different drives on
153
- # Windows.
154
- return
155
- else
156
- lcsp = lcsp.parent
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
157
162
  end
158
163
  end
159
- end
160
164
 
161
- lcsp
162
- end
165
+ lcsp
166
+ end
163
167
 
164
- # Returns the deepest existing ascendant, which could be the argument itself.
165
- def existing_parent(dir)
166
- dir.ascend do |ascendant|
167
- break ascendant if ascendant.directory?
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
168
173
  end
169
- end
170
174
 
171
- # Filters out directories which are descendants of others in the collection (stable).
172
- def filter_out_descendants(dirs)
173
- return dirs if dirs.length < 2
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
174
178
 
175
- dirs_sorted_by_nparts = dirs.sort_by { |dir| dir.each_filename.to_a.length }
176
- descendants = []
179
+ dirs_sorted_by_nparts = dirs.sort_by { |dir| dir.each_filename.to_a.length }
180
+ descendants = []
177
181
 
178
- until dirs_sorted_by_nparts.empty?
179
- dir = dirs_sorted_by_nparts.shift
182
+ until dirs_sorted_by_nparts.empty?
183
+ dir = dirs_sorted_by_nparts.shift
180
184
 
181
- dirs_sorted_by_nparts.reject! do |possible_descendant|
182
- ascendant_of?(dir, possible_descendant) && descendants << possible_descendant
185
+ dirs_sorted_by_nparts.reject! do |possible_descendant|
186
+ ascendant_of?(dir, possible_descendant) && descendants << possible_descendant
187
+ end
183
188
  end
184
- end
185
189
 
186
- # Array#- preserves order.
187
- dirs - descendants
188
- end
190
+ # Array#- preserves order.
191
+ dirs - descendants
192
+ end
189
193
 
190
- private
194
+ private
191
195
 
192
- def ascendant_of?(base, other)
193
- base != other && other.ascend do |ascendant|
194
- break true if base == ascendant
196
+ def ascendant_of?(base, other)
197
+ base != other && other.ascend do |ascendant|
198
+ break true if base == ascendant
199
+ end
195
200
  end
196
- end
197
- end
201
+ end
198
202
  end
199
203
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/callbacks'
1
+ require "active_support/callbacks"
2
2
 
3
3
  module ActiveSupport
4
4
  class ExecutionWrapper
@@ -19,14 +19,14 @@ module ActiveSupport
19
19
  set_callback(:complete, *args, &block)
20
20
  end
21
21
 
22
- class RunHook < Struct.new(:hook) # :nodoc:
22
+ RunHook = Struct.new(:hook) do # :nodoc:
23
23
  def before(target)
24
24
  hook_state = target.send(:hook_state)
25
25
  hook_state[hook] = hook.run
26
26
  end
27
27
  end
28
28
 
29
- class CompleteHook < Struct.new(:hook) # :nodoc:
29
+ CompleteHook = Struct.new(:hook) do # :nodoc:
30
30
  def before(target)
31
31
  hook_state = target.send(:hook_state)
32
32
  if hook_state.key?(hook)
@@ -1,4 +1,4 @@
1
- require 'active_support/execution_wrapper'
1
+ require "active_support/execution_wrapper"
2
2
 
3
3
  module ActiveSupport
4
4
  class Executor < ExecutionWrapper
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/time/calculations'
1
+ require "active_support/core_ext/time/calculations"
2
2
 
3
3
  module ActiveSupport
4
4
  # FileUpdateChecker specifies the API used by Rails to watch files
@@ -38,6 +38,10 @@ module ActiveSupport
38
38
  # changes. The array of files and list of directories cannot be changed
39
39
  # after FileUpdateChecker has been initialized.
40
40
  def initialize(files, dirs = {}, &block)
41
+ unless block
42
+ raise ArgumentError, "A block is required to initialize a FileUpdateChecker"
43
+ end
44
+
41
45
  @files = files.freeze
42
46
  @glob = compile_glob(dirs)
43
47
  @block = block
@@ -93,65 +97,65 @@ module ActiveSupport
93
97
 
94
98
  private
95
99
 
96
- def watched
97
- @watched || begin
98
- all = @files.select { |f| File.exist?(f) }
99
- all.concat(Dir[@glob]) if @glob
100
- all
100
+ def watched
101
+ @watched || begin
102
+ all = @files.select { |f| File.exist?(f) }
103
+ all.concat(Dir[@glob]) if @glob
104
+ all
105
+ end
101
106
  end
102
- end
103
107
 
104
- def updated_at(paths)
105
- @updated_at || max_mtime(paths) || Time.at(0)
106
- end
108
+ def updated_at(paths)
109
+ @updated_at || max_mtime(paths) || Time.at(0)
110
+ end
107
111
 
108
- # This method returns the maximum mtime of the files in +paths+, or +nil+
109
- # if the array is empty.
110
- #
111
- # Files with a mtime in the future are ignored. Such abnormal situation
112
- # can happen for example if the user changes the clock by hand. It is
113
- # healthy to consider this edge case because with mtimes in the future
114
- # reloading is not triggered.
115
- def max_mtime(paths)
116
- time_now = Time.now
117
- max_mtime = nil
118
-
119
- # Time comparisons are performed with #compare_without_coercion because
120
- # AS redefines these operators in a way that is much slower and does not
121
- # bring any benefit in this particular code.
112
+ # This method returns the maximum mtime of the files in +paths+, or +nil+
113
+ # if the array is empty.
122
114
  #
123
- # Read t1.compare_without_coercion(t2) < 0 as t1 < t2.
124
- paths.each do |path|
125
- mtime = File.mtime(path)
126
-
127
- next if time_now.compare_without_coercion(mtime) < 0
128
-
129
- if max_mtime.nil? || max_mtime.compare_without_coercion(mtime) < 0
130
- max_mtime = mtime
115
+ # Files with a mtime in the future are ignored. Such abnormal situation
116
+ # can happen for example if the user changes the clock by hand. It is
117
+ # healthy to consider this edge case because with mtimes in the future
118
+ # reloading is not triggered.
119
+ def max_mtime(paths)
120
+ time_now = Time.now
121
+ max_mtime = nil
122
+
123
+ # Time comparisons are performed with #compare_without_coercion because
124
+ # AS redefines these operators in a way that is much slower and does not
125
+ # bring any benefit in this particular code.
126
+ #
127
+ # Read t1.compare_without_coercion(t2) < 0 as t1 < t2.
128
+ paths.each do |path|
129
+ mtime = File.mtime(path)
130
+
131
+ next if time_now.compare_without_coercion(mtime) < 0
132
+
133
+ if max_mtime.nil? || max_mtime.compare_without_coercion(mtime) < 0
134
+ max_mtime = mtime
135
+ end
131
136
  end
132
- end
133
137
 
134
- max_mtime
135
- end
138
+ max_mtime
139
+ end
136
140
 
137
- def compile_glob(hash)
138
- hash.freeze # Freeze so changes aren't accidentally pushed
139
- return if hash.empty?
141
+ def compile_glob(hash)
142
+ hash.freeze # Freeze so changes aren't accidentally pushed
143
+ return if hash.empty?
140
144
 
141
- globs = hash.map do |key, value|
142
- "#{escape(key)}/**/*#{compile_ext(value)}"
145
+ globs = hash.map do |key, value|
146
+ "#{escape(key)}/**/*#{compile_ext(value)}"
147
+ end
148
+ "{#{globs.join(",")}}"
143
149
  end
144
- "{#{globs.join(",")}}"
145
- end
146
150
 
147
- def escape(key)
148
- key.gsub(',','\,')
149
- end
151
+ def escape(key)
152
+ key.gsub(",", '\,')
153
+ end
150
154
 
151
- def compile_ext(array)
152
- array = Array(array)
153
- return if array.empty?
154
- ".{#{array.join(",")}}"
155
- end
155
+ def compile_ext(array)
156
+ array = Array(array)
157
+ return if array.empty?
158
+ ".{#{array.join(",")}}"
159
+ end
156
160
  end
157
161
  end