FilePathsBase.jl icon indicating copy to clipboard operation
FilePathsBase.jl copied to clipboard

Should `readdir` return a path?

Open oxinabox opened this issue 6 years ago • 7 comments

It is kind of annoying that I can't do readdir.(readdir(somepath)) to exact the 2 level hierachy.

One solution to this would be for readdir to always return a path type. Wether this is a fully qualified path of the same type as its input, or wether it is some kind of PathPart{<:AbstractPath} <:AbstractPath type that both Strings into just the last component, but readdirs as a fully path using a remembered parent, or some other solution I am not sure.

oxinabox avatar Jan 28 '19 11:01 oxinabox

This seems related to https://github.com/rofinn/FilePathsBase.jl/issues/20. I think the current behaviour of readdir is correct in that it just returns the basename paths, similar to how it works in base julia:

julia> readdir(cwd())
8-element Array{PosixPath,1}:
 p".git"
 p".travis.yml"
 p"LICENSE.md"
 p"README.md"
 p"REQUIRE"
 p"appveyor.yml"
 p"src"
 p"test"

julia> readdir(pwd())
8-element Array{String,1}:
 ".git"
 ".travis.yml"
 "LICENSE.md"
 "README.md"
 "REQUIRE"
 "appveyor.yml"
 "src"
 "test"

To do what you're proposing you probably want to write.

readdir.(joinpath.(Ref(somepath), readdir(somepath)))

Better support for directory walking and globbing would probably help with these kinds of operations though.

rofinn avatar Jan 30 '19 20:01 rofinn

I agree it alighs with Base julia, but can we do better?

One option we could have that I alluded to is

struct SubPath{T,S}
    part::S
    parent::T
end

returned by readdir, with the properties such as

string(p::SubPath) = print(io, p::SubPath) = print(io, p.part) open(p::SubPath,args...) = open(p.parent, args...)

joinpath(p::SubPath, x) = joinpath(p.parent, x) joinpath(x, p::SubPath) = joinpath(x, p.part)

This could be pretty cool, I think. It might be a nicer structure to actually use for walking around (I find walkdir kinda annoying most of the time) Though I am not 100% on it, it would take some playing with I think.

oxinabox avatar Jan 30 '19 20:01 oxinabox

Hmmm, I did want to do something similar for a restricted/sandboxed path type which would essentially work like a chroot:

struct RestrictedPath{P<:AbstractPath} <: Abstractpath
    parent::P
    parts
end

It would have special rules to prevent you from operating outside of the parent path.

Would it make sense for SubPath to work more like SubString and just store an index into the parent.parts?

rofinn avatar Jan 30 '19 21:01 rofinn

Would it make sense for SubPath to work more like SubString and just store an index into the parent.parts?

I was thinking that, but didn't want to complicate the example.

oxinabox avatar Jan 30 '19 21:01 oxinabox

This kind of reminds me of Haskell's path library http://hackage.haskell.org/package/path

(not that I've used it).

which divides path types into Absolute and Relative.

oxinabox avatar Jan 30 '19 21:01 oxinabox

join=true helps a lot with this, at least from experience with AWSS3 (ref #110)

ericphanson avatar Nov 16 '21 11:11 ericphanson

For now, I think I'm gonna support join and sort for both readdir/readpath. The distinction between those two functions will simply be:

  1. Return strings vs paths
  2. Default values for join to avoid a breaking changes

Since readdir now supports more of what readpath does, I may introduce a breaking release in readpath is deprecated and the readdir output is simply determined by the input as suggested here, so we aren't introducing unnecessary type instabilities.

rofinn avatar Nov 18 '21 17:11 rofinn