Skip to content

Commit

Permalink
Add windows support to hpath-directory
Browse files Browse the repository at this point in the history
  • Loading branch information
hasufell committed Nov 1, 2021
1 parent bd4ee44 commit 37921d7
Show file tree
Hide file tree
Showing 8 changed files with 1,402 additions and 122 deletions.
2 changes: 1 addition & 1 deletion cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ source-repository-package
source-repository-package
type: git
location: https://github.com/hasufell/abstract-filepath.git
tag: 535133eb0eda91c55e96832bcede4b65f74e3fb9
tag: 595973d0e2027315f5c7ac865e70b43fbb2356e4
subdir: abstract-filepath
abstract-filepath-types
abstract-filepath-unix
Expand Down
35 changes: 24 additions & 11 deletions hpath-directory/hpath-directory.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,35 @@ tested-with: GHC==7.10.3
library
if os(windows)
cpp-options: -DWINDOWS
exposed-modules: System.Win32.WindowsFilePath.Directory
build-depends: Win32
, abstract-filepath-Win32
else
exposed-modules: System.Posix.PosixFilePath.Directory
System.Posix.PosixFilePath.Directory.Errors
build-depends: unix >= 2.5
, unix-bytestring >= 0.3
, abstract-filepath-unix
, hpath-posix >= 0.14.0
, streamly-posix >= 0.1.0.2

exposed-modules: System.Directory.AFP
System.Directory.Errors
System.Directory.Types
System.Posix.PosixFilePath.Directory
System.Posix.PosixFilePath.Directory.Errors
-- other-modules:
-- other-extensions:
build-depends: base >= 4.8 && <5
, IfElse
, abstract-filepath
, abstract-filepath-types
, abstract-filepath-unix
, bytestring >= 0.10
, exceptions >= 0.10
, hpath-posix >= 0.14.0
, safe-exceptions >= 0.1
, streamly >= 0.7
, streamly-bytestring >= 0.1.2
, streamly-posix >= 0.1.0.2
, split
, time >= 1.8
, transformers
, unix >= 2.5
, unix-bytestring >= 0.3
, utf8-string
if impl(ghc < 8.0)
build-depends:
Expand Down Expand Up @@ -99,20 +106,26 @@ test-suite spec
Spec
Utils
GHC-Options: -Wall
Build-Depends: abstract-filepath
if os(windows)
cpp-options: -DWINDOWS
build-depends: Win32
, abstract-filepath-Win32
else
build-depends: unix
, unix-bytestring
, hpath-posix >= 0.13
, abstract-filepath-unix
Build-Depends: abstract-filepath
, abstract-filepath-types
, base
, HUnit
, IfElse
, bytestring >= 0.10.0.0
, hpath-directory
, hpath-filepath >= 0.10
, hpath-posix >= 0.13
, hspec >= 1.3
, process
, time >= 1.8
, unix
, unix-bytestring
, utf8-string
build-tool-depends: hspec-discover:hspec-discover
default-extensions: PackageImports
Expand Down
15 changes: 14 additions & 1 deletion hpath-directory/src/System/Directory/AFP.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ module System.Directory.AFP
-- * Types
module System.Directory.Types
, Permissions
#ifdef WINDOWS
, module System.Win32.WindowsFilePath.Directory
#else
, module System.Posix.PosixFilePath.Directory
#endif
{--
-- * File copying
, copyDirRecursive
, recreateSymlink
Expand Down Expand Up @@ -67,6 +73,7 @@ module System.Directory.AFP
-- * Others
, canonicalizePath
, toAbs
--}
)
where

Expand All @@ -77,8 +84,10 @@ import Prelude hiding ( appendFile
import Data.Bits
import System.Directory.Types
#ifdef WINDOWS
import System.Win32.WindowsFilePath.Directory
import qualified System.Win32.WindowsFilePath.Directory as Dir
#else
import System.Posix.PosixFilePath.Directory
import qualified System.Posix.PosixFilePath.Directory as Dir
import qualified System.Posix as Posix (FileMode)
import qualified System.Posix.Files.ByteString as Posix
Expand Down Expand Up @@ -213,6 +222,7 @@ setPermissions (OsString (PS path')) (Permissions r w e s) = do
--------------------


{--
copyDirRecursive :: AbstractFilePath -- ^ source dir
-> AbstractFilePath -- ^ destination (parent dirs
-- are not automatically created)
Expand Down Expand Up @@ -392,7 +402,7 @@ easyDelete :: AbstractFilePath -> IO ()
easyDelete (OsString p) = Dir.easyDelete p

--}

---------------------
--[ File Creation ]--
Expand All @@ -412,6 +422,8 @@ createRegularFile :: AbstractFilePath -> IO ()
createRegularFile (OsString destBS) = Dir.createRegularFile Dir.newFilePerms destBS


{--
-- |Create an empty directory at the given directory with the given filename.
--
-- Throws:
Expand Down Expand Up @@ -820,3 +832,4 @@ canonicalizePath (OsString fp) = OsString <$> Dir.canonicalizePath fp
toAbs :: AbstractFilePath -> IO AbstractFilePath
toAbs (OsString bs) = OsString <$> Dir.toAbs bs
--}
163 changes: 163 additions & 0 deletions hpath-directory/src/System/Directory/Errors.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
-- |
-- Module : System.Directory.Errors
-- Copyright : © 2016 Julian Ospald
-- License : BSD3
--
-- Maintainer : Julian Ospald <hasufell@posteo.de>
-- Stability : experimental
-- Portability : portable
--
-- Provides error handling.

{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ScopedTypeVariables #-}

module System.Directory.Errors
(
-- * Types
HPathIOException(..)
, RecursiveFailureHint(..)

-- * Exception identifiers
, isSameFile
, isDestinationInSource
, isRecursiveFailure
, isReadContentsFailed
, isCreateDirFailed
, isCopyFileFailed
, isRecreateSymlinkFailed

-- * Error handling functions
, handleIOError
, hideError
, bracketeer
, reactOnError
)
where


import Control.Applicative
(
(<$>)
)
import Control.Exception.Safe hiding (handleIOError)
import Control.Monad
(
forM
, when
)
import Control.Monad.IfElse
(
whenM
)
import Foreign.C.Error
(
getErrno
, Errno
)
import GHC.IO.Exception
(
IOErrorType
)
import System.IO.Error
(
alreadyExistsErrorType
, ioeGetErrorType
, mkIOError
)
import System.Directory.Types




toConstr :: HPathIOException -> String
toConstr SameFile {} = "SameFile"
toConstr DestinationInSource {} = "DestinationInSource"
toConstr RecursiveFailure {} = "RecursiveFailure"





-----------------------------
--[ Exception identifiers ]--
-----------------------------


isSameFile, isDestinationInSource, isRecursiveFailure :: HPathIOException -> Bool
isSameFile ex = toConstr (ex :: HPathIOException) == toConstr (SameFile mempty mempty)
isDestinationInSource ex = toConstr (ex :: HPathIOException) == (toConstr $ DestinationInSource mempty mempty)
isRecursiveFailure ex = toConstr (ex :: HPathIOException) == (toConstr $ RecursiveFailure mempty)


isReadContentsFailed, isCreateDirFailed, isCopyFileFailed, isRecreateSymlinkFailed ::RecursiveFailureHint -> Bool
isReadContentsFailed ReadContentsFailed{} = True
isReadContentsFailed _ = False
isCreateDirFailed CreateDirFailed{} = True
isCreateDirFailed _ = False
isCopyFileFailed CopyFileFailed{} = True
isCopyFileFailed _ = False
isRecreateSymlinkFailed RecreateSymlinkFailed{} = True
isRecreateSymlinkFailed _ = False





--------------------------------
--[ Error handling functions ]--
--------------------------------




-- |Like `catchIOError`, with arguments swapped.
handleIOError :: (IOError -> IO a) -> IO a -> IO a
handleIOError = flip catchIOError


hideError :: IOErrorType -> IO () -> IO ()
hideError err = handleIO (\e -> if err == ioeGetErrorType e then pure () else ioError e)


-- |Like `bracket`, but allows to have different clean-up
-- actions depending on whether the in-between computation
-- has raised an exception or not.
bracketeer :: IO a -- ^ computation to run first
-> (a -> IO b) -- ^ computation to run last, when
-- no exception was raised
-> (a -> IO b) -- ^ computation to run last,
-- when an exception was raised
-> (a -> IO c) -- ^ computation to run in-between
-> IO c
bracketeer before after afterEx thing =
mask $ \restore -> do
a <- before
r <- restore (thing a) `onException` afterEx a
_ <- after a
return r


reactOnError :: IO a
-> [(IOErrorType, IO a)] -- ^ reaction on IO errors
-> [(HPathIOException, IO a)] -- ^ reaction on HPathIOException
-> IO a
reactOnError a ios fmios =
a `catches` [iohandler, fmiohandler]
where
iohandler = Handler $
\(ex :: IOException) ->
foldr (\(t, a') y -> if ioeGetErrorType ex == t
then a'
else y)
(throwIO ex)
ios
fmiohandler = Handler $
\(ex :: HPathIOException) ->
foldr (\(t, a') y -> if toConstr ex == toConstr t
then a'
else y)
(throwIO ex)
fmios


41 changes: 0 additions & 41 deletions hpath-directory/src/System/Directory/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,6 @@ import AFP.AbstractFilePath.Types



toConstr :: HPathIOException -> String
toConstr SameFile {} = "SameFile"
toConstr DestinationInSource {} = "DestinationInSource"
toConstr RecursiveFailure {} = "RecursiveFailure"





-----------------------------
--[ Exception identifiers ]--
-----------------------------


isSameFile, isDestinationInSource, isRecursiveFailure :: HPathIOException -> Bool
isSameFile ex = toConstr (ex :: HPathIOException) == toConstr (SameFile mempty mempty)
isDestinationInSource ex = toConstr (ex :: HPathIOException) == (toConstr $ DestinationInSource mempty mempty)
isRecursiveFailure ex = toConstr (ex :: HPathIOException) == (toConstr $ RecursiveFailure mempty)


isReadContentsFailed, isCreateDirFailed, isCopyFileFailed, isRecreateSymlinkFailed ::RecursiveFailureHint -> Bool
isReadContentsFailed ReadContentsFailed{} = True
isReadContentsFailed _ = False
isCreateDirFailed CreateDirFailed{} = True
isCreateDirFailed _ = False
isCopyFileFailed CopyFileFailed{} = True
isCopyFileFailed _ = False
isRecreateSymlinkFailed RecreateSymlinkFailed{} = True
isRecreateSymlinkFailed _ = False




-------------
--[ Types ]--
Expand Down Expand Up @@ -68,15 +36,6 @@ data RecursiveFailureHint = ReadContentsFailed AbstractFilePath AbstractFileP

instance Exception HPathIOException

data FileType = Directory
| RegularFile
| SymbolicLink
| BlockDevice
| CharacterDevice
| NamedPipe
| Socket
deriving (Eq, Show)



-- |The error mode for recursive operations.
Expand Down
Loading

0 comments on commit 37921d7

Please sign in to comment.