mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add ActiveSupport::FileUpdateChecker.
This commit is contained in:
parent
9e081caee7
commit
71703c98ba
3 changed files with 96 additions and 1 deletions
|
@ -39,6 +39,9 @@ require "active_support/dependencies/autoload"
|
|||
module ActiveSupport
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :DescendantsTracker
|
||||
autoload :FileUpdateChecker
|
||||
|
||||
# TODO: Narrow this list down
|
||||
eager_autoload do
|
||||
autoload :BacktraceCleaner
|
||||
|
@ -51,7 +54,6 @@ module ActiveSupport
|
|||
autoload :Concern
|
||||
autoload :Configurable
|
||||
autoload :Deprecation
|
||||
autoload :DescendantsTracker
|
||||
autoload :Gzip
|
||||
autoload :Inflector
|
||||
autoload :JSON
|
||||
|
|
37
activesupport/lib/active_support/file_update_checker.rb
Normal file
37
activesupport/lib/active_support/file_update_checker.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
module ActiveSupport
|
||||
# This class is responsible to track files and invoke the given block
|
||||
# whenever one of these files are changed. For example, this class
|
||||
# is used by Rails to reload routes whenever they are changed upon
|
||||
# a new request.
|
||||
#
|
||||
# routes_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
|
||||
# paths.each { |p| load(p) }
|
||||
# Rails::Application.routes.reload!
|
||||
# end
|
||||
#
|
||||
# ActionDispatch::Callbacks.to_prepare do
|
||||
# routes_reloader.execute_if_updated
|
||||
# end
|
||||
#
|
||||
class FileUpdateChecker
|
||||
attr_reader :paths, :last_update_at
|
||||
|
||||
def initialize(paths, calculate=false, &block)
|
||||
@paths = paths
|
||||
@block = block
|
||||
@last_update_at = updated_at if calculate
|
||||
end
|
||||
|
||||
def updated_at
|
||||
paths.map { |path| File.stat(path).mtime }.max
|
||||
end
|
||||
|
||||
def execute_if_updated
|
||||
current_update_at = self.updated_at
|
||||
if @last_update_at != current_update_at
|
||||
@last_update_at = current_update_at
|
||||
@block.call
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
56
activesupport/test/file_update_checker_test.rb
Normal file
56
activesupport/test/file_update_checker_test.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
require 'abstract_unit'
|
||||
require 'test/unit'
|
||||
require 'active_support'
|
||||
require 'fileutils'
|
||||
|
||||
MTIME_FIXTURES_PATH = File.expand_path("../fixtures", __FILE__)
|
||||
|
||||
class FileUpdateCheckerTest < Test::Unit::TestCase
|
||||
FILES = %w(1.txt 2.txt 3.txt)
|
||||
|
||||
def setup
|
||||
FileUtils.touch(FILES)
|
||||
end
|
||||
|
||||
def teardown
|
||||
FileUtils.rm(FILES)
|
||||
end
|
||||
|
||||
def test_should_not_execute_the_block_if_no_paths_are_given
|
||||
i = 0
|
||||
checker = ActiveSupport::FileUpdateChecker.new([]){ i += 1 }
|
||||
checker.execute_if_updated
|
||||
assert_equal 0, i
|
||||
end
|
||||
|
||||
def test_should_invoke_the_block_on_first_call_if_it_does_not_calculate_last_updated_at_on_load
|
||||
i = 0
|
||||
checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
|
||||
checker.execute_if_updated
|
||||
assert_equal 1, i
|
||||
end
|
||||
|
||||
def test_should_not_invoke_the_block_on_first_call_if_it_calculates_last_updated_at_on_load
|
||||
i = 0
|
||||
checker = ActiveSupport::FileUpdateChecker.new(FILES, true){ i += 1 }
|
||||
checker.execute_if_updated
|
||||
assert_equal 0, i
|
||||
end
|
||||
|
||||
def test_should_not_invoke_the_block_if_no_file_has_changed
|
||||
i = 0
|
||||
checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
|
||||
5.times { checker.execute_if_updated }
|
||||
assert_equal 1, i
|
||||
end
|
||||
|
||||
def test_should_invoke_the_block_if_a_file_has_changed
|
||||
i = 0
|
||||
checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
|
||||
checker.execute_if_updated
|
||||
sleep(1)
|
||||
FileUtils.touch(FILES)
|
||||
checker.execute_if_updated
|
||||
assert_equal 2, i
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue