Don't preserve trailing path separators

This commit is contained in:
Julian Ospald 2020-01-20 19:44:42 +01:00
parent 1eeef0806d
commit f2986e60db
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
2 changed files with 20 additions and 16 deletions

View File

@ -28,7 +28,6 @@ Note: this library was written for __posix__ systems and it will probably not su
## Differences to 'path' ## Differences to 'path'
* doesn't attempt to fake IO-related information into the path, so whether a path points to a file or directory is up to your IO-code to decide... * doesn't attempt to fake IO-related information into the path, so whether a path points to a file or directory is up to your IO-code to decide...
* trailing path separators will be preserved if they exist, no messing with that
* uses safe ByteString for filepaths under the hood instead of unsafe String * uses safe ByteString for filepaths under the hood instead of unsafe String
* fixes broken [dirname](https://github.com/chrisdone/path/issues/18) * fixes broken [dirname](https://github.com/chrisdone/path/issues/18)
* renames dirname/filename to basename/dirname to match the POSIX shell functions * renames dirname/filename to basename/dirname to match the POSIX shell functions

View File

@ -125,7 +125,7 @@ pattern Path x <- (MkPath x)
-- >>> parseAbs "/abc/def" :: Maybe (Path Abs) -- >>> parseAbs "/abc/def" :: Maybe (Path Abs)
-- Just "/abc/def" -- Just "/abc/def"
-- >>> parseAbs "/abc/def/.///" :: Maybe (Path Abs) -- >>> parseAbs "/abc/def/.///" :: Maybe (Path Abs)
-- Just "/abc/def/" -- Just "/abc/def"
-- >>> parseAbs "abc" :: Maybe (Path Abs) -- >>> parseAbs "abc" :: Maybe (Path Abs)
-- Nothing -- Nothing
-- >>> parseAbs "" :: Maybe (Path Abs) -- >>> parseAbs "" :: Maybe (Path Abs)
@ -138,7 +138,7 @@ parseAbs filepath =
if isAbsolute filepath && if isAbsolute filepath &&
isValid filepath && isValid filepath &&
not (hasParentDir filepath) not (hasParentDir filepath)
then return (MkPath $ normalise filepath) then return (MkPath . dropTrailingPathSeparator . normalise $ filepath)
else throwM (InvalidAbs filepath) else throwM (InvalidAbs filepath)
@ -153,11 +153,11 @@ parseAbs filepath =
-- >>> parseRel "abc" :: Maybe (Path Rel) -- >>> parseRel "abc" :: Maybe (Path Rel)
-- Just "abc" -- Just "abc"
-- >>> parseRel "def/" :: Maybe (Path Rel) -- >>> parseRel "def/" :: Maybe (Path Rel)
-- Just "def/" -- Just "def"
-- >>> parseRel "abc/def" :: Maybe (Path Rel) -- >>> parseRel "abc/def" :: Maybe (Path Rel)
-- Just "abc/def" -- Just "abc/def"
-- >>> parseRel "abc/def/." :: Maybe (Path Rel) -- >>> parseRel "abc/def/." :: Maybe (Path Rel)
-- Just "abc/def/" -- Just "abc/def"
-- >>> parseRel "/abc" :: Maybe (Path Rel) -- >>> parseRel "/abc" :: Maybe (Path Rel)
-- Nothing -- Nothing
-- >>> parseRel "" :: Maybe (Path Rel) -- >>> parseRel "" :: Maybe (Path Rel)
@ -176,7 +176,7 @@ parseRel filepath =
filepath /= BS.pack [_period, _period] && filepath /= BS.pack [_period, _period] &&
not (hasParentDir filepath) && not (hasParentDir filepath) &&
isValid filepath isValid filepath
then return (MkPath $ normalise filepath) then return (MkPath . dropTrailingPathSeparator . normalise $ filepath)
else throwM (InvalidRel filepath) else throwM (InvalidRel filepath)
@ -197,7 +197,7 @@ parseRel filepath =
-- >>> parseAny "abc/def" :: Maybe (Either (Path Abs) (Path Rel)) -- >>> parseAny "abc/def" :: Maybe (Either (Path Abs) (Path Rel))
-- Just (Right "abc/def") -- Just (Right "abc/def")
-- >>> parseAny "abc/def/." :: Maybe (Either (Path Abs) (Path Rel)) -- >>> parseAny "abc/def/." :: Maybe (Either (Path Abs) (Path Rel))
-- Just (Right "abc/def/") -- Just (Right "abc/def")
-- >>> parseAny "/abc" :: Maybe (Either (Path Abs) (Path Rel)) -- >>> parseAny "/abc" :: Maybe (Either (Path Abs) (Path Rel))
-- Just (Left "/abc") -- Just (Left "/abc")
-- >>> parseAny "" :: Maybe (Either (Path Abs) (Path Rel)) -- >>> parseAny "" :: Maybe (Either (Path Abs) (Path Rel))
@ -253,14 +253,15 @@ fromAny = either toFilePath toFilePath
-- "/path/to/file" -- "/path/to/file"
-- >>> (MkPath "/") </> (MkPath "file/lal" :: Path Rel) -- >>> (MkPath "/") </> (MkPath "file/lal" :: Path Rel)
-- "/file/lal" -- "/file/lal"
-- >>> (MkPath "/") </> (MkPath "file/" :: Path Rel) -- >>> (MkPath "/") </> (MkPath "file" :: Path Rel)
-- "/file/" -- "/file"
(</>) :: Path b -> Path Rel -> Path b (</>) :: Path b -> Path Rel -> Path b
(</>) (MkPath a) (MkPath b) = MkPath (a' `BS.append` b) (</>) (MkPath a) (MkPath b) = MkPath (a' `BS.append` b)
where where
a' = if BS.last a == pathSeparator a' = if hasTrailingPathSeparator a
then a then a
else addTrailingPathSeparator a else addTrailingPathSeparator a
-- | Strip directory from path, making it relative to that directory. -- | Strip directory from path, making it relative to that directory.
-- Throws 'Couldn'tStripPrefixDir' if directory is not a parent of the path. -- Throws 'Couldn'tStripPrefixDir' if directory is not a parent of the path.
@ -309,6 +310,8 @@ isParentOf p l = isJust (stripDir p l :: Maybe (Path Rel))
-- --
-- >>> getAllParents (MkPath "/abs/def/dod") -- >>> getAllParents (MkPath "/abs/def/dod")
-- ["/abs/def","/abs","/"] -- ["/abs/def","/abs","/"]
-- >>> getAllParents (MkPath "/foo")
-- ["/"]
-- >>> getAllParents (MkPath "/") -- >>> getAllParents (MkPath "/")
-- [] -- []
getAllParents :: Path Abs -> [Path Abs] getAllParents :: Path Abs -> [Path Abs]
@ -316,7 +319,7 @@ getAllParents (MkPath p)
| np == BS.singleton pathSeparator = [] | np == BS.singleton pathSeparator = []
| otherwise = dirname (MkPath np) : getAllParents (dirname $ MkPath np) | otherwise = dirname (MkPath np) : getAllParents (dirname $ MkPath np)
where where
np = dropTrailingPathSeparator . normalise $ p np = normalise p
-- | Extract the directory name of a path. -- | Extract the directory name of a path.
@ -326,7 +329,7 @@ getAllParents (MkPath p)
-- >>> dirname (MkPath "/") -- >>> dirname (MkPath "/")
-- "/" -- "/"
dirname :: Path Abs -> Path Abs dirname :: Path Abs -> Path Abs
dirname (MkPath fp) = MkPath (takeDirectory $ dropTrailingPathSeparator fp) dirname (MkPath fp) = MkPath (takeDirectory fp)
-- | Extract the file part of a path. -- | Extract the file part of a path.
-- --
@ -339,7 +342,9 @@ dirname (MkPath fp) = MkPath (takeDirectory $ dropTrailingPathSeparator fp)
-- --
-- >>> basename (MkPath "/abc/def/dod") :: Maybe (Path Rel) -- >>> basename (MkPath "/abc/def/dod") :: Maybe (Path Rel)
-- Just "dod" -- Just "dod"
-- >>> basename (MkPath "/abc/def/dod/") :: Maybe (Path Rel) -- >>> basename (MkPath "abc/def/dod") :: Maybe (Path Rel)
-- Just "dod"
-- >>> basename (MkPath "dod") :: Maybe (Path Rel)
-- Just "dod" -- Just "dod"
-- >>> basename (MkPath "/") :: Maybe (Path Rel) -- >>> basename (MkPath "/") :: Maybe (Path Rel)
-- Nothing -- Nothing
@ -348,7 +353,7 @@ basename (MkPath l)
| not (isAbsolute rl) = return $ MkPath rl | not (isAbsolute rl) = return $ MkPath rl
| otherwise = throwM RootDirHasNoBasename | otherwise = throwM RootDirHasNoBasename
where where
rl = last . splitPath . dropTrailingPathSeparator $ l rl = last . splitPath $ l
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------