packages feed

filepath-bytestring 1.4.2.1.2 → 1.4.2.1.3

raw patch · 5 files changed

+64/−47 lines, 5 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ System.FilePath.Posix.ByteString: equalFilePath :: RawFilePath -> RawFilePath -> Bool
+ System.FilePath.Posix.ByteString: makeRelative :: RawFilePath -> RawFilePath -> RawFilePath
+ System.FilePath.Windows.ByteString: equalFilePath :: RawFilePath -> RawFilePath -> Bool
+ System.FilePath.Windows.ByteString: makeRelative :: RawFilePath -> RawFilePath -> RawFilePath

Files

CHANGELOG view
@@ -1,3 +1,10 @@+filepath-bytestring (1.4.2.1.3) unstable; urgency=medium++  * Added equalFilePath.+  * Added makeRelative.++ -- Joey Hess <id@joeyh.name>  Mon, 30 Dec 2019 13:07:31 -0400+ filepath-bytestring (1.4.2.1.2) unstable; urgency=medium    * Fix build with ghc 8.0 (pre-Semigroup Monoid transition)
System/FilePath/Internal.hs view
@@ -126,8 +126,8 @@     dropTrailingPathSeparator,      -- * File name manipulations-    normalise, --equalFilePath,-    --makeRelative,+    normalise, equalFilePath,+    makeRelative,     isRelative, isAbsolute,     isValid, --makeValid     )@@ -136,7 +136,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8-import Data.Char(ord, chr, toUpper, isAsciiLower, isAsciiUpper)+import Data.Char(ord, chr, toUpper, toLower, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.Word(Word8) #ifdef mingw32_HOST_OS@@ -796,7 +796,7 @@ -- > Posix:   "/directory" </> "file.ext" == "/directory/file.ext" -- > Windows: "/directory" </> "file.ext" == "/directory\\file.ext" -- >          "directory" </> "/file.ext" == "/file.ext"--- > untested Valid x => (takeDirectory x </> takeFileName x) `equalFilePath` x+-- > Valid x => (takeDirectory x </> takeFileName x) `equalFilePath` x -- --   Combined: --@@ -859,7 +859,7 @@ -- >          splitDirectories "test/file" == ["test","file"] -- >          splitDirectories "/test/file" == ["/","test","file"] -- > Windows: splitDirectories "C:\\test\\file" == ["C:\\", "test", "file"]--- > untested          Valid x => joinPath (splitDirectories x) `equalFilePath` x+-- >          Valid x => joinPath (splitDirectories x) `equalFilePath` x -- >          splitDirectories "" == [] -- > Windows: splitDirectories "C:\\test\\\\\\file" == ["C:\\", "test", "file"] -- >          splitDirectories "/test///file" == ["/","test","file"]@@ -877,8 +877,6 @@ -- Note that this definition on c:\\c:\\, join then split will give c:\\. joinPath = foldr combine mempty -{-- --------------------------------------------------------------------- -- File name manipulators @@ -887,24 +885,21 @@ --   first this has a much better chance of working. --   Note that this doesn't follow symlinks or DOSNAM~1s. ----- > untested          x == y ==> equalFilePath x y--- > untested          normalise x == normalise y ==> equalFilePath x y--- > untested          equalFilePath "foo" "foo/"--- > untested          not (equalFilePath "foo" "/foo")--- > untested Posix:   not (equalFilePath "foo" "FOO")--- > untested Windows: equalFilePath "foo" "FOO"--- > untested Windows: not (equalFilePath "C:" "C:/")+-- >          x == y ==> equalFilePath x y+-- >          normalise x == normalise y ==> equalFilePath x y+-- >          equalFilePath "foo" "foo/"+-- >          not (equalFilePath "foo" "/foo")+-- > Posix:   not (equalFilePath "foo" "FOO")+-- > Windows: equalFilePath "foo" "FOO"+-- > Windows: not (equalFilePath "C:" "C:/") equalFilePath :: RawFilePath -> RawFilePath -> Bool equalFilePath a b = f a == f b   where--- FIXME: B8.map will not lower-case non-ascii characters. 	f x-		| isWindows = dropTrailingPathSeparator $ B8.map toLower $ normalise x+		| isWindows = dropTrailingPathSeparator $ encodeFilePath $+			map toLower $ decodeFilePath $ normalise x 		| otherwise = dropTrailingPathSeparator $ normalise x--} -{-- -- | Contract a filename, based on a relative path. Note that the resulting path --   will never introduce @..@ paths, as the presence of symlinks means @..\/b@ --   may not reach @a\/b@ if it starts from @a\/c@. For a worked example see@@ -913,46 +908,46 @@ --   The corresponding @makeAbsolute@ function can be found in --   @System.Directory@. ----- > untested          makeRelative "/directory" "/directory/file.ext" == "file.ext"--- > untested          Valid x => makeRelative (takeDirectory x) x `equalFilePath` takeFileName x--- > untested          makeRelative x x == "."--- > untested          Valid x y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x--- > untested Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"--- > untested Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"--- > untested Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"--- > untested Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"--- > untested Windows: makeRelative "/Home" "/home/bob" == "bob"--- > untested Windows: makeRelative "/" "//" == "//"--- > untested Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"--- > untested Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"--- > untested Posix:   makeRelative "/fred" "bob" == "bob"--- > untested Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"--- > untested Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"--- > untested Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"-makeRelative :: FilePath -> FilePath -> FilePath+-- >          makeRelative "/directory" "/directory/file.ext" == "file.ext"+-- >          Valid x => makeRelative (takeDirectory x) x `equalFilePath` takeFileName x+-- >          makeRelative x x == "."+-- >          Valid x y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x+-- > Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"+-- > Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"+-- > Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"+-- > Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"+-- > Windows: makeRelative "/Home" "/home/bob" == "bob"+-- > Windows: makeRelative "/" "//" == "//"+-- > Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"+-- > Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"+-- > Posix:   makeRelative "/fred" "bob" == "bob"+-- > Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"+-- > Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"+-- > Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"+makeRelative :: RawFilePath -> RawFilePath -> RawFilePath makeRelative root path 	| equalFilePath root path = "." 	| takeAbs root /= takeAbs path = path 	| otherwise = f (dropAbs root) (dropAbs path)   where-	f "" y = dropWhile isPathSeparator y+	f "" y = B.dropWhile isPathSeparator y 	f x y = 		let (x1,x2) = g x 		    (y1,y2) = g y 		in if equalFilePath x1 y1 then f x2 y2 else path -	g x = (dropWhile isPathSeparator a, dropWhile isPathSeparator b)+	g x = (B.dropWhile isPathSeparator a, B.dropWhile isPathSeparator b) 	  where-		(a,b) = break isPathSeparator $ dropWhile isPathSeparator x+		(a,b) = B.break isPathSeparator $ B.dropWhile isPathSeparator x  	-- on windows, need to drop '/' which is kind of absolute, but not a drive-	dropAbs x | hasLeadingPathSeparator x && not (hasDrive x) = tail x+	dropAbs x | hasLeadingPathSeparator x && not (hasDrive x) = B.tail x 	dropAbs x = dropDrive x -	takeAbs x | hasLeadingPathSeparator x && not (hasDrive x) = [pathSeparator]-	takeAbs x = map (\y -> if isPathSeparator y then pathSeparator else toLower y) $ takeDrive x---}+	takeAbs x | hasLeadingPathSeparator x && not (hasDrive x) = B.singleton pathSeparator+	-- A Windows drive letter is an ascii character, so it's safe to+	-- operate on the ByteString containing it using B8.+	takeAbs x = B8.map toLower $ takeDrive x  -- | Normalise a file --@@ -1074,7 +1069,7 @@ 		not (isJust (readDriveUNC x1) && not (hasTrailingPathSeparator x1))   where 	(x1,x2) = splitDrive path-	f x = map toUpper (B8.unpack $ dropWhileEnd (== 32) $ dropExtensions x) `elem` badElements+	f x = map toUpper (decodeFilePath $ dropWhileEnd (== 32) $ dropExtensions x) `elem` badElements  {- 
TODO view
@@ -1,3 +1,3 @@ * Some functions have not been ported from FilePath and are commented out:-  splitSearchPath, getSearchPath, normalise, equalFilePath, makeRelative,+  splitSearchPath, getSearchPath,   makeValid. Implementations would be accepted if you need any of these.
filepath-bytestring.cabal view
@@ -1,6 +1,6 @@ cabal-version:  >= 1.18 name:           filepath-bytestring-version:        1.4.2.1.2+version:        1.4.2.1.3 -- NOTE: Don't forget to update CHANGELOG and the filepath version below license:        BSD3 license-file:   LICENSE
tests/TestGen.hs view
@@ -303,6 +303,8 @@     ,("\"/directory\" W.</> \"file.ext\" == \"/directory\\\\file.ext\"", property $ "/directory" W.</> "file.ext" == "/directory\\file.ext")     ,("\"directory\" P.</> \"/file.ext\" == \"/file.ext\"", property $ "directory" P.</> "/file.ext" == "/file.ext")     ,("\"directory\" W.</> \"/file.ext\" == \"/file.ext\"", property $ "directory" W.</> "/file.ext" == "/file.ext")+    ,("(P.takeDirectory x P.</> P.takeFileName x) `P.equalFilePath` x", property $ \(QFilePathValidP vx) -> let x = toRawFilePath vx in (P.takeDirectory x P.</> P.takeFileName x) `P.equalFilePath` x)+    ,("(W.takeDirectory x W.</> W.takeFileName x) `W.equalFilePath` x", property $ \(QFilePathValidW vx) -> let x = toRawFilePath vx in (W.takeDirectory x W.</> W.takeFileName x) `W.equalFilePath` x)     ,("\"/\" P.</> \"test\" == \"/test\"", property $ "/" P.</> "test" == "/test")     ,("\"home\" P.</> \"bob\" == \"home/bob\"", property $ "home" P.</> "bob" == "home/bob")     ,("\"x:\" P.</> \"foo\" == \"x:/foo\"", property $ "x:" P.</> "foo" == "x:/foo")@@ -334,6 +336,8 @@     ,("P.splitDirectories \"/test/file\" == [\"/\", \"test\", \"file\"]", property $ P.splitDirectories "/test/file" == ["/", "test", "file"])     ,("W.splitDirectories \"/test/file\" == [\"/\", \"test\", \"file\"]", property $ W.splitDirectories "/test/file" == ["/", "test", "file"])     ,("W.splitDirectories \"C:\\\\test\\\\file\" == [\"C:\\\\\", \"test\", \"file\"]", property $ W.splitDirectories "C:\\test\\file" == ["C:\\", "test", "file"])+    ,("P.joinPath (P.splitDirectories x) `P.equalFilePath` x", property $ \(QFilePathValidP vx) -> let x = toRawFilePath vx in P.joinPath (P.splitDirectories x) `P.equalFilePath` x)+    ,("W.joinPath (W.splitDirectories x) `W.equalFilePath` x", property $ \(QFilePathValidW vx) -> let x = toRawFilePath vx in W.joinPath (W.splitDirectories x) `W.equalFilePath` x)     ,("P.splitDirectories \"\" == []", property $ P.splitDirectories "" == [])     ,("W.splitDirectories \"\" == []", property $ W.splitDirectories "" == [])     ,("W.splitDirectories \"C:\\\\test\\\\\\\\\\\\file\" == [\"C:\\\\\", \"test\", \"file\"]", property $ W.splitDirectories "C:\\test\\\\\\file" == ["C:\\", "test", "file"])@@ -346,6 +350,17 @@     ,("P.joinPath [] == \"\"", property $ P.joinPath [] == "")     ,("W.joinPath [] == \"\"", property $ W.joinPath [] == "")     ,("P.joinPath [\"test\", \"file\", \"path\"] == \"test/file/path\"", property $ P.joinPath ["test", "file", "path"] == "test/file/path")+    ,("x == y ==> P.equalFilePath x y", property $ \(QFilePath vx) (QFilePath vy) -> let y = toRawFilePath vy in let x = toRawFilePath vx in x == y ==> P.equalFilePath x y)+    ,("x == y ==> W.equalFilePath x y", property $ \(QFilePath vx) (QFilePath vy) -> let y = toRawFilePath vy in let x = toRawFilePath vx in x == y ==> W.equalFilePath x y)+    ,("P.normalise x == P.normalise y ==> P.equalFilePath x y", property $ \(QFilePath vx) (QFilePath vy) -> let y = toRawFilePath vy in let x = toRawFilePath vx in P.normalise x == P.normalise y ==> P.equalFilePath x y)+    ,("W.normalise x == W.normalise y ==> W.equalFilePath x y", property $ \(QFilePath vx) (QFilePath vy) -> let y = toRawFilePath vy in let x = toRawFilePath vx in W.normalise x == W.normalise y ==> W.equalFilePath x y)+    ,("P.equalFilePath \"foo\" \"foo/\"", property $ P.equalFilePath "foo" "foo/")+    ,("W.equalFilePath \"foo\" \"foo/\"", property $ W.equalFilePath "foo" "foo/")+    ,("not (P.equalFilePath \"foo\" \"/foo\")", property $ not (P.equalFilePath "foo" "/foo"))+    ,("not (W.equalFilePath \"foo\" \"/foo\")", property $ not (W.equalFilePath "foo" "/foo"))+    ,("not (P.equalFilePath \"foo\" \"FOO\")", property $ not (P.equalFilePath "foo" "FOO"))+    ,("W.equalFilePath \"foo\" \"FOO\"", property $ W.equalFilePath "foo" "FOO")+    ,("not (W.equalFilePath \"C:\" \"C:/\")", property $ not (W.equalFilePath "C:" "C:/"))     ,("P.normalise \"/file/\\\\test////\" == \"/file/\\\\test/\"", property $ P.normalise "/file/\\test////" == "/file/\\test/")     ,("P.normalise \"/file/./test\" == \"/file/test\"", property $ P.normalise "/file/./test" == "/file/test")     ,("P.normalise \"/test/file/../bob/fred/\" == \"/test/file/../bob/fred/\"", property $ P.normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/")