{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Strict #-}
module VtUtils.FS
( FSCopyDirectoryDestException(..)
, FSCopyDirectorySourceException(..)
, fsCopyDirectory
) where
import Prelude (IO, Show(..), ($), (<$>), fmap)
import Control.Exception (Exception(..), throwIO)
import Control.Monad (forM_, unless, when)
import Data.Monoid ((<>))
import Data.Text (Text, pack, unpack)
import System.Directory (copyFile, createDirectory, doesDirectoryExist, listDirectory)
import VtUtils.Error (errorShow)
import VtUtils.Path (pathConcat)
data FSCopyDirectorySourceException = FSCopyDirectorySourceException
{ source :: Text
}
instance Exception FSCopyDirectorySourceException
instance Show FSCopyDirectorySourceException where
show e@(FSCopyDirectorySourceException {source}) = errorShow e $
"Source directory does not exist,"
<> " path: [" <> source <> "]"
data FSCopyDirectoryDestException = FSCopyDirectoryDestException
{ dest :: Text
}
instance Exception FSCopyDirectoryDestException
instance Show FSCopyDirectoryDestException where
show e@(FSCopyDirectoryDestException {dest}) = errorShow e $
"Destination directory does not exist,"
<> " path: [" <> dest <> "]"
fsCopyDirectory :: Text -> Text -> IO ()
fsCopyDirectory src dest = do
srcex <- doesDirectoryExist (unpack src)
unless (srcex) $ throwIO $ FSCopyDirectorySourceException src
destex <- doesDirectoryExist (unpack dest)
when (destex) $ throwIO $ FSCopyDirectoryDestException dest
createDirectory (unpack dest)
children <- (fmap pack) <$> listDirectory (unpack src)
forM_ children $ \child -> do
let srcpath = pathConcat src child
let destpath = pathConcat dest child
isdir <- doesDirectoryExist (unpack srcpath)
if isdir then
fsCopyDirectory srcpath destpath
else
copyFile (unpack srcpath) (unpack destpath)