From 8da8f6a33def410147a5f3eb4f3beb91c4d1faa4 Mon Sep 17 00:00:00 2001 From: Darren Pearce Date: Tue, 23 Aug 2011 10:07:23 -0600 Subject: [PATCH] added optional support for watching deletions and with that comes file moves --- bin/guard | 2 +- lib/guard.rb | 23 +++++++++++++++++++---- lib/guard/cli.rb | 1 + lib/guard/guard.rb | 4 ++++ lib/guard/listener.rb | 23 +++++++++++++++++------ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/bin/guard b/bin/guard index d30b664..ff51a7d 100755 --- a/bin/guard +++ b/bin/guard @@ -3,4 +3,4 @@ require 'guard' require 'guard/cli' -Guard::CLI.start \ No newline at end of file +Guard::CLI.start diff --git a/lib/guard.rb b/lib/guard.rb index 701d428..4aea6e9 100644 --- a/lib/guard.rb +++ b/lib/guard.rb @@ -14,10 +14,11 @@ module Guard # initialize this singleton def setup(options = {}) @options = options - @listener = Listener.select_and_init(@options[:watchdir] ? File.expand_path(@options[:watchdir]) : Dir.pwd) + @listener = Listener.select_and_init(@options[:watchdir] ? File.expand_path(@options[:watchdir]) : Dir.pwd,options) @groups = [:default] @guards = [] + @watch_deletions = options[:deletions] @options[:notify] && ENV["GUARD_NOTIFY"] != 'false' ? Notifier.turn_on : Notifier.turn_off UI.clear if @options[:clear] @@ -46,10 +47,24 @@ module Guard def run_on_change_for_all_guards(files) guards.each do |guard| + #UI.debug "files: #{files.inspect}" 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) + if @watch_deletions + unless paths.empty? + UI.debug "#{guard.class.name}#run_on_change with #{paths.inspect}" + supervised_task(guard, :run_on_change, paths.select {|f| !f.start_with?('!') }) + deletions = paths.collect { |f| f.slice(1..-1) if f.start_with?('!') }.compact + end + + unless deletions.empty? + UI.debug "#{guard.class.name}#run_on_deletion with #{deletions.inspect}" + supervised_task(guard, :run_on_deletion, deletions) + end + else + unless paths.empty? + UI.debug "#{guard.class.name}#run_on_change with #{paths.inspect}" + supervised_task(guard, :run_on_change, paths) + end end end diff --git a/lib/guard/cli.rb b/lib/guard/cli.rb index dc539f0..f189b63 100644 --- a/lib/guard/cli.rb +++ b/lib/guard/cli.rb @@ -11,6 +11,7 @@ module Guard method_option :group, :type => :array, :default => [], :aliases => '-g', :banner => "Run only the passed groups" method_option :watchdir, :type => :string, :aliases => '-w', :banner => "Specify the directory to watch" method_option :guardfile, :type => :string, :aliases => '-G', :banner => "Specify a Guardfile" + method_option :deletions, :type => :boolean, :default => false, :aliases => '-D', :banner => "Watch for deleted files" desc "start", "Starts Guard" def start diff --git a/lib/guard/guard.rb b/lib/guard/guard.rb index aed9bc9..a316d51 100644 --- a/lib/guard/guard.rb +++ b/lib/guard/guard.rb @@ -53,5 +53,9 @@ module Guard true end + def run_on_deletion(paths) + true + end + end end diff --git a/lib/guard/listener.rb b/lib/guard/listener.rb index b3bf224..e9f5a46 100644 --- a/lib/guard/listener.rb +++ b/lib/guard/listener.rb @@ -29,12 +29,14 @@ module Guard @directory = directory.to_s @sha1_checksums_hash = {} @relativize_paths = options.fetch(:relativize_paths, true) - @cached_files = all_files + @watch_deletions = options.deletions update_last_event end def start watch(@directory) + # populate initial sha1 hash to watch for deleted or moved files + all_files.each {|path| set_sha1_checksums_hash(path, sha1_checksum(path))} if @watch_deletions end def stop @@ -49,10 +51,17 @@ module Guard end def modified_files(dirs, options={}) - files = potentially_modified_files(dirs, options).select { |path| file_modified?(path) } - deleted_files = @cached_files.collect { |path| "!#{path}" unless File.exists?(path) }.compact - files.concat(deleted_files) - @cached_files = all_files + files = [] + if @watch_deletions + deleted_files = @sha1_checksums_hash.collect do |path, sha1| + unless File.exists?(path) + @sha1_checksums_hash.delete(path) + "!#{path}" + end + end + files.concat(deleted_files.compact) + end + files.concat(potentially_modified_files(dirs, options).select { |path| file_modified?(path) }) update_last_event relativize_paths(files) end @@ -74,7 +83,7 @@ module Guard def relativize_paths(paths) return paths unless relativize_paths? paths.map do |path| - path.gsub(%r{^#{@directory}/}, '') + path.gsub(%r{#{@directory}/}, '') end end @@ -111,6 +120,8 @@ module Guard elsif File.mtime(path).to_i > @last_event.to_i set_sha1_checksums_hash(path, sha1_checksum(path)) true + elsif @watch_deletions + file_content_modified?(path, sha1_checksum(path)) end rescue false