aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/file_update_checker.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/file_update_checker.rb')
-rw-r--r--activesupport/lib/active_support/file_update_checker.rb92
1 files changed, 56 insertions, 36 deletions
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
index 1fa9335080..98aceabe21 100644
--- a/activesupport/lib/active_support/file_update_checker.rb
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/time/calculations"
+
module ActiveSupport
# FileUpdateChecker specifies the API used by Rails to watch files
# and control reloading. The API depends on four methods:
@@ -23,7 +25,7 @@ module ActiveSupport
# I18n.reload!
# end
#
- # ActionDispatch::Reloader.to_prepare do
+ # ActiveSupport::Reloader.to_prepare do
# i18n_reloader.execute_if_updated
# end
class FileUpdateChecker
@@ -81,6 +83,7 @@ module ActiveSupport
# Execute the block given if updated.
def execute_if_updated
if updated?
+ yield if block_given?
execute
true
else
@@ -90,48 +93,65 @@ module ActiveSupport
private
- def watched
- @watched || begin
- all = @files.select { |f| File.exist?(f) }
- all.concat(Dir[@glob]) if @glob
- all
+ def watched
+ @watched || begin
+ all = @files.select { |f| File.exist?(f) }
+ all.concat(Dir[@glob]) if @glob
+ all
+ end
end
- end
- def updated_at(paths)
- @updated_at || max_mtime(paths) || Time.at(0)
- end
+ def updated_at(paths)
+ @updated_at || max_mtime(paths) || Time.at(0)
+ end
- # This method returns the maximum mtime of the files in +paths+, or +nil+
- # if the array is empty.
- #
- # Files with a mtime in the future are ignored. Such abnormal situation
- # can happen for example if the user changes the clock by hand. It is
- # healthy to consider this edge case because with mtimes in the future
- # reloading is not triggered.
- def max_mtime(paths)
- time_now = Time.now
- paths.map {|path| File.mtime(path)}.reject {|mtime| time_now < mtime}.max
- end
+ # This method returns the maximum mtime of the files in +paths+, or +nil+
+ # if the array is empty.
+ #
+ # Files with a mtime in the future are ignored. Such abnormal situation
+ # can happen for example if the user changes the clock by hand. It is
+ # healthy to consider this edge case because with mtimes in the future
+ # reloading is not triggered.
+ def max_mtime(paths)
+ time_now = Time.now
+ max_mtime = nil
+
+ # Time comparisons are performed with #compare_without_coercion because
+ # AS redefines these operators in a way that is much slower and does not
+ # bring any benefit in this particular code.
+ #
+ # Read t1.compare_without_coercion(t2) < 0 as t1 < t2.
+ paths.each do |path|
+ mtime = File.mtime(path)
- def compile_glob(hash)
- hash.freeze # Freeze so changes aren't accidentally pushed
- return if hash.empty?
+ next if time_now.compare_without_coercion(mtime) < 0
+
+ if max_mtime.nil? || max_mtime.compare_without_coercion(mtime) < 0
+ max_mtime = mtime
+ end
+ end
- globs = hash.map do |key, value|
- "#{escape(key)}/**/*#{compile_ext(value)}"
+ max_mtime
end
- "{#{globs.join(",")}}"
- end
- def escape(key)
- key.gsub(',','\,')
- end
+ def compile_glob(hash)
+ hash.freeze # Freeze so changes aren't accidentally pushed
+ return if hash.empty?
- def compile_ext(array)
- array = Array(array)
- return if array.empty?
- ".{#{array.join(",")}}"
- end
+ globs = hash.map do |key, value|
+ "#{escape(key)}/**/*#{compile_ext(value)}"
+ end
+ "{#{globs.join(",")}}"
+ end
+
+ def escape(key)
+ key.gsub(",",'\,')
+ end
+
+ def compile_ext(array)
+ array = Array(array)
+ return if array.empty?
+ ".{#{array.join(",")}}"
+ end
end
end