Refactor new interactor/listener mechanic now it's

look pretty.
Specs still need some love :)
This commit is contained in:
Thibaud Guillaume-Gentil 2011-08-30 21:13:51 +02:00
parent e752dbe1c1
commit 3717179591
5 changed files with 112 additions and 120 deletions

View File

@ -9,15 +9,14 @@ module Guard
autoload :Notifier, 'guard/notifier'
class << self
attr_accessor :options, :guards, :listener, :interactor_thread
attr_accessor :options, :guards, :interactor, :listener
# initialize this singleton
def setup(options = {})
@options = options
@listener = Listener.select_and_init(@options[:watchdir] ? File.expand_path(@options[:watchdir]) : Dir.pwd)
@guards = []
@locked = false
@files = []
@options = options
@guards = []
@interactor = Interactor.new
@listener = Listener.select_and_init(@options[:watchdir] ? File.expand_path(@options[:watchdir]) : Dir.pwd)
@options[:notify] && ENV["GUARD_NOTIFY"] != 'false' ? Notifier.turn_on : Notifier.turn_off
@ -28,48 +27,69 @@ module Guard
end
def start(options = {})
# Interactor.init_signal_traps
setup(options)
Dsl.evaluate_guardfile(options)
listener.on_change do |files|
Dsl.reevaluate_guardfile if Watcher.match_guardfile?(files)
@files += files if Watcher.match_files?(guards, files)
end
UI.info "Guard is now watching at '#{listener.directory}'"
guards.each { |guard| supervised_task(guard, :start) }
Interactor.listen
Thread.new do
loop do
if @files != [] && !@listener_locked
files = @files.dup
@files.clear
run { run_on_change_for_all_guards(files) }
end
end
end
interactor.start
listener.start
end
def run_on_change_for_all_guards(files)
guards.each do |guard|
paths = Watcher.match_files(guard, files)
unless paths.empty?
UI.debug "#{guard.class.name}#run_on_change with #{paths.inspect}"
supervised_task(guard, :run_on_change, paths)
def stop
UI.info "Bye bye...", :reset => true
listener.stop
guards.each { |guard| supervised_task(guard, :stop) }
abort
end
def reload
run do
guards.each { |guard| supervised_task(guard, :reload) }
end
end
def run_all
run do
guards.each { |guard| supervised_task(guard, :run_all) }
end
end
def pause
if listener.locked
UI.info "Un-paused files modification listening", :reset => true
listener.clear_changed_files
listener.unlock
else
UI.info "Paused files modification listening", :reset => true
listener.lock
end
end
def run_on_change(files)
run do
guards.each do |guard|
paths = Watcher.match_files(guard, files)
unless paths.empty?
UI.debug "#{guard.class.name}#run_on_change with #{paths.inspect}"
supervised_task(guard, :run_on_change, paths)
end
end
end
end
# Reparse the whole directory to catch new files modified during the guards run
# new_modified_files = listener.modified_files([listener.directory], :all => true)
# if !new_modified_files.empty? && Watcher.match_files?(guards, new_modified_files)
# run { run_on_change_for_all_guards(new_modified_files) }
# end
def run
listener.lock
interactor.lock
UI.clear if options[:clear]
begin
yield
rescue Interrupt
end
interactor.unlock
listener.unlock
end
# Let a guard execute its task but
@ -84,18 +104,6 @@ module Guard
return ex
end
def run
@listener_locked = true
Interactor.lock
UI.clear if options[:clear]
# begin
yield
# rescue Interrupt
# end
Interactor.unlock
@listener_locked = false
end
def add_guard(name, watchers = [], options = {})
if name.downcase == 'ego'
UI.deprecation("Guard::Ego is now part of Guard. You can remove it from your Guardfile.")

View File

@ -1,29 +1,25 @@
module Guard
module Interactor
extend self
class Interactor
@@locked = false
def initialize
@locked = false
end
def listen
def start
return if ENV["GUARD_ENV"] == 'test'
Thread.new do
loop do
if (entry = $stdin.gets) && !@@locked
if (entry = $stdin.gets) && !@locked
entry.gsub! /\n/, ''
case entry
when 'quit', 'exit', 'q', 'e'
UI.info "Bye bye...", :reset => true
::Guard.listener.stop
::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :stop) }
abort
when 'stop', 'quit', 'exit', 's', 'q', 'e'
::Guard.stop
when 'reload', 'r', 'z'
::Guard.run do
::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :reload) }
end
else # run_all
::Guard.run do
::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :run_all) }
end
::Guard.reload
when 'pause', 'p'
::Guard.pause
else
::Guard.run_all
end
end
end
@ -31,59 +27,12 @@ module Guard
end
def lock
@@locked = true
end
def unlock
@@locked = false
@locked = true
end
def unlock
@locked = false
end
# def run_all
# ::Guard.run do
# ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :run_all) }
# end
# end
#
# def stop
# UI.info "Bye bye...", :reset => true
# ::Guard.listener.stop
# ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :stop) }
# abort
# end
#
# def reload
# ::Guard.run do
# ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :reload) }
# end
# end
#
# def self.init_signal_traps
# # Run all (Ctrl-\)
# if Signal.list.has_key?('QUIT')
# Signal.trap('QUIT') do
# run_all
# end
# else
# UI.info "Your system doesn't support QUIT signal, so Ctrl-\\ (Run all) won't work"
# end
#
# # Stop (Ctrl-C)
# if Signal.list.has_key?('INT')
# Signal.trap('INT') do
# stop
# end
# else
# UI.info "Your system doesn't support INT signal, so Ctrl-C (Stop) won't work"
# end
#
# # Reload (Ctrl-Z)
# if Signal.list.has_key?('TSTP')
# Signal.trap('TSTP') do
# reload
# end
# else
# UI.info "Your system doesn't support TSTP signal, so Ctrl-Z (Reload) won't work"
# end
#
# end
end
end

View File

@ -9,8 +9,8 @@ module Guard
autoload :Polling, 'guard/listeners/polling'
class Listener
attr_reader :directory
attr_reader :directory, :locked
def self.select_and_init(*a)
if mac? && Darwin.usable?
@ -29,16 +29,53 @@ module Guard
@directory = directory.to_s
@sha1_checksums_hash = {}
@relativize_paths = options.fetch(:relativize_paths, true)
@changed_files = []
@locked = false
update_last_event
start_reactor
end
def start_reactor
Thread.new do
loop do
if @changed_files != [] && !@locked
changed_files = @changed_files.dup
clear_changed_files
::Guard.run_on_change(changed_files)
else
sleep 0.1
end
end
end
end
def start
on_change do |files|
if Watcher.match_guardfile?(files)
Dsl.reevaluate_guardfile
end
if Watcher.match_files?(::Guard.guards, files)
@changed_files += files
end
end
watch(@directory)
end
def stop
end
def lock
@locked = true
end
def unlock
@locked = false
end
def clear_changed_files
@changed_files.clear
end
def on_change(&callback)
@callback = callback
end

View File

@ -3,7 +3,6 @@ module Guard
def initialize(*)
super
@inotify = INotify::Notifier.new
@files = []
@latency = 0.5

View File

@ -3,7 +3,6 @@ module Guard
def initialize(*)
super
@fchange = FChange::Notifier.new
end