diff --git a/src/path.jl b/src/path.jl index f21244f..e1422f9 100644 --- a/src/path.jl +++ b/src/path.jl @@ -687,8 +687,8 @@ Download a file from the remote `url` and save it to the `localfile` path. NOTE: Not downloading into a `localfile` directory matches the base Julia behaviour. https://github.com/rofinn/FilePathsBase.jl/issues/48 """ -function Base.download(url::AbstractString, localfile::P) where P <: AbstractPath - mktemp(P) do fp, io +function Base.download(url::AbstractString, localfile::AbstractPath) + mktmp() do fp, io download(url, fp) cp(fp, localfile; force=false) end @@ -767,26 +767,22 @@ Base.write(fp::AbstractPath, x) = open(io -> write(io, x), fp, "w") # Default `touch` will just write an empty string to a file Base.touch(fp::AbstractPath) = write(fp, "") -Base.tempname(::Type{<:AbstractPath}) = Path(tempname()) -tmpname() = tempname(SystemPath) - -Base.tempdir(::Type{<:AbstractPath}) = Path(tempdir()) -tmpdir() = tempdir(SystemPath) - -Base.mktemp(P::Type{<:AbstractPath}) = mktemp(tempdir(P)) -mktmp() = mktemp(SystemPath) - -Base.mktemp(fn::Function, P::Type{<:AbstractPath}) = mktemp(fn, tempdir(P)) -mktmp(fn::Function) = mktemp(fn, SystemPath) - -Base.mktempdir(P::Type{<:AbstractPath}) = mktempdir(tempdir(P)) -mktmpdir() = mktempdir(SystemPath) - -Base.mktempdir(fn::Function, P::Type{<:AbstractPath}) = mktempdir(fn, tempdir(P)) -mktmpdir(fn::Function) = mktempdir(fn, SystemPath) +Base.tempname(P::Type{<:AbstractPath}; kwargs...) = tempname(tempdir(P); kwargs...) +Base.mktemp(P::Type{<:AbstractPath}; kwargs...) = mktemp(tempdir(P); kwargs...) +Base.mktemp(fn::Function, P::Type{<:AbstractPath}; kwargs...) = mktemp(fn, tempdir(P); kwargs...) +Base.mktempdir(P::Type{<:AbstractPath}; kwargs...) = mktempdir(tempdir(P); kwargs...) +Base.mktempdir(fn::Function, P::Type{<:AbstractPath}; kwargs...) = mktempdir(fn, tempdir(P); kwargs...) + +function Base.tempname(parent::AbstractPath; prefix="jl_", cleanup=true) + isdir(parent) || throw(ArgumentError("$(repr(parent)) is not a directory")) + fp = parent / string(prefix, uuid1()) + @assert !exists(fp) + cleanup && temp_cleanup(fp) + return fp +end -function Base.mktemp(parent::AbstractPath) - fp = parent / string(uuid4()) +function Base.mktemp(parent::AbstractPath; kwargs...) + fp = tempname(parent; kwargs...) # touch the file in case `open` isn't implement for the path and # we're buffering locally. touch(fp) @@ -794,14 +790,14 @@ function Base.mktemp(parent::AbstractPath) return fp, io end -function Base.mktempdir(parent::AbstractPath) - fp = parent / string(uuid4()) +function Base.mktempdir(parent::AbstractPath; kwargs...) + fp = tempname(parent; kwargs...) mkdir(fp) return fp end -function Base.mktemp(fn::Function, parent::AbstractPath) - (tmp_fp, tmp_io) = mktmp(parent) +function Base.mktemp(fn::Function, parent::AbstractPath; kwargs...) + (tmp_fp, tmp_io) = mktemp(parent; kwargs...) try fn(tmp_fp, tmp_io) finally @@ -810,8 +806,8 @@ function Base.mktemp(fn::Function, parent::AbstractPath) end end -function Base.mktempdir(fn::Function, parent::AbstractPath) - tmpdir = mktmpdir(parent) +function Base.mktempdir(fn::Function, parent::AbstractPath; kwargs...) + tmpdir = mktmpdir(parent; kwargs...) try fn(tmpdir) finally @@ -819,8 +815,15 @@ function Base.mktempdir(fn::Function, parent::AbstractPath) end end -mktmp(arg1, args...) = mktemp(arg1, args...) -mktmpdir(arg1, args...) = mktempdir(arg1, args...) +mktmp(arg1, args...; kwargs...) = mktemp(arg1, args...; kwargs...) +mktmpdir(arg1, args...; kwargs...) = mktempdir(arg1, args...; kwargs...) + +function temp_cleanup(fp::AbstractPath) + atexit() do + # Might not work in all cases, but default to recursively deleting the path on exit + rm(fp; force=true, recursive=true) + end +end """ isdescendant(fp::P, asc::P) where {P <: AbstractPath} -> Bool diff --git a/src/system.jl b/src/system.jl index 3eaf438..7430102 100644 --- a/src/system.jl +++ b/src/system.jl @@ -113,8 +113,8 @@ function isexecutable(fp::SystemPath) return ( isexecutable(s.mode, :ALL) || isexecutable(s.mode, :OTHER) || - ( usr.uid == s.user.uid && isexecutable(s.mode, :USER) ) || - ( usr.gid == s.group.gid && isexecutable(s.mode, :GROUP) ) + (usr.uid == s.user.uid && isexecutable(s.mode, :USER)) || + (usr.gid == s.group.gid && isexecutable(s.mode, :GROUP)) ) end @@ -130,8 +130,8 @@ function Base.iswritable(fp::SystemPath) return ( iswritable(s.mode, :ALL) || iswritable(s.mode, :OTHER) || - ( usr.uid == s.user.uid && iswritable(s.mode, :USER) ) || - ( usr.gid == s.group.gid && iswritable(s.mode, :GROUP) ) + (usr.uid == s.user.uid && iswritable(s.mode, :USER)) || + (usr.gid == s.group.gid && iswritable(s.mode, :GROUP)) ) end @@ -147,8 +147,8 @@ function Base.isreadable(fp::SystemPath) return ( isreadable(s.mode, :ALL) || isreadable(s.mode, :OTHER) || - ( usr.uid == s.user.uid && isreadable(s.mode, :USER) ) || - ( usr.gid == s.group.gid && isreadable(s.mode, :GROUP) ) + (usr.uid == s.user.uid && isreadable(s.mode, :USER)) || + (usr.gid == s.group.gid && isreadable(s.mode, :GROUP)) ) end @@ -184,7 +184,7 @@ function Base.cd(fn::Function, dir::SystemPath) try cd(dir) fn() - finally + finally cd(old) end end @@ -198,17 +198,17 @@ function Base.mkdir(fp::T; mode=0o777, recursive=false, exist_ok=false) where T< end else if hasparent(fp) && !exists(parent(fp)) - if recursive - mkdir(parent(fp); mode=mode, recursive=recursive, exist_ok=exist_ok) - else - error( - "The parent of $fp does not exist. " * - "Pass recursive=true to create it." - ) - end + if recursive + mkdir(parent(fp); mode=mode, recursive=recursive, exist_ok=exist_ok) + else + error( + "The parent of $fp does not exist. " * + "Pass recursive=true to create it." + ) + end end - return parse(T, mkdir(string(fp), mode=mode)) + return parse(T, mkdir(string(fp), mode=mode)) end end @@ -231,13 +231,32 @@ end function Base.rm(fp::SystemPath; kwargs...) rm(string(fp); kwargs...) end + Base.touch(fp::T) where {T<:SystemPath} = parse(T, touch(string(fp))) -function Base.mktemp(parent::T) where T<:SystemPath - fp, io = mktemp(string(parent)) + +Base.tempdir(::Type{<:SystemPath}) = Path(tempdir()) +Base.tempname(::Type{<:SystemPath}) = Path(tempname()) + +function Base.tempname(parent::T; kwargs...) where {T<:SystemPath} + return parse(T, tempname(string(parent); kwargs...)) +end + +function Base.mktemp(parent::T; kwargs...) where {T<:SystemPath} + fp, io = mktemp(string(parent); kwargs...) return parse(T, fp), io end -Base.mktempdir(parent::T) where {T<:SystemPath}= parse(T, mktempdir(string(parent))) +function Base.mktempdir(parent::T; kwargs...) where {T<:SystemPath} + return parse(T, mktempdir(string(parent); kwargs...)) +end + +# Some extra default/utilityy functions +tmpdir() = tempdir(SystemPath) +tmpname(; kwargs...) = tempname(SystemPath; kwargs...) +mktmp() = mktemp(SystemPath) +mktmp(fn::Function) = mktemp(fn, SystemPath) +mktmpdir() = mktempdir(SystemPath) +mktmpdir(fn::Function) = mktempdir(fn, SystemPath) """ chown(fp::SystemPath, user::AbstractString, group::AbstractString; recursive=false) diff --git a/test/testpkg.jl b/test/testpkg.jl index 739d49c..267de56 100644 --- a/test/testpkg.jl +++ b/test/testpkg.jl @@ -70,5 +70,6 @@ Base.read(fp::TestPath) = read(test2posix(fp)) Base.write(fp::TestPath, x) = write(test2posix(fp), x) Base.chown(fp::TestPath, args...; kwargs...) = chown(test2posix(fp), args...; kwargs...) Base.chmod(fp::TestPath, args...; kwargs...) = chmod(test2posix(fp), args...; kwargs...) +Base.tempdir(::Type{TestPath}) = posix2test(tempdir(PosixPath)) end