system-filepath 0.4.9 → 0.4.10
raw patch · 6 files changed
+94/−12 lines, 6 files
Files
- lib/Filesystem/Path.hs +26/−7
- lib/Filesystem/Path/CurrentOS.hs +6/−0
- lib/Filesystem/Path/Internal.hs +4/−0
- lib/Filesystem/Path/Rules.hs +11/−0
- system-filepath.cabal +2/−2
- tests/Tests.hs +45/−3
lib/Filesystem/Path.hs view
@@ -56,9 +56,10 @@ ) where import Prelude hiding (FilePath, concat, null)+import qualified Prelude as Prelude import Data.List (foldl')-import Data.Maybe (isNothing)+import Data.Maybe (isJust, isNothing) import qualified Data.Monoid as M import qualified Data.Text as T @@ -87,9 +88,8 @@ directory p = empty { pathRoot = pathRoot p , pathDirectories = let- starts = map Just [dot, dots]- dot' | safeHead (pathDirectories p) `elem` starts = []- | isNothing (pathRoot p) = [dot]+ dot' | isJust (pathRoot p) = []+ | Prelude.null (pathDirectories p) = [dot] | otherwise = [] in dot' ++ pathDirectories p }@@ -220,6 +220,15 @@ -- 'stripPrefix' \"\/foo\/\" \"\/bar\/baz.txt\" == Nothing -- @ --+-- This function operates on logical prefixes, rather than by counting+-- characters. The prefix @\"\/foo\/bar\/baz\"@ is interpreted the path+-- @(\"\/foo\/bar\/\", \"baz\")@, and will be stripped accordingly:+--+-- @+-- 'stripPrefix' \"\/foo\/bar\/baz\" \"\/foo\/bar\/baz\/qux\" == Nothing+-- 'stripPrefix' \"\/foo\/bar\/baz\" \"\/foo\/bar\/baz.txt\" == Just \".txt\"+-- @+-- -- Since: 0.4.1 stripPrefix :: FilePath -> FilePath -> Maybe FilePath stripPrefix x y = if pathRoot x /= pathRoot y@@ -251,15 +260,25 @@ then strip xs ys else Nothing --- | Remove @\".\"@ and @\"..\"@ directories from a path.+-- | Remove intermediate @\".\"@ and @\"..\"@ directories from a path. --+-- @+-- 'collapse' \"\/foo\/.\/bar\" == \"\/foo\/bar\"+-- 'collapse' \"\/foo\/bar\/..\/baz\" == \"\/foo\/baz\"+-- 'collapse' \"\/foo\/..\/..\/bar\" == \"\/bar\"+-- 'collapse' \".\/foo\/bar\" == \".\/foo\/baz\"+-- @+-- -- Note that if any of the elements are symbolic links, 'collapse' may change -- which file the path resolves to. -- -- Since: 0.2 collapse :: FilePath -> FilePath-collapse p = p { pathDirectories = reverse newDirs } where- (_, newDirs) = foldl' step (True, []) (pathDirectories p)+collapse p = p { pathDirectories = newDirs } where+ newDirs = case pathRoot p of+ Nothing -> reverse revNewDirs+ Just _ -> dropWhile (\x -> x == dot || x == dots) (reverse revNewDirs)+ (_, revNewDirs) = foldl' step (True, []) (pathDirectories p) step (True, acc) c = (False, c:acc) step (_, acc) c | c == dot = (False, acc)
lib/Filesystem/Path/CurrentOS.hs view
@@ -29,6 +29,7 @@ -- * Rule‐specific path properties , valid , splitSearchPath+ , splitSearchPathString ) where import Prelude hiding (FilePath)@@ -117,6 +118,11 @@ -- of 'FilePath's. splitSearchPath :: PLATFORM_PATH_FORMAT -> [F.FilePath] splitSearchPath = R.splitSearchPath currentOS++-- | splitSearchPathString is like 'splitSearchPath', but takes a string+-- encoded in the format used by @System.IO@.+splitSearchPathString :: String -> [F.FilePath]+splitSearchPathString = R.splitSearchPathString currentOS -- | Convert a 'F.FilePath' to a platform‐specific format, suitable -- for use with external OS functions.
lib/Filesystem/Path/Internal.hs view
@@ -113,6 +113,10 @@ -- a list of 'FilePath's. , splitSearchPath :: platformFormat -> [FilePath] + -- | splitSearchPathString is like 'splitSearchPath', but takes a string+ -- encoded in the format used by @System.IO@.+ , splitSearchPathString :: String -> [FilePath]+ -- | Attempt to convert a 'FilePath' to human‐readable text. -- -- If the path is decoded successfully, the result is a 'Right'
lib/Filesystem/Path/Rules.hs view
@@ -26,6 +26,7 @@ -- * Rule‐specific path properties , valid , splitSearchPath+ , splitSearchPathString ) where import Prelude hiding (FilePath, null)@@ -52,6 +53,7 @@ { rulesName = T.pack "POSIX" , valid = posixValid , splitSearchPath = posixSplitSearch+ , splitSearchPathString = posixSplitSearch . B8.pack , toText = posixToText , fromText = posixFromText , encode = posixToBytes@@ -69,6 +71,7 @@ posix_ghc702 :: Rules B.ByteString posix_ghc702 = posix { rulesName = T.pack "POSIX (GHC 7.2)"+ , splitSearchPathString = posixSplitSearchString posixFromGhc702String , encodeString = posixToGhc702String , decodeString = posixFromGhc702String }@@ -82,6 +85,7 @@ posix_ghc704 :: Rules B.ByteString posix_ghc704 = posix { rulesName = T.pack "POSIX (GHC 7.4)"+ , splitSearchPathString = posixSplitSearchString posixFromGhc704String , encodeString = posixToGhc704String , decodeString = posixFromGhc704String }@@ -184,6 +188,10 @@ posixSplitSearch = map (posixFromBytes . normSearch) . B.split 0x3A where normSearch bytes = if B.null bytes then B8.pack "." else bytes +posixSplitSearchString :: (String -> FilePath) -> String -> [FilePath]+posixSplitSearchString toPath = map (toPath . normSearch) . splitBy (== ':') where+ normSearch s = if P.null s then "." else s+ ------------------------------------------------------------------------------- -- Darwin -------------------------------------------------------------------------------@@ -199,6 +207,7 @@ { rulesName = T.pack "Darwin" , valid = posixValid , splitSearchPath = darwinSplitSearch+ , splitSearchPathString = darwinSplitSearch . TE.decodeUtf8 . B8.pack , toText = Right . darwinToText , fromText = posixFromText , encode = darwinToText@@ -216,6 +225,7 @@ darwin_ghc702 :: Rules T.Text darwin_ghc702 = darwin { rulesName = T.pack "Darwin (GHC 7.2)"+ , splitSearchPathString = darwinSplitSearch . T.pack , encodeString = T.unpack . darwinToText , decodeString = posixFromText . T.pack }@@ -245,6 +255,7 @@ { rulesName = T.pack "Windows" , valid = winValid , splitSearchPath = winSplit+ , splitSearchPathString = winSplit . T.pack , toText = Right . winToText , fromText = winFromText , encode = winToText
system-filepath.cabal view
@@ -1,5 +1,5 @@ name: system-filepath-version: 0.4.9+version: 0.4.10 synopsis: High-level, byte-based file and directory path manipulations license: MIT license-file: license.txt@@ -29,7 +29,7 @@ source-repository this type: git location: https://john-millikin.com/code/haskell-filesystem/- tag: system-filepath_0.4.9+ tag: system-filepath_0.4.10 library ghc-options: -Wall -O2
tests/Tests.hs view
@@ -63,6 +63,7 @@ :: Suite) test_SplitSearchPath+ test_SplitSearchPathString test_Parsing test_EncodeString test_DecodeString@@ -97,7 +98,7 @@ $expect $ equal (directory "../foo") "../" $expect $ equal (directory "../foo/") "../foo/" $expect $ equal (directory "foo") "./"- $expect $ equal (directory "foo/bar") "./foo/"+ $expect $ equal (directory "foo/bar") "foo/" test_Parent :: Test test_Parent = assertions "parent" $ do@@ -348,6 +349,8 @@ $expect $ equal (collapse "parent/foo/baz/../bar") "parent/foo/bar" $expect $ equal (collapse "parent/foo/baz/../../bar") "parent/bar" $expect $ equal (collapse "parent/foo/..") "parent/"+ $expect $ equal (collapse "/parent/foo/../../../bar") "/bar"+ $expect $ equal (collapse "/./parent/foo") "/parent/foo" test_SplitDirectories :: Test test_SplitDirectories = assertions "splitDirectories" $ do@@ -423,13 +426,52 @@ test_SplitSearchPath :: Test test_SplitSearchPath = assertions "splitSearchPath" $ do- let p x = map (toChar8) (splitSearchPath posix (B8.pack x))- let w x = map (toString) (splitSearchPath windows (T.pack x))+ let p x = map toChar8 (splitSearchPath posix (B8.pack x))+ let w x = map toString (splitSearchPath windows (T.pack x)) $expect $ equal (p "a:b:c") ["a", "b", "c"] $expect $ equal (p "a::b:c") ["a", "./", "b", "c"] $expect $ equal (w "a;b;c") ["a", "b", "c"] $expect $ equal (w "a;;b;c") ["a", "b", "c"]++test_SplitSearchPathString :: Suite+test_SplitSearchPathString = suite "splitSearchPathString"+ test_SplitSearchPathString_Posix+ test_SplitSearchPathString_Posix_Ghc702+ test_SplitSearchPathString_Posix_Ghc704+ test_SplitSearchPathString_Darwin+ test_SplitSearchPathString_Darwin_Ghc702+ test_SplitSearchPathString_Win32++test_SplitSearchPathString_Posix :: Test+test_SplitSearchPathString_Posix = assertions "posix" $ do+ let split x = map (toText posix) (splitSearchPathString posix x)+ $expect $ equal (split "a::\xC2\xA1\xC2\xA2:\xA1\xA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]++test_SplitSearchPathString_Posix_Ghc702 :: Test+test_SplitSearchPathString_Posix_Ghc702 = assertions "posix_ghc702" $ do+ let split x = map (toText posix) (splitSearchPathString posix_ghc702 x)+ $expect $ equal (split "a::\xA1\xA2:\xEFA1\xEFA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]++test_SplitSearchPathString_Posix_Ghc704 :: Test+test_SplitSearchPathString_Posix_Ghc704 = assertions "posix_ghc704" $ do+ let split x = map (toText posix) (splitSearchPathString posix_ghc704 x)+ $expect $ equal (split "a::\xA1\xA2:\xDCA1\xDCA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]++test_SplitSearchPathString_Darwin :: Test+test_SplitSearchPathString_Darwin = assertions "darwin" $ do+ let split x = map (toText darwin) (splitSearchPathString darwin x)+ $expect $ equal (split "a::\xC2\xA1\xC2\xA2") [Right "a", Right "./", Right "\xA1\xA2"]++test_SplitSearchPathString_Darwin_Ghc702 :: Test+test_SplitSearchPathString_Darwin_Ghc702 = assertions "darwin_ghc702" $ do+ let split x = map (toText darwin) (splitSearchPathString darwin_ghc702 x)+ $expect $ equal (split "a::\xA1\xA2") [Right "a", Right "./", Right "\xA1\xA2"]++test_SplitSearchPathString_Win32 :: Test+test_SplitSearchPathString_Win32 = assertions "win32" $ do+ let split x = map (toText windows) (splitSearchPathString windows x)+ $expect $ equal (split "a;;\xA1\xA2") [Right "a", Right "\xA1\xA2"] test_EncodeString :: Suite test_EncodeString = suite "encodeString"