Skip to content

Commit

Permalink
Cleaned up README docs and added Glob support.
Browse files Browse the repository at this point in the history
  • Loading branch information
rofinn committed Apr 27, 2020
1 parent c3aa1e6 commit a77d374
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 122 deletions.
7 changes: 6 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ version = "0.8.1"

[deps]
FilePathsBase = "48062228-2e41-5def-b9a4-89aafe57970f"
Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
URIParser = "30578b45-9adc-5946-b283-645ec420af67"

[compat]
FilePathsBase = "0.6, 0.7, 0.8"
FilePathsBase = "0.9"
Glob = "1"
MacroTools = "0.5"
Reexport = "0.2"
URIParser = "0.4"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
147 changes: 32 additions & 115 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,143 +3,60 @@
[![Build Status](https://travis-ci.org/rofinn/FilePaths.jl.svg?branch=master)](https://travis-ci.org/rofinn/FilePaths.jl)
[![codecov](https://codecov.io/gh/rofinn/FilePaths.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/rofinn/FilePaths.jl)

FilePaths.jl provides a type based approach to working with filesystem paths in julia.
[FilePathsBase.jl](https://github.com/rofinn/FilePathsBase.jl) provides a type based API for working with filesystem paths.
Please review the FilePathsBase [docs](https://rofinn.github.io/FilePathsBase.jl/stable/) for more info on working with the base filepath types.
FilePaths.jl extends FilePathsBase to provide easier interoperability with the rest of the Julia ecosystem.

## Intallation:
FilePaths.jl is registered, so you can to use `Pkg.add` to install it.

```julia
julia> Pkg.add("FilePaths")
```

## Usage:
```julia
julia> using FilePaths
julia> using FilePaths; using FilePathsBase: /
```

The first important difference about working with paths in FilePaths.jl is that a path is an immutable list (Tuple) of strings, rather than simple a string.

Path creation:
Globbing files:
```julia
julia> Path("~/repos/FilePaths.jl/")
Paths.PosixPath(("~","repos","FilePaths.jl",""))
```
or
```julia
julia> p"~/repos/FilePaths.jl/"
Paths.PosixPath(("~","repos","FilePaths.jl",""))
```
julia> using Glob

Human readable file status info:
```julia
julia> stat(p"README.md")
Status(
device = 16777220,
inode = 48428965,
mode = -rw-r--r--,
nlink = 1,
uid = 501,
gid = 20,
rdev = 0,
size = 1880 (1.8K),
blksize = 4096 (4.0K),
blocks = 8,
mtime = 2016-02-16T00:49:27,
ctime = 2016-02-16T00:49:27,
)
julia> glob("*test*.jl", p"test")
2-element Array{PosixPath,1}:
p"test/runtests.jl"
p"test/test_uri.jl"
```

Working with permissions:
URIParsing:
```julia
julia> m = mode(p"README.md")
-rw-r--r--

julia> m - readable(:ALL)
--w-------

julia> m + executable(:ALL)
-rwxr-xr-x

julia> chmod(p"README.md", "+x")

julia> mode(p"README.md")
-rwxr-xr-x

julia> chmod(p"README.md", m)

julia> m = mode(p"README.md")
-rw-r--r--

julia> chmod(p"README.md", user=(READ+WRITE+EXEC), group=(READ+WRITE), other=READ)

julia> mode(p"README.md")
-rwxrw-r--

julia> URI(cwd() / p"test/runtests.jl")
URI(file:///Users/rory/repos/FilePaths.jl/test/runtests.jl)
```

Writing `String` and `AbstractPath` compatible code:

Reading and writing directly to file paths:
```julia
julia> write(p"testfile", "foobar")
6

julia> read(p"testfile")
"foobar"
```
julia> FilePaths.@compat function myrelative(x::AbstractPath, y::AbstractPath)
return relative(x, y)
end
myrelative (generic function with 2 methods)

All the standard methods for working with paths in base julia exist in the FilePaths.jl. The following describes the rough mapping of method names. Use `?` at the REPL to get the documentation and arguments as they may be different than the base implementations.
julia> FilePaths.@compat function myjoin(x::P, y::String)::P where P <: AbstractPath
return x / y
end
myjoin (generic function with 2 methods)

Base | FilePaths.jl
--- | ---
pwd() | cwd()
homedir() | home()
cd() | cd()
joinpath() | joinpath()
basename() | basename()
splitext(basename())[1] | filename
splitext(basename())[2] | extension
N/A | extensions
ispath | exists
realpath | real
normpath | norm
abspath | abs
relpath | relative
stat | stat
lstat | lstat
filemode | mode
mtime | modified
ctime | created
isdir | isdir
isfile | isfile
islink | islink
issocket | issocket
isfifo | isfifo
ischardev | ischardev
isblockdev | isblockdev
isexecutable (deprecated) | isexecutable
iswritable (deprecated) | iswritable
isreadable (deprecated) | isreadable
ismount | ismount
isabspath | isabs
splitdrive()[1] | drive
N/A | root
expanduser | expanduser
mkdir | mkdir
mkpath | N/A (use mkdir)
symlink | symlink
cp | copy
mv | move
rm | remove
touch | touch
tempname | tmpname
tempdir | tmpdir
mktemp | mktmp
mktempdir | mktmpdir
chmod | chmod (recursive unix-only)
chown (unix only) | chown (unix only)
N/A | read
N/A | write
julia> myrelative(cwd(), home())
p"repos/FilePaths.jl"

## TODO:
* cross platform chmod and chown
julia> myrelative(pwd(), homedir())
p"repos/FilePaths.jl"

julia> myjoin(parent(cwd()), "FilePaths.jl")
p"/Users/rory/repos/FilePaths.jl"

julia> myjoin("/Users/rory/repos", "FilePaths.jl")
"/Users/rory/repos/FilePaths.jl"
```
6 changes: 4 additions & 2 deletions src/FilePaths.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ __precompile__()

module FilePaths

using Reexport, URIParser, MacroTools
using Glob, MacroTools, Reexport, URIParser
using Glob: GlobMatch
@reexport using FilePathsBase

include("uri.jl")
include("compat.jl")
include("glob.jl")
include("uri.jl")

end # end of module
2 changes: 1 addition & 1 deletion src/compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Wrapper method properties:
# Examples
```
julia> using FilePaths
julia> using FilePathsBase; using FilePathsBase: /; using FilePaths
julia> FilePaths.@compat function myrelative(x::AbstractPath, y::AbstractPath)
return relative(x, y)
Expand Down
5 changes: 5 additions & 0 deletions src/glob.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Base.readdir(pattern::GlobMatch, prefix::AbstractPath) = glob(pattern, prefix)

function Glob.glob(pattern, prefix::T) where T<:AbstractPath
return [parse(T, m) for m in glob(pattern, string(prefix))]
end
8 changes: 6 additions & 2 deletions test/compat.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module TestPkg

using FilePathsBase
using FilePathsBase: /
using FilePaths

# Test for basic definitions taking abstract paths
Expand Down Expand Up @@ -44,14 +46,16 @@ struct MyPath <: AbstractPath
end

__init__() = FilePathsBase.register(MyPath)
FilePathsBase.ispathtype(::Type{MyPath}, str::AbstractString) = startswith(str, "mypath://")
function Base.tryparse(::Type{MyPath}, str::AbstractString)
startswith(str, "mypath://") ? MyPath(str) : nothing
end

FilePaths.@compat mypath_testem(path::MyPath) = "**"*path.x

end # TestPkg module

@testset "@compat" begin
cd(abs(parent(Path(@__FILE__)))) do
cd(absolute(parent(Path(@__FILE__)))) do
reg = Sys.iswindows() ? "..\\src\\FilePaths.jl" : "../src/FilePaths.jl"
@test ispath(reg)
p = Path(reg)
Expand Down
4 changes: 4 additions & 0 deletions test/glob.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using Glob

@test string.(glob("*tests.jl", cwd())) == glob("*tests.jl", pwd())
@test string.(readdir(glob"*tests.jl", cwd())) == readdir(glob"*tests.jl", pwd())
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ using Test

@testset "FilePaths" begin

include("test_uri.jl")
include("compat.jl")
include("glob.jl")
include("test_uri.jl")

end

0 comments on commit a77d374

Please sign in to comment.