diff --git a/README.md b/README.md index 5b3b05a..210bf32 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,12 @@ $ guard --guardfile ~/.your_global_guardfile $ guard -G ~/.your_global_guardfile # shortcut ``` +Guard can optionally watch moved or deleted files with: + +``` bash +$ guard -D +``` + An exhaustive list of options is available with: ``` bash diff --git a/lib/guard/listener.rb b/lib/guard/listener.rb index b099770..84c49b2 100644 --- a/lib/guard/listener.rb +++ b/lib/guard/listener.rb @@ -30,14 +30,13 @@ module Guard @sha1_checksums_hash = {} @file_timestamp_hash = {} @relativize_paths = options.fetch(:relativize_paths, true) - @watch_deletions = options.fetch(:deletions, false) + @watch_deletions = options.fetch(:deletions, false) update_last_event end def start watch(@directory) - # populate initial sha1 hash to watch for deleted or moved files - all_files.each {|path| set_file_timestamp_hash(path, file_timestamp(path)) } if @watch_deletions + timestamp_files end def stop @@ -93,6 +92,11 @@ module Guard !!@relativize_paths end + def timestamp_files + # populate initial timestamp file hash to watch for deleted or moved files + all_files.each {|path| set_file_timestamp_hash(path, file_timestamp(path)) } if @watch_deletions + end + private def potentially_modified_files(dirs, options={}) @@ -123,11 +127,11 @@ module Guard set_sha1_checksums_hash(path, sha1_checksum(path)) true elsif @watch_deletions - ts = file_timestamp(path) - if ts != @file_timestamp_hash[path] - set_file_timestamp_hash(path, ts) - true - end + ts = file_timestamp(path) + if ts != @file_timestamp_hash[path] + set_file_timestamp_hash(path, ts) + true + end end rescue false diff --git a/spec/guard/listener_spec.rb b/spec/guard/listener_spec.rb index e9ae26b..55db0f6 100644 --- a/spec/guard/listener_spec.rb +++ b/spec/guard/listener_spec.rb @@ -81,6 +81,8 @@ describe Guard::Listener do let(:file1) { @fixture_path.join("folder1", "file1.txt") } let(:file2) { @fixture_path.join("folder1", "folder2", "file2.txt") } let(:file3) { @fixture_path.join("folder1", "deletedfile1.txt") } + let(:file4) { @fixture_path.join("folder1", "movedfile1.txt") } + let(:destfile) { @fixture_path.join("folder1", "folder2","movedfile1.txt") } before do subject.update_last_event @@ -102,7 +104,7 @@ describe Guard::Listener do end context "without updating the content" do - it "ignores the files for the second time" do + it "ignores the}fil)s for the second time" do FileUtils.touch([file1, file2, file3]) subject.modified_files([@fixture_path.join("folder1")], {}).should =~ ["spec/fixtures/folder1/deletedfile1.txt", "spec/fixtures/folder1/file1.txt"] subject.update_last_event @@ -125,6 +127,87 @@ describe Guard::Listener do sleep 1 end end + + context "without watch_deletions" do + + after { FileUtils.touch(file3) } + + it "defaults to false" do + subject.instance_variable_get(:@watch_deletions).should eql false + end + + it "it should not track deleted files" do + FileUtils.touch([file1, file2, file3]) + subject.modified_files([@fixture_path.join("folder1")], {}).should =~ ["spec/fixtures/folder1/deletedfile1.txt", "spec/fixtures/folder1/file1.txt"] + subject.update_last_event + FileUtils.rm(file3) + subject.modified_files([@fixture_path.join("folder1")], {}).should =~ [] + sleep 1 + end + end + + context "with watch_deletions" do + subject { described_class.new(Dir.pwd, :deletions=>true) } + + before :each do + subject.timestamp_files + sleep 1 + subject.update_last_event + end + + after :each do + FileUtils.touch([file1, file2, file3, file4]) + FileUtils.rm_f([destfile]) + end + + it "should be true when set" do + subject.instance_variable_get(:@watch_deletions).should eql true + end + + it "should track deleted files" do + FileUtils.touch([file1, file3]) + subject.modified_files([@fixture_path.join("folder1")], {}).should =~ + ["spec/fixtures/folder1/deletedfile1.txt", "spec/fixtures/folder1/file1.txt"] + + subject.update_last_event + FileUtils.remove_file(file3) + subject.modified_files([@fixture_path.join("folder1")], {}).should =~ + ["!spec/fixtures/folder1/deletedfile1.txt"] + end + + it "should track moved files" do + FileUtils.touch([file1, file3]) + subject.modified_files([@fixture_path.join("folder1")], {}).should =~ + ["spec/fixtures/folder1/deletedfile1.txt", "spec/fixtures/folder1/file1.txt"] + + subject.update_last_event + FileUtils.move(file4, destfile) + subject.modified_files([@fixture_path.join("folder1")], {}).should =~ + ["!spec/fixtures/folder1/movedfile1.txt"] + end + + it "should track deleted files with all option" do + FileUtils.touch([file1, file2]) + subject.modified_files([@fixture_path.join("folder1")], {:all=>true}).should =~ + ["spec/fixtures/folder1/file1.txt", "spec/fixtures/folder1/folder2/file2.txt"] + + subject.update_last_event + FileUtils.remove_file(file2) + subject.modified_files([@fixture_path.join("folder1")], {:all=>true}).should =~ + ["!spec/fixtures/folder1/folder2/file2.txt"] + end + + it "should track moved files with all option" do + FileUtils.touch([file1, file2]) + subject.modified_files([@fixture_path.join("folder1")], {:all=>true}).should =~ + ["spec/fixtures/folder1/file1.txt", "spec/fixtures/folder1/folder2/file2.txt"] + + subject.update_last_event + FileUtils.move(file4, destfile) + subject.modified_files([@fixture_path.join("folder1")], {:all=>true}).should =~ + ["!spec/fixtures/folder1/movedfile1.txt","spec/fixtures/folder1/folder2/movedfile1.txt"] + end + end end describe "working directory" do @@ -160,5 +243,4 @@ describe Guard::Listener do end end - end