From 318525719111edf6043f024ac6a5d906806cf2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20F=C3=A9votte?= Date: Tue, 26 May 2020 11:52:20 +0200 Subject: [PATCH] Fix test case for `entr` on directories This fixes uses of `entr` to watch directories, both when `Revise` watches directories (`watching_files[] = false`) and when it watches files (`watching_files[] = true`). Tests mirror those defined for `entr` on regular files, and check in particular that: - file creations, modifications and deletions in the directory are correctly detected; - clustered notifications trigger the callback only once; - empty directories are correctly handled (i.e. they remain in the watch list even when all files in them are deleted). Closes: #470 --- src/Revise.jl | 2 +- src/pkgs.jl | 6 +++- test/runtests.jl | 76 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/Revise.jl b/src/Revise.jl index c7108280..51978a55 100644 --- a/src/Revise.jl +++ b/src/Revise.jl @@ -661,7 +661,7 @@ function revise_file_queued(pkgdata::PkgData, file) dirfull, basename = splitdir(file) stillwatching = true while stillwatching - if !file_exists(file) + if !file_exists(file) && !isdir(file) with_logger(SimpleLogger(stderr)) do @warn "$file is not an existing file, Revise is not watching" end diff --git a/src/pkgs.jl b/src/pkgs.jl index c4986e4d..d0aa60a4 100644 --- a/src/pkgs.jl +++ b/src/pkgs.jl @@ -381,7 +381,11 @@ function watch_files_via_dir(dirname) wf = watched_files[dirname] for (file, id) in wf.trackedfiles fullpath = joinpath(dirname, file) - if !file_exists(fullpath) + if isdir(fullpath) + println("detected dir modification: $fullpath") + push!(latestfiles, file=>id) + continue + elseif !file_exists(fullpath) # File may have been deleted. But be very sure. sleep(0.1) if !file_exists(fullpath) diff --git a/test/runtests.jl b/test/runtests.jl index df66282d..f9c40e25 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3003,32 +3003,70 @@ do_test("entr") && @testset "entr" begin # Watch directories (#470) - dn = joinpath(tempdir(), randtmp()) - mkdir(dn) - fn = joinpath(dn, "trigger.txt") - open(fn, "w") do io - println(io, "blank") - end - counter = Ref(0) - stop = Ref(false) try - @sync begin + @sync let + srcdir = joinpath(tempdir(), randtmp()) + mkdir(srcdir) + + trigger = joinpath(srcdir, "trigger.txt") + + counter = Ref(0) + stop = Ref(false) + @async begin - entr([dn]) do + entr([srcdir]; pause=0.5) do counter[] += 1 - stop[] && error("stopping") + stop[] && error("stop watching directory") end end - sleep(mtimedelay) - touch(fn) - sleep(mtimedelay) - @test counter[] == 1 + sleep(1) + @test length(readdir(srcdir)) == 0 # directory should still be empty + @test counter[] == 1 # postpone=false + + # File creation + touch(trigger) + sleep(1) + @test counter[] == 2 + + # File modification + touch(trigger) + sleep(1) + @test counter[] == 3 + + # File deletion -> the directory should be empty again + rm(trigger) + sleep(1) + @test length(readdir(srcdir)) == 0 + @test counter[] == 4 + + # Two events in quick succession (w.r.t. the `pause` argument) + touch(trigger) # creation + sleep(0.1) + touch(trigger) # modification + sleep(1) + @test counter[] == 5 # Callback should have been called only once + + # Stop stop[] = true - touch(fn) - sleep(mtimedelay) + touch(trigger) + end + + # `entr` should have errored by now + @test false + catch err + while err isa CompositeException + err = err.exceptions[1] + @static if VERSION >= v"1.3.0-alpha.110" + if err isa TaskFailedException + err = err.task.exception + end + end + if err isa CapturedException + err = err.ex + end end - catch - @test counter[] == 2 + @test isa(err, ErrorException) + @test err.msg == "stop watching directory" end end