Path
is a simple file path library for Carp.
Installation
(load "git@github.com:carpentry-org/path@0.2.0")
Usage
The Path module mostly operates on String arguments. It allows you to
split, join, and merge paths and extensions in a lot of different ways. It also
has some functions to work with the PATH environment variable.
It assumes either Windows or POSIX-style separators.
</>
(Fn [a, b] String)
(</> before after)
joins before and after using the default path separator.
absolute?
(Fn [(Ref String a)] Bool)
(absolute? p)
checks whether a path is absolute.
As such, it is the inverse to relative?.
add-extension
(Fn [(Ref String a), (Ref String b)] String)
(add-extension p ext)
adds an extension ext to a path p.
cwd
(Fn [] (Maybe String))
(cwd)
returns the current working directory as a Maybe. The ways in
which it can fail are OS-dependent, but it should happen relatively rare.
drop-extension
(Fn [(Ref String a)] String)
(drop-extension p)
drops the extension of a path p. Does nothing if there
is none.
extension
(Fn [(Ref String a)] (Maybe String))
(extension p)
gets the extension of a file as a Maybe.
filename
(Fn [(Ref String a)] (Maybe String))
(filename p)
gets the filename of the path p as a (Maybe String).
Returns Nothing when the path has no filename component: the empty path, a
bare root like /, or a path ending in a separator such as foo/bar/.
Otherwise returns Just of the last component.
get-search-path
(Fn [] (Maybe (Array String)))
(get-search-path)
gets the PATH environment variable and splits it.
has-extension?
(Fn [(Ref String a)] Bool)
(has-extension? p)
checks whether the path p has an extension.
is-extension?
(Fn [(Ref String a), (Ref String b)] Bool)
(is-extension? p ext)
checks whether the path p has the extension ext.
join
(Fn [(Ref (Array String) a)] String)
(join ps)
joins the path components ps into a path.
As such, it is the inverse to split.
matches?
(Fn [(Ref String a), (Ref String b)] Bool)
(matches? p pattern)
checks whether the path p matches the glob pattern.
The path comes first, like everywhere else in this module — note that this is
the opposite of Pattern.matches? in core:
(matches? "src/main.carp" "src/*.carp") ; => true
The pattern language is:
? exactly one character, never a separator
* zero or more characters, never a separator
** zero or more whole segments, as an entire segment
[abc] one of the characters in the class
[a-z] one character from the range
[!abc] one character not in the class ([^abc] works too)
\* a literal *, on POSIX (see below)
** is only a segment wildcard when it is the whole segment, so **/*.carp
matches both a.carp and x/y/a.carp, while a**b is just a*b. Inside a
class, a ] directly after the [ (or after the !/^) is a literal ], and
a - first or last is a literal -.
On POSIX a \ escapes the next pattern character. On Windows \ is a
separator, so escaping is disabled there. A trailing \ and an unterminated
[ are matched as literal characters, which is why this is a total function and
not a Result.
Separators are structural and cannot be escaped away: a\/b splits into
segments just like a/b, and a class holding one, such as [a/], matches its
other members but never the separator.
Leading dots are not special: * matches .hidden. Matching happens on the
path exactly as given, with no normalization and no collapsing of repeated
separators — run it through normalize first if you want that.
matching
(Fn [(Ref (Array String) a), (Ref String b)] (Array String))
(matching ps pattern)
keeps the paths in ps that match the glob pattern,
preserving their order.
It is matches? over an array, which is usually what you want:
(matching &[@"a.carp" @"a.c"] "*.carp") ; => [@"a.carp"]
normalize
(Fn [(Ref String a)] String)
(normalize p)
normalizes the path p lexically, without touching the
filesystem.
It collapses repeated separators, drops . components, and resolves each ..
against the preceding component. Leading .. components are kept in relative
paths (they cannot be resolved without a base), and .. never escapes the root
of an absolute path. An empty or fully-cancelling relative path normalizes to
., and a fully-cancelling absolute path normalizes to its root (a lone
separator on POSIX, the drive root such as C:\ on Windows).
Examples on POSIX:
(normalize "a/./b") ; => "a/b"
(normalize "a/b/../c") ; => "a/c"
(normalize "//a///b") ; => "/a/b"
(normalize "/a/../..") ; => "/"
(normalize "a/../..") ; => ".."
(normalize "") ; => "."
relative
(Fn [(Ref String a), (Ref String b)] (Maybe String))
(relative target base)
computes the path to target relative to base, purely
lexically. It is the companion to absolute.
Both paths are normalized first, so ., .., and redundant separators are
resolved before comparing. Returns Nothing when the paths cannot be related
lexically: one absolute and one relative, or, on Windows, rooted at different
drives. Equal paths yield Just ".".
relative?
(Fn [(Ref String a)] Bool)
(relative? p)
checks whether a path is relative.
As such, it is the inverse to absolute?.
replace-extension
(Fn [(Ref String a), (Ref String b)] String)
(replace-extension p ext)
replaces the extension of a path p with ext. Adds
an extension if there previously was none.
search-path-separator
Char
is the separator for the PATH environment
variable we use on this OS.
search-path-separator?
(Fn [Char] Bool)
(search-path-separator? c)
checks whether the character c is a separator
for the PATH environment variable on this OS.
separator?
(Fn [(Ref Char StaticLifetime)] Bool)
(separator? c)
checks whether the character c is a path separator on this
OS.
split
(Fn [(Ref String a)] (Array String))
(split p)
splits the path p into its components.
As such, it is the inverse to join.
split-extension
(Fn [(Ref String a)] (Maybe (Pair String String)))
(split-extension p)
splits the path p on its extension.
It will return a (Maybe (Pair String String)). Maybe because there might not
be an extension, and Pair because it will return the part before and after
the extension.
Examples on POSIX:
(split-extension "file.txt")
; => (Maybe.Just (Pair "file" "txt"))
(split-extension "file")
; => (Maybe.Nothing)
(split-extension "file/file.txt")
; => (Maybe.Just (Pair "file/file" "txt"))
(split-extension "file.txt/veit")
; => (Maybe.Nothing)
(split-extension "file.txt/veit.ext")
; => (Maybe.Just (Pair "file.txt/veit" "ext"))
(split-extension "file/path.txt.bob.fred")
; => (Maybe.Just (Pair "file/path.txt.bob" "fred"))
split-search-path
(Fn [(Ref String a)] (Array String))
(split-search-path p)
splits a PATH environment variable p.