Refactor new interactor/listener mechanic now it's
look pretty. Specs still need some love :)
This commit is contained in:
parent
e752dbe1c1
commit
3717179591
102
lib/guard.rb
102
lib/guard.rb
@ -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.")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -3,7 +3,6 @@ module Guard
|
||||
|
||||
def initialize(*)
|
||||
super
|
||||
|
||||
@inotify = INotify::Notifier.new
|
||||
@files = []
|
||||
@latency = 0.5
|
||||
|
@ -3,7 +3,6 @@ module Guard
|
||||
|
||||
def initialize(*)
|
||||
super
|
||||
|
||||
@fchange = FChange::Notifier.new
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user