diff options
author | José Valim <jose.valim@gmail.com> | 2011-12-12 22:51:33 +0100 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2011-12-12 22:54:04 +0100 |
commit | fa1d9a884c0d5b70c97442e3360ac98ca5fa4340 (patch) | |
tree | e39e017a9de2936a87f3b9ecf1d14b6febd0a8f1 /activesupport | |
parent | 62cda03fa824ce1e1fc92aaee0367c29ade6a504 (diff) | |
download | rails-fa1d9a884c0d5b70c97442e3360ac98ca5fa4340.tar.gz rails-fa1d9a884c0d5b70c97442e3360ac98ca5fa4340.tar.bz2 rails-fa1d9a884c0d5b70c97442e3360ac98ca5fa4340.zip |
Speed up development by only reloading classes if dependencies files changed.
This can be turned off by setting `config.reload_classes_only_on_change` to false.
Extensions like Active Record should add their respective files like db/schema.rb and db/structure.sql to `config.watchable_files` if they want their changes to affect classes reloading.
Thanks to https://github.com/paneq/active_reload and Pastorino for the inspiration. <3
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/file_update_checker.rb | 43 | ||||
-rw-r--r-- | activesupport/lib/active_support/i18n_railtie.rb | 3 | ||||
-rw-r--r-- | activesupport/test/file_update_checker_test.rb | 13 |
3 files changed, 48 insertions, 11 deletions
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb index 77bc5388d6..4137bbf6a0 100644 --- a/activesupport/lib/active_support/file_update_checker.rb +++ b/activesupport/lib/active_support/file_update_checker.rb @@ -39,30 +39,53 @@ module ActiveSupport @paths = paths @glob = compile_glob(@paths.extract_options!) @block = block + @updated_at = nil @last_update_at = calculate ? updated_at : nil end - def updated_at - all = [] - all.concat @paths - all.concat Dir[@glob] if @glob - all.map { |path| File.mtime(path) }.max + # Check if any of the entries were updated. If so, the updated_at + # value is cached until flush! is called. + def updated? + current_updated_at = updated_at + if @last_update_at != current_updated_at + @updated_at = updated_at + true + else + false + end end + # Flush the cache so updated? is calculated again + def flush! + @updated_at = nil + end + + # Execute the block given if updated. This call + # always flush the cache. def execute_if_updated - current_update_at = self.updated_at - if @last_update_at != current_update_at - @last_update_at = current_update_at + if updated? + @last_update_at = updated_at @block.call true else false end + ensure + flush! end private - def compile_glob(hash) + def updated_at #:nodoc: + @updated_at || begin + all = [] + all.concat @paths + all.concat Dir[@glob] if @glob + all.map { |path| File.mtime(path) }.max + end + end + + def compile_glob(hash) #:nodoc: return if hash.empty? globs = [] hash.each do |key, value| @@ -71,7 +94,7 @@ module ActiveSupport "{#{globs.join(",")}}" end - def compile_ext(array) + def compile_ext(array) #:nodoc: array = Array.wrap(array) return if array.empty? ".{#{array.join(",")}}" diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb index 4c59fe9ac9..a989ff8f57 100644 --- a/activesupport/lib/active_support/i18n_railtie.rb +++ b/activesupport/lib/active_support/i18n_railtie.rb @@ -17,7 +17,8 @@ module I18n # point, no path was added to the reloader, I18n.reload! is not triggered # on to_prepare callbacks. This will only happen on the config.after_initialize # callback below. - initializer "i18n.callbacks" do + initializer "i18n.callbacks" do |app| + app.reloaders << I18n::Railtie.reloader ActionDispatch::Reloader.to_prepare do I18n::Railtie.reloader.execute_if_updated end diff --git a/activesupport/test/file_update_checker_test.rb b/activesupport/test/file_update_checker_test.rb index a5a9b7a682..52c1f3260d 100644 --- a/activesupport/test/file_update_checker_test.rb +++ b/activesupport/test/file_update_checker_test.rb @@ -54,6 +54,19 @@ class FileUpdateCheckerWithEnumerableTest < Test::Unit::TestCase assert_equal 1, i end + def test_should_cache_updated_result_until_flushed + i = 0 + checker = ActiveSupport::FileUpdateChecker.new(FILES, true){ i += 1 } + assert !checker.updated? + + sleep(1) + FileUtils.touch(FILES) + + assert checker.updated? + assert checker.execute_if_updated + assert !checker.updated? + end + def test_should_invoke_the_block_if_a_watched_dir_changed_its_glob i = 0 checker = ActiveSupport::FileUpdateChecker.new([{"tmp_watcher" => [:txt]}], true){ i += 1 } |