cabal-cache-1.0.6.0: src/HaskellWorks/CabalCache/IO/Tar.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module HaskellWorks.CabalCache.IO.Tar
( ArchiveError(..),
TarGroup(..),
createTar,
extractTar,
) where
import Control.DeepSeq (NFData)
import Control.Lens ((^.))
import Control.Monad.Except (MonadError)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Generics.Product.Any (HasAny(the))
import Data.Text (Text)
import GHC.Generics (Generic)
import HaskellWorks.CabalCache.Show (tshow)
import qualified Control.Monad.Oops as OO
import qualified System.Exit as IO
import qualified System.Process as IO
data ArchiveError = ArchiveError Text deriving (Eq, Show, Generic)
data TarGroup = TarGroup
{ basePath :: FilePath
, entryPaths :: [FilePath]
} deriving (Show, Eq, Generic, NFData)
createTar :: ()
=> MonadIO m
=> MonadError (OO.Variant e) m
=> e `OO.CouldBe` ArchiveError
=> Foldable t
=> [Char]
-> t TarGroup
-> m ()
createTar tarFile groups = do
let args = ["-zcf", tarFile] <> foldMap tarGroupToArgs groups
process <- liftIO $ IO.spawnProcess "tar" args
exitCode <- liftIO $ IO.waitForProcess process
case exitCode of
IO.ExitSuccess -> return ()
IO.ExitFailure n -> OO.throw $ ArchiveError $ "Failed to create tar. Exit code: " <> tshow n
extractTar :: ()
=> MonadIO m
=> MonadError (OO.Variant e) m
=> e `OO.CouldBe` ArchiveError
=> String
-> String
-> m ()
extractTar tarFile targetPath = do
process <- liftIO $ IO.spawnProcess "tar" ["-C", targetPath, "-zxf", tarFile]
exitCode <- liftIO $ IO.waitForProcess process
case exitCode of
IO.ExitSuccess -> return ()
IO.ExitFailure n -> OO.throw $ ArchiveError $ "Failed to extract tar. Exit code: " <> tshow n
tarGroupToArgs :: TarGroup -> [String]
tarGroupToArgs tarGroup = ["-C", tarGroup ^. the @"basePath"] <> tarGroup ^. the @"entryPaths"