{-# LANGUAGE OverloadedStrings #-}

module HaskellWorks.CabalCache.IO.File
  ( copyDirectoryRecursive,
    listMaybeDirectory,
  ) where

import Control.Monad.Except   (MonadError)
import HaskellWorks.Prelude

import qualified Control.Monad.Oops                 as OO
import qualified Data.Text                          as T
import qualified HaskellWorks.CabalCache.IO.Console as CIO
import qualified System.Directory                   as IO
import qualified System.Exit                        as IO
import qualified System.Process                     as IO

copyDirectoryRecursive :: ()
  => MonadIO m
  => MonadError (OO.Variant e) m
  => e `OO.CouldBe` [Char]
  => String
  -> String
  -> m ()
copyDirectoryRecursive :: forall (m :: * -> *) (e :: [*]).
(MonadIO m, MonadError (Variant e) m, CouldBe e [Char]) =>
[Char] -> [Char] -> m ()
copyDirectoryRecursive [Char]
source [Char]
target = do
  Text -> m ()
forall (m :: * -> *). MonadIO m => Text -> m ()
CIO.putStrLn (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Copying recursively from " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack [Char]
source Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack [Char]
target
  ProcessHandle
process <- IO ProcessHandle -> m ProcessHandle
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ProcessHandle -> m ProcessHandle)
-> IO ProcessHandle -> m ProcessHandle
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]] -> IO ProcessHandle
IO.spawnProcess [Char]
"cp" [[Char]
"-r", [Char]
source, [Char]
target]
  ExitCode
exitCode <- IO ExitCode -> m ExitCode
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ExitCode -> m ExitCode) -> IO ExitCode -> m ExitCode
forall a b. (a -> b) -> a -> b
$ ProcessHandle -> IO ExitCode
IO.waitForProcess ProcessHandle
process
  case ExitCode
exitCode of
    ExitCode
IO.ExitSuccess   -> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    IO.ExitFailure Int
n -> [Char] -> m ()
forall x (e :: [*]) (m :: * -> *) a.
(MonadError (Variant e) m, CouldBe e x) =>
x -> m a
OO.throw ([Char] -> m ()) -> [Char] -> m ()
forall a b. (a -> b) -> a -> b
$ [Char]
"cp exited with " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n

listMaybeDirectory :: MonadIO m => FilePath -> m [FilePath]
listMaybeDirectory :: forall (m :: * -> *). MonadIO m => [Char] -> m [[Char]]
listMaybeDirectory [Char]
filepath = do
  Bool
exists <- IO Bool -> m Bool
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> m Bool) -> IO Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> IO Bool
IO.doesDirectoryExist [Char]
filepath
  if Bool
exists
    then IO [[Char]] -> m [[Char]]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [[Char]] -> m [[Char]]) -> IO [[Char]] -> m [[Char]]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [[Char]]
IO.listDirectory [Char]
filepath
    else [[Char]] -> m [[Char]]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []