Move file check functions to HPath.IO

This commit is contained in:
Julian Ospald 2020-01-13 23:12:55 +01:00
parent 931851c8c1
commit 6a1f80bc17
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
4 changed files with 94 additions and 43 deletions

View File

@ -73,7 +73,6 @@ test-suite spec
HPath.IO.GetFileTypeSpec
HPath.IO.MoveFileOverwriteSpec
HPath.IO.MoveFileSpec
HPath.IO.ReadFileEOFSpec
HPath.IO.ReadFileSpec
HPath.IO.RecreateSymlinkOverwriteSpec
HPath.IO.RecreateSymlinkSpec

View File

@ -73,6 +73,12 @@ module HPath.IO
-- * File permissions
, newFilePerms
, newDirPerms
-- * File checks
, doesExist
, doesFileExist
, doesDirectoryExist
, isWritable
, canOpenDirectory
-- * Directory reading
, getDirsFiles
-- * Filetype operations
@ -191,7 +197,9 @@ import System.Posix.ByteString
import System.Posix.Directory.ByteString
(
createDirectory
, closeDirStream
, getWorkingDirectory
, openDirStream
, removeDirectory
)
import System.Posix.Directory.Traversals
@ -201,6 +209,7 @@ import System.Posix.Directory.Traversals
import System.Posix.Files.ByteString
(
createSymbolicLink
, fileAccess
, fileMode
, getFdStatus
, groupExecuteMode
@ -446,7 +455,9 @@ recreateSymlink symsource@(MkPath symsourceBS) newsym@(MkPath newsymBS) cm
case cm of
Strict -> return ()
Overwrite -> do
writable <- toAbs newsym >>= isWritable
writable <- toAbs newsym >>= (\p -> do
e <- doesExist p
if e then isWritable p else pure False)
isfile <- doesFileExist newsym
isdir <- doesDirectoryExist newsym
when (writable && isfile) (deleteFile newsym)
@ -830,7 +841,10 @@ moveFile from to cm = do
easyDelete from
Overwrite -> do
ft <- getFileType from
writable <- toAbs to >>= isWritable
writable <- toAbs to >>= (\p -> do
e <- doesFileExist p
if e then isWritable p else pure False)
case ft of
RegularFile -> do
exists <- doesFileExist to
@ -980,6 +994,72 @@ newDirPerms
-------------------
--[ File checks ]--
-------------------
-- |Checks if the given file exists.
-- Does not follow symlinks.
--
-- Only eNOENT is catched (and returns False).
doesExist :: Path b -> IO Bool
doesExist (MkPath bs) =
catchErrno [eNOENT] (do
_ <- PF.getSymbolicLinkStatus bs
return $ True)
$ return False
-- |Checks if the given file exists and is not a directory.
-- Does not follow symlinks.
--
-- Only eNOENT is catched (and returns False).
doesFileExist :: Path b -> IO Bool
doesFileExist (MkPath bs) =
catchErrno [eNOENT] (do
fs <- PF.getSymbolicLinkStatus bs
return $ not . PF.isDirectory $ fs)
$ return False
-- |Checks if the given file exists and is a directory.
-- Does not follow symlinks.
--
-- Only eNOENT is catched (and returns False).
doesDirectoryExist :: Path b -> IO Bool
doesDirectoryExist (MkPath bs) =
catchErrno [eNOENT] (do
fs <- PF.getSymbolicLinkStatus bs
return $ PF.isDirectory fs)
$ return False
-- |Checks whether a file or folder is writable.
--
-- Only eACCES, eROFS, eTXTBSY, ePERM are catched (and return False).
--
-- Throws:
--
-- - `NoSuchThing` if the file does not exist
isWritable :: Path b -> IO Bool
isWritable (MkPath bs) = fileAccess bs False True False
-- |Checks whether the directory at the given path exists and can be
-- opened. This invokes `openDirStream` which follows symlinks.
canOpenDirectory :: Path b -> IO Bool
canOpenDirectory (MkPath bs) =
handleIOError (\_ -> return False) $ do
bracket (openDirStream bs)
closeDirStream
(\_ -> return ())
return True
-------------------------
--[ Directory reading ]--
-------------------------

View File

@ -6,3 +6,11 @@ import HPath
canonicalizePath :: Path b -> IO (Path Abs)
toAbs :: Path b -> IO (Path Abs)
doesFileExist :: Path b -> IO Bool
doesDirectoryExist :: Path b -> IO Bool
isWritable :: Path b -> IO Bool
canOpenDirectory :: Path b -> IO Bool

View File

@ -33,10 +33,6 @@ module HPath.IO.Errors
, throwSameFile
, sameFile
, throwDestinationInSource
, doesFileExist
, doesDirectoryExist
, isWritable
, canOpenDirectory
-- * Error handling functions
, catchErrno
@ -92,6 +88,10 @@ import {-# SOURCE #-} HPath.IO
(
canonicalizePath
, toAbs
, doesFileExist
, doesDirectoryExist
, isWritable
, canOpenDirectory
)
import System.IO.Error
(
@ -242,42 +242,6 @@ throwDestinationInSource (MkPath sbs) dest@(MkPath dbs) = do
(throwIO $ DestinationInSource dbs sbs)
-- |Checks if the given file exists and is not a directory.
-- Does not follow symlinks.
doesFileExist :: Path b -> IO Bool
doesFileExist (MkPath bs) =
handleIOError (\_ -> return False) $ do
fs <- PF.getSymbolicLinkStatus bs
return $ not . PF.isDirectory $ fs
-- |Checks if the given file exists and is a directory.
-- Does not follow symlinks.
doesDirectoryExist :: Path b -> IO Bool
doesDirectoryExist (MkPath bs) =
handleIOError (\_ -> return False) $ do
fs <- PF.getSymbolicLinkStatus bs
return $ PF.isDirectory fs
-- |Checks whether a file or folder is writable.
isWritable :: Path b -> IO Bool
isWritable (MkPath bs) =
handleIOError (\_ -> return False) $
fileAccess bs False True False
-- |Checks whether the directory at the given path exists and can be
-- opened. This invokes `openDirStream` which follows symlinks.
canOpenDirectory :: Path b -> IO Bool
canOpenDirectory (MkPath bs) =
handleIOError (\_ -> return False) $ do
bracket (PFD.openDirStream bs)
PFD.closeDirStream
(\_ -> return ())
return True
--------------------------------