diff --git a/src/API.jl b/src/API.jl index 1adcbaef1f..49ae21936e 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1046,18 +1046,33 @@ function gc(ctx::Context = Context(); collect_delay::Union{Period, Nothing} = no end end - # Delete any files that could not be rm-ed and were specially moved to the delayed delete directory. - # Do this silently because it's out of scope for Pkg.gc() but it's helpful to use this opportunity to do it - if isdefined(Base.Filesystem, :delayed_delete_dir) - if isdir(Base.Filesystem.delayed_delete_dir()) - for p in readdir(Base.Filesystem.delayed_delete_dir(), join = true) + # Delete anything that could not be rm-ed and was specially recorded in the delayed delete reference folder. + # Do this silently because it's out of scope for Pkg.gc() but it's helpful to use this opportunity to do it. + if isdefined(Base.Filesystem, :delayed_delete_ref) + delayed_delete_ref_path = Base.Filesystem.delayed_delete_ref() + if isdir(delayed_delete_ref_path) + delayed_delete_dirs = Set{String}() + for f in readdir(delayed_delete_ref_path; join = true) try + p = readline(f) + push!(delayed_delete_dirs, dirname(p)) Base.Filesystem.prepare_for_deletion(p) Base.rm(p; recursive = true, force = true, allow_delayed_delete = false) + Base.rm(f) catch e @debug "Failed to delete $p" exception = e end end + for dir in delayed_delete_dirs + if basename(dir) == "julia_delayed_deletes" && isempty(readdir(dir)) + Base.Filesystem.prepare_for_deletion(dir) + Base.rm(dir; recursive = true) + end + end + if isempty(readdir(delayed_delete_ref_path)) + Base.Filesystem.prepare_for_deletion(delayed_delete_ref_path) + Base.rm(delayed_delete_ref_path; recursive = true) + end end end diff --git a/test/pkg.jl b/test/pkg.jl index 91206c93a7..07fe417a30 100644 --- a/test/pkg.jl +++ b/test/pkg.jl @@ -694,6 +694,27 @@ end end end +if isdefined(Base.Filesystem, :delayed_delete_ref) + @testset "Pkg.gc for delayed deletes" begin + mktempdir() do root + dir = joinpath(root, "julia_delayed_deletes") + mkdir(dir) + testfile = joinpath(dir, "testfile") + write(testfile, "foo bar") + delayed_delete_ref_path = Base.Filesystem.delayed_delete_ref() + mkpath(delayed_delete_ref_path) + ref = tempname(delayed_delete_ref_path; cleanup = false) + write(ref, testfile) + @test isfile(testfile) + Pkg.gc() + @test !ispath(testfile) + @test !ispath(dir) + @test !ispath(ref) + @test !ispath(delayed_delete_ref_path) || !isempty(readdir(delayed_delete_ref_path)) + end + end +end + #issue #876 @testset "targets should survive add/rm" begin temp_pkg_dir() do project_path