filepath-bytestring 1.4.2.1.5 → 1.4.2.1.6
raw patch · 7 files changed
+63/−39 lines, 7 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ System.FilePath.Posix.ByteString: makeValid :: RawFilePath -> RawFilePath
+ System.FilePath.Windows.ByteString: makeValid :: RawFilePath -> RawFilePath
Files
- CHANGELOG +6/−0
- System/FilePath/Internal.hs +28/−29
- TODO +0/−3
- filepath-bytestring.cabal +1/−1
- tests/Test.hs +6/−6
- tests/TestEquiv.hs +2/−0
- tests/TestGen.hs +20/−0
CHANGELOG view
@@ -1,3 +1,9 @@+filepath-bytestring (1.4.2.1.6) unstable; urgency=medium++ * Added makeValid. All functions from filepath are now implemented.++ -- Joey Hess <id@joeyh.name> Thu, 02 Jan 2020 16:05:49 -0400+ filepath-bytestring (1.4.2.1.5) unstable; urgency=medium * Allow building with filepath-1.4.2 as well as 1.4.2.1;
System/FilePath/Internal.hs view
@@ -129,7 +129,7 @@ normalise, equalFilePath, makeRelative, isRelative, isAbsolute,- isValid, --makeValid+ isValid, makeValid ) where @@ -774,7 +774,7 @@ -- | Set the directory, keeping the filename the same. -- -- > replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext"--- > untested Valid x => replaceDirectory x (takeDirectory x) `equalFilePath` x+-- > Valid x => replaceDirectory x (takeDirectory x) `equalFilePath` x replaceDirectory :: RawFilePath -> ByteString -> RawFilePath replaceDirectory x dir = combineAlways dir (takeFileName x) @@ -1079,45 +1079,44 @@ (x1,x2) = splitDrive path f x = map toUpper (decodeFilePath $ dropWhileEnd (== 32) $ dropExtensions x) `elem` badElements -{-- -- | Take a FilePath and make it valid; does not change already valid FilePaths. ----- > untested isValid (makeValid x)--- > untested isValid x ==> makeValid x == x--- > untested makeValid "" == "_"--- > untested makeValid "file\0name" == "file_name"--- > untested Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"--- > untested Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"--- > untested Windows: makeValid "test*" == "test_"--- > untested Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"--- > untested Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"--- > untested Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"--- > untested Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"--- > untested Windows: makeValid "\\\\\\foo" == "\\\\drive"--- > untested Windows: makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file"--- > untested Windows: makeValid "nul .txt" == "nul _.txt"-makeValid :: FilePath -> FilePath+-- > isValid (makeValid x)+-- > isValid x ==> makeValid x == x+-- > makeValid "" == "_"+-- > makeValid "file\0name" == "file_name"+-- > Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"+-- > Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"+-- > Windows: makeValid "test*" == "test_"+-- > Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"+-- > Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"+-- > Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"+-- > Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"+-- > Windows: makeValid "\\\\\\foo" == "\\\\drive"+-- > Windows: makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file"+-- > Windows: makeValid "nul .txt" == "nul _.txt"+makeValid :: RawFilePath -> RawFilePath makeValid "" = "_" makeValid path- | isPosix = map (\x -> if x == '\0' then '_' else x) path- | isJust (readDriveShare drv) && all isPathSeparator drv = take 2 drv ++ "drive"+ | isPosix = B.map (\x -> if x == 0 then underscore else x) path+ | isJust (readDriveShare drv) && B.all isPathSeparator drv = B.take 2 drv <> "drive" | isJust (readDriveUNC drv) && not (hasTrailingPathSeparator drv) =- makeValid (drv ++ [pathSeparator] ++ pth)+ makeValid (drv <> B.singleton pathSeparator <> pth) | otherwise = joinDrive drv $ validElements $ validChars pth where (drv,pth) = splitDrive path - validChars = map f- f x = if isBadCharacter x then '_' else x+ underscore :: Word8+ underscore = fromIntegral (ord '_') + validChars = B.map f+ f x = if isBadCharacter x then underscore else x+ validElements x = joinPath $ map g $ splitPath x- g x = h a ++ b- where (a,b) = break isPathSeparator x- h x = if map toUpper (dropWhileEnd (== ' ') a) `elem` badElements then a ++ "_" <.> b else x+ g x = h a <> b+ where (a,b) = B.break isPathSeparator x+ h x = if map toUpper (decodeFilePath $ dropWhileEnd (== 32) a) `elem` badElements then a <> "_" <.> b else x where (a,b) = splitExtensions x---} -- | Is a path relative, or is it fixed to the root? --
TODO view
@@ -1,3 +0,0 @@-* Some functions have not been ported from FilePath and are commented out:- 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.5+version: 1.4.2.1.6 -- NOTE: Don't forget to update CHANGELOG and the filepath dependency below license: BSD3 license-file: LICENSE
tests/Test.hs view
@@ -15,18 +15,18 @@ let count = case args of i:_ -> read i; _ -> 10000 putStrLn $ "Testing with " ++ show count ++ " repetitions" let alltests = equivtests ++ tests- let total = length alltests+ let ntotal = length alltests let showOutput x = show x{output=""} ++ "\n" ++ output x- bad <- fmap catMaybes $ forM (zip [1..] alltests) $ \(i,(msg,prop)) -> do- putStrLn $ "Test " ++ show i ++ " of " ++ show total ++ ": " ++ msg+ bad <- fmap catMaybes $ forM (zip [(1 :: Integer)..] alltests) $ \(i,(msg,prop)) -> do+ putStrLn $ "Test " ++ show i ++ " of " ++ show ntotal ++ ": " ++ msg res <- quickCheckWithResult stdArgs{chatty=False, maxSuccess=count} prop case res of Success{} -> return Nothing bad -> do putStrLn $ showOutput bad; putStrLn "TEST FAILURE!"; return $ Just (msg,bad) if null bad then- putStrLn $ "Success, " ++ show total ++ " tests passed"+ putStrLn $ "Success, " ++ show ntotal ++ " tests passed" else do putStrLn $ show (length bad) ++ " FAILURES\n"- forM_ (zip [1..] bad) $ \(i,(a,b)) ->+ forM_ (zip [(1 :: Integer)..] bad) $ \(i,(a,b)) -> putStrLn $ "FAILURE " ++ show i ++ ": " ++ a ++ "\n" ++ showOutput b ++ "\n"- fail $ "FAILURE, failed " ++ show (length bad) ++ " of " ++ show total ++ " tests"+ fail $ "FAILURE, failed " ++ show (length bad) ++ " of " ++ show ntotal ++ " tests"
tests/TestEquiv.hs view
@@ -47,6 +47,7 @@ ,("equiv Posix.equalFilePath", equiv_2 OurPosix.equalFilePath TheirPosix.equalFilePath) ,("equiv Posix.makeRelative", equiv_2 OurPosix.makeRelative TheirPosix.makeRelative) ,("equiv Posix.splitSearchPath", equiv_1 OurPosix.splitSearchPath TheirPosix.splitSearchPath)+ ,("equiv Posix.makeValid", equiv_1 OurPosix.makeValid TheirPosix.makeValid) ,("equiv Windows.isPathSeparator", equiv_0 OurWindows.isPathSeparator TheirWindows.isPathSeparator) ,("equiv Windows.isSearchPathSeparator", equiv_0 OurWindows.isSearchPathSeparator TheirWindows.isSearchPathSeparator) ,("equiv Windows.isExtSeparator", equiv_0 OurWindows.isExtSeparator TheirWindows.isExtSeparator)@@ -87,4 +88,5 @@ ,("equiv Windows.equalFilePath", equiv_2 OurWindows.equalFilePath TheirWindows.equalFilePath) ,("equiv Windows.makeRelative", equiv_2 OurWindows.makeRelative TheirWindows.makeRelative) ,("equiv Windows.splitSearchPath", equiv_1 OurWindows.splitSearchPath TheirWindows.splitSearchPath)+ ,("equiv Windows.makeValid", equiv_1 OurWindows.makeValid TheirWindows.makeValid) ]
tests/TestGen.hs view
@@ -304,6 +304,8 @@ ,("W.takeDirectory \"C:\\\\\" == \"C:\\\\\"", property $ W.takeDirectory "C:\\" == "C:\\") ,("P.replaceDirectory \"root/file.ext\" \"/directory/\" == \"/directory/file.ext\"", property $ P.replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext") ,("W.replaceDirectory \"root/file.ext\" \"/directory/\" == \"/directory/file.ext\"", property $ W.replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext")+ ,("P.replaceDirectory x (P.takeDirectory x) `P.equalFilePath` x", property $ \(QFilePathValidP vx) -> let x = toRawFilePath vx in P.replaceDirectory x (P.takeDirectory x) `P.equalFilePath` x)+ ,("W.replaceDirectory x (W.takeDirectory x) `W.equalFilePath` x", property $ \(QFilePathValidW vx) -> let x = toRawFilePath vx in W.replaceDirectory x (W.takeDirectory x) `W.equalFilePath` x) ,("\"/directory\" P.</> \"file.ext\" == \"/directory/file.ext\"", property $ "/directory" P.</> "file.ext" == "/directory/file.ext") ,("\"/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")@@ -426,6 +428,24 @@ ,("W.isValid \"foo\\tbar\" == False", property $ W.isValid "foo\tbar" == False) ,("W.isValid \"nul .txt\" == False", property $ W.isValid "nul .txt" == False) ,("W.isValid \" nul.txt\" == True", property $ W.isValid " nul.txt" == True)+ ,("P.isValid (P.makeValid x)", property $ \(QFilePath vx) -> let x = toRawFilePath vx in P.isValid (P.makeValid x))+ ,("W.isValid (W.makeValid x)", property $ \(QFilePath vx) -> let x = toRawFilePath vx in W.isValid (W.makeValid x))+ ,("P.isValid x ==> P.makeValid x == x", property $ \(QFilePath vx) -> let x = toRawFilePath vx in P.isValid x ==> P.makeValid x == x)+ ,("W.isValid x ==> W.makeValid x == x", property $ \(QFilePath vx) -> let x = toRawFilePath vx in W.isValid x ==> W.makeValid x == x)+ ,("P.makeValid \"\" == \"_\"", property $ P.makeValid "" == "_")+ ,("W.makeValid \"\" == \"_\"", property $ W.makeValid "" == "_")+ ,("P.makeValid \"file\\0name\" == \"file_name\"", property $ P.makeValid "file\0name" == "file_name")+ ,("W.makeValid \"file\\0name\" == \"file_name\"", property $ W.makeValid "file\0name" == "file_name")+ ,("W.makeValid \"c:\\\\already\\\\/valid\" == \"c:\\\\already\\\\/valid\"", property $ W.makeValid "c:\\already\\/valid" == "c:\\already\\/valid")+ ,("W.makeValid \"c:\\\\test:of_test\" == \"c:\\\\test_of_test\"", property $ W.makeValid "c:\\test:of_test" == "c:\\test_of_test")+ ,("W.makeValid \"test*\" == \"test_\"", property $ W.makeValid "test*" == "test_")+ ,("W.makeValid \"c:\\\\test\\\\nul\" == \"c:\\\\test\\\\nul_\"", property $ W.makeValid "c:\\test\\nul" == "c:\\test\\nul_")+ ,("W.makeValid \"c:\\\\test\\\\prn.txt\" == \"c:\\\\test\\\\prn_.txt\"", property $ W.makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt")+ ,("W.makeValid \"c:\\\\test/prn.txt\" == \"c:\\\\test/prn_.txt\"", property $ W.makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt")+ ,("W.makeValid \"c:\\\\nul\\\\file\" == \"c:\\\\nul_\\\\file\"", property $ W.makeValid "c:\\nul\\file" == "c:\\nul_\\file")+ ,("W.makeValid \"\\\\\\\\\\\\foo\" == \"\\\\\\\\drive\"", property $ W.makeValid "\\\\\\foo" == "\\\\drive")+ ,("W.makeValid \"\\\\\\\\?\\\\D:file\" == \"\\\\\\\\?\\\\D:\\\\file\"", property $ W.makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file")+ ,("W.makeValid \"nul .txt\" == \"nul _.txt\"", property $ W.makeValid "nul .txt" == "nul _.txt") ,("W.isRelative \"path\\\\test\" == True", property $ W.isRelative "path\\test" == True) ,("W.isRelative \"c:\\\\test\" == False", property $ W.isRelative "c:\\test" == False) ,("W.isRelative \"c:test\" == True", property $ W.isRelative "c:test" == True)