Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Integrating ruby-fsevent; first pass - sloppy

  • Loading branch information...
commit b2136341a06e0fb50117ee887cf3b98298301c96 1 parent 77bd4cc
@sandro sandro authored mynyml committed
View
0  bin/m
No changes.
View
2  bin/watchr
@@ -4,7 +4,7 @@ require 'pathname'
require 'optparse'
require 'tempfile'
-require 'watchr'
+require File.dirname(__FILE__) + '/../lib/watchr'
module Watchr
# Namespaced to avoid defining global methods
View
18 lib/watchr.rb
@@ -12,10 +12,19 @@
# # on command line, from project's root dir
# $ watchr path/to/script
#
+$LOAD_PATH.unshift(File.dirname(__FILE__))
module Watchr
VERSION = '0.6'
begin
+ begin require 'rubygems'; rescue LoadError; end
+ require 'fsevent'
+ HAVE_FSE = true
+ rescue LoadError, RuntimeError
+ HAVE_FSE = false
+ end
+
+ begin
require 'rev'
HAVE_REV = true
rescue LoadError, RuntimeError
@@ -29,6 +38,7 @@ module EventHandler
autoload :Base, 'watchr/event_handlers/base'
autoload :Unix, 'watchr/event_handlers/unix' if ::Watchr::HAVE_REV
autoload :Portable, 'watchr/event_handlers/portable'
+ autoload :FSE, 'watchr/event_handlers/fse' if ::Watchr::HAVE_FSE
end
class << self
@@ -99,11 +109,15 @@ def debug(msg)
#
def handler
@handler ||=
- case ENV['HANDLER'] || Config::CONFIG['host_os']
+ case check_handler = ENV['HANDLER'] || Config::CONFIG['host_os']
when /mswin|windows|cygwin/i
Watchr::EventHandler::Portable
when /sunos|solaris|darwin|mach|osx|bsd|linux/i, 'unix'
- if ::Watchr::HAVE_REV
+ Watchr.debug ENV['HANDLER']
+ Watchr.debug check_handler
+ if ::Watchr::HAVE_FSE && check_handler =~ /osx|darwin/
+ Watchr::EventHandler::FSE
+ elsif ::Watchr::HAVE_REV
Watchr::EventHandler::Unix
else
Watchr.debug "rev not found. `gem install rev` to get evented handler"
View
5 lib/watchr/controller.rb
@@ -31,6 +31,7 @@ class Controller
def initialize(script, handler)
@script, @handler = script, handler
@handler.add_observer(self)
+ @handler.controller = self
Watchr.debug "using %s handler" % handler.class.name
end
@@ -66,6 +67,10 @@ def update(path, event_type = nil)
end
end
+ def update_monitored_paths
+ @handler.refresh(monitored_paths)
+ end
+
# List of paths the script is monitoring.
#
# Basically this means all paths below current directoly recursivelly that
View
106 lib/watchr/event_handlers/fse.rb
@@ -0,0 +1,106 @@
+module Watchr
+ module EventHandler
+ class FSEWatcher < ::FSEvent
+ attr_reader :handler
+
+ def initialize(handler)
+ super()
+ @handler = handler
+ self.latency = 0.2
+ end
+
+ def on_change(dirs)
+ handler.on_change(dirs)
+ end
+ end
+
+ class FSE
+ include Base
+
+ attr_reader :watcher, :path_stats, :monitored_paths
+ attr_accessor :controller
+
+ def initialize
+ @watcher = FSEWatcher.new(self)
+ @path_stats = {}
+ end
+
+ def on_change(dirs)
+ update_monitored_paths
+ watch_monitored_paths
+ dirs.each do |dir|
+ Watchr.debug "change in #{dir}"
+ changed_pathname = Pathname(dir)
+ monitored_paths.each do |pathname|
+ if pathname.dirname.basename == changed_pathname.basename
+ type = detect_change(pathname)
+ if type
+ Watchr.debug type
+ notify(pathname, type)
+ update_path_stats(pathname) unless type == :deleted
+ end
+ end
+ end
+ end
+ end
+
+ def listen(monitored_paths)
+ @monitored_paths = monitored_paths
+ watch_monitored_paths
+ @watcher.start
+ end
+
+ def refresh(monitored_paths)
+ @monitored_paths = monitored_paths
+ watch_monitored_paths
+ end
+
+ protected
+
+ def watch_monitored_paths
+ init_path_stats
+ paths = monitored_paths.map {|p| p.dirname.to_s}.uniq
+ @watcher.watch_directories(paths)
+ end
+
+ def init_path_stats
+ now = Time.now
+ monitored_paths.each do |pathname|
+ unless path_stats[pathname]
+ path_stats[pathname] = {:mtime => now, :atime => now, :ctime => now}
+ end
+ end
+ end
+
+ def detect_change(pathname)
+ return :deleted if !pathname.exist?
+ return :modified if pathname.mtime > mtime(pathname)
+ return :accessed if pathname.atime > atime(pathname)
+ return :changed if pathname.ctime > ctime(pathname)
+ end
+
+ def update_monitored_paths
+ @monitored_paths = controller.monitored_paths
+ end
+
+ def update_path_stats(pathname)
+ path_stats[pathname][:mtime] = pathname.mtime
+ path_stats[pathname][:atime] = pathname.atime
+ path_stats[pathname][:ctime] = pathname.ctime
+ end
+
+ def mtime(pathname)
+ path_stats[pathname][:mtime]
+ end
+
+ def atime(pathname)
+ path_stats[pathname][:atime]
+ end
+
+ def ctime(pathname)
+ path_stats[pathname][:ctime]
+ end
+ end
+ end
+end
+
Please sign in to comment.
Something went wrong with that request. Please try again.