diff --git a/lib/guard/listener.rb b/lib/guard/listener.rb index e1df894..9ea5948 100644 --- a/lib/guard/listener.rb +++ b/lib/guard/listener.rb @@ -8,7 +8,7 @@ module Guard autoload :Polling, 'guard/listeners/polling' class Listener - attr_reader :last_event + attr_reader :last_event, :sha1_checksums_hash def self.select_and_init if mac? && Darwin.usable? @@ -24,6 +24,7 @@ module Guard end def initialize + @sha1_checksums_hash = {} update_last_event end @@ -32,7 +33,7 @@ module Guard end def modified_files(dirs, options = {}) - files = potentially_modified_files(dirs, options).select { |path| File.file?(path) && recent_file?(path) } + files = potentially_modified_files(dirs, options).select { |path| File.file?(path) && file_modified?(path) && file_content_modified?(path) } files.map! { |file| file.gsub("#{Dir.pwd}/", '') } end @@ -43,12 +44,24 @@ module Guard Dir.glob(dirs.map { |dir| "#{dir}#{match}" }) end - def recent_file?(file) - File.mtime(file) >= last_event + def file_modified?(path) + # Depending on the filesystem, mtime is probably only precise to the second, so round + # both values down to the second for the comparison. + File.mtime(path).to_i >= last_event.to_i rescue false end + def file_content_modified?(path) + sha1_checksum = Digest::SHA1.file(path).to_s + if sha1_checksums_hash[path] != sha1_checksum + @sha1_checksums_hash[path] = sha1_checksum + true + else + false + end + end + def self.mac? Config::CONFIG['target_os'] =~ /darwin/i end diff --git a/spec/guard/listener_spec.rb b/spec/guard/listener_spec.rb index 5d09104..5a62f43 100644 --- a/spec/guard/listener_spec.rb +++ b/spec/guard/listener_spec.rb @@ -35,7 +35,7 @@ describe Guard::Listener do it "updates last_event with time.now" do time = Time.now subject.update_last_event - subject.last_event.should >= time + subject.last_event.to_i.should >= time.to_i end end