diff options
author | Xavier Noria <fxn@hashref.com> | 2015-10-12 20:41:14 +0200 |
---|---|---|
committer | Xavier Noria <fxn@hashref.com> | 2015-11-08 22:49:49 -0800 |
commit | 785adabc4b8d892b6e06fca2f259e9c5147e9ca5 (patch) | |
tree | 3f6aa360466928f1ecbe59870944d879abb454c4 /activesupport/lib | |
parent | 823d3a8de0ccfe2301e51ac1e06e106035edb8e6 (diff) | |
download | rails-785adabc4b8d892b6e06fca2f259e9c5147e9ca5.tar.gz rails-785adabc4b8d892b6e06fca2f259e9c5147e9ca5.tar.bz2 rails-785adabc4b8d892b6e06fca2f259e9c5147e9ca5.zip |
implements an evented file update checker [Puneet Agarwal]
This is the implementation of the file update checker written
by Puneet Agarwal for GSoC 2015 (except for the tiny version
of the listen gem, which was 3.0.2 in the original patch).
Puneet's branch became too out of sync with upstream. This is
the final work in one single clean commit.
Credit goes in the first line using a convention understood
by the contrib app.
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support.rb | 1 | ||||
-rw-r--r-- | activesupport/lib/active_support/file_evented_update_checker.rb | 67 |
2 files changed, 68 insertions, 0 deletions
diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 63277a65b4..3a2a7d28cb 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -34,6 +34,7 @@ module ActiveSupport autoload :Dependencies autoload :DescendantsTracker autoload :FileUpdateChecker + autoload :FileEventedUpdateChecker autoload :LogSubscriber autoload :Notifications diff --git a/activesupport/lib/active_support/file_evented_update_checker.rb b/activesupport/lib/active_support/file_evented_update_checker.rb new file mode 100644 index 0000000000..d45576bb00 --- /dev/null +++ b/activesupport/lib/active_support/file_evented_update_checker.rb @@ -0,0 +1,67 @@ +require 'listen' + +module ActiveSupport + class FileEventedUpdateChecker + attr_reader :listener + def initialize(files, directories={}, &block) + @files = files.map { |f| File.expand_path(f)}.to_set + @dirs = Hash.new + directories.each do |key,value| + @dirs[File.expand_path(key)] = Array(value) if !Array(value).empty? + end + @block = block + @modified = false + watch_dirs = base_directories + @listener = Listen.to(*watch_dirs,&method(:changed)) if !watch_dirs.empty? + @listener.start if @listener + end + + def updated? + @modified + end + + def execute + @block.call + ensure + @modified = false + end + + def execute_if_updated + if updated? + execute + true + else + false + end + end + + private + + def watching?(file) + return true if @files.include?(file) + cfile = file + while !cfile.eql? "/" + cfile = File.expand_path("#{cfile}/..") + if !@dirs[cfile].nil? and file.end_with?(*(@dirs[cfile].map {|ext| ".#{ext.to_s}"})) + return true + end + end + false + end + + def changed(modified, added, removed) + return if updated? + if (modified + added + removed).any? { |f| watching? f } + @modified = true + end + end + + def base_directories + (@files.map { |f| existing_parent(File.expand_path("#{f}/..")) } + @dirs.keys.map {|dir| existing_parent(dir)}).uniq + end + + def existing_parent(path) + File.exist?(path) ? path : existing_parent(File.expand_path("#{path}/..")) + end + end +end |