{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module GHCup.Utils.Tar where
import GHCup.Utils.Tar.Types ( ArchiveResult(..) )
import GHCup.Errors
import GHCup.Prelude
import GHCup.Prelude.Logger.Internal
import GHCup.Types.Optics
import Control.Monad.Catch (MonadThrow)
import Control.Monad.Reader
import Data.List
import Haskus.Utils.Variant.Excepts
import System.FilePath
#if defined(TAR)
import Codec.Archive.Zip
import qualified Codec.Archive.Tar as Tar
import qualified Codec.Archive.Tar.Entry as Tar
import qualified Data.Map.Strict as Map
#else
import Codec.Archive hiding ( Directory
, ArchiveResult
)
#endif
import qualified Codec.Compression.BZip as BZip
import qualified Codec.Compression.GZip as GZip
import qualified Codec.Compression.Lzma as Lzma
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as T
unpackToDir :: (MonadReader env m, HasLog env, MonadIO m, MonadThrow m)
=> FilePath
-> FilePath
-> Excepts '[UnknownArchive
, ArchiveResult
] m ()
unpackToDir :: forall env (m :: * -> *).
(MonadReader env m, HasLog env, MonadIO m, MonadThrow m) =>
FilePath
-> FilePath -> Excepts '[UnknownArchive, ArchiveResult] m ()
unpackToDir FilePath
dfp FilePath
av = do
let fn :: FilePath
fn = FilePath -> FilePath
takeFileName FilePath
av
m () -> Excepts '[UnknownArchive, ArchiveResult] m ()
forall (m :: * -> *) a.
Monad m =>
m a -> Excepts '[UnknownArchive, ArchiveResult] m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> Excepts '[UnknownArchive, ArchiveResult] m ())
-> m () -> Excepts '[UnknownArchive, ArchiveResult] m ()
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall env (m :: * -> *).
(MonadReader env m,
LabelOptic' "loggerConfig" A_Lens env LoggerConfig, MonadIO m) =>
Text -> m ()
logInfo (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Unpacking: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Text
T.pack FilePath
fn Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Text
T.pack FilePath
dfp
#if defined(TAR)
let untar :: MonadIO m => BL.ByteString -> Excepts '[ArchiveResult] m ()
untar :: forall (m :: * -> *).
MonadIO m =>
ByteString -> Excepts '[ArchiveResult] m ()
untar = IO () -> Excepts '[ArchiveResult] m ()
forall a. IO a -> Excepts '[ArchiveResult] m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Excepts '[ArchiveResult] m ())
-> (ByteString -> IO ())
-> ByteString
-> Excepts '[ArchiveResult] m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Entries FormatError -> IO ()
forall e. Exception e => FilePath -> Entries e -> IO ()
Tar.unpack FilePath
dfp (Entries FormatError -> IO ())
-> (ByteString -> Entries FormatError) -> ByteString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Entries FormatError
Tar.read
rf :: MonadIO m => FilePath -> Excepts '[ArchiveResult] m BL.ByteString
rf :: forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf = IO ByteString -> Excepts '[ArchiveResult] m ByteString
forall a. IO a -> Excepts '[ArchiveResult] m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> Excepts '[ArchiveResult] m ByteString)
-> (FilePath -> IO ByteString)
-> FilePath
-> Excepts '[ArchiveResult] m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO ByteString
BL.readFile
#else
let untar :: MonadIO m => BL.ByteString -> Excepts '[ArchiveResult] m ()
untar = lEM . liftIO . runArchiveM . unpackToDirLazy dfp
rf :: MonadIO m => FilePath -> Excepts '[ArchiveResult] m BL.ByteString
rf = liftIO . BL.readFile
#endif
if
| FilePath
".tar.gz" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> Excepts '[ArchiveResult] m ()
-> Excepts '[UnknownArchive, ArchiveResult] m ()
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE
(ByteString -> Excepts '[ArchiveResult] m ()
forall (m :: * -> *).
MonadIO m =>
ByteString -> Excepts '[ArchiveResult] m ()
untar (ByteString -> Excepts '[ArchiveResult] m ())
-> (ByteString -> ByteString)
-> ByteString
-> Excepts '[ArchiveResult] m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
GZip.decompress (ByteString -> Excepts '[ArchiveResult] m ())
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[ArchiveResult] m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av)
| FilePath
".tar.xz" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> do
ByteString
filecontents <- Excepts '[ArchiveResult] m ByteString
-> Excepts '[UnknownArchive, ArchiveResult] m ByteString
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (Excepts '[ArchiveResult] m ByteString
-> Excepts '[UnknownArchive, ArchiveResult] m ByteString)
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[UnknownArchive, ArchiveResult] m ByteString
forall a b. (a -> b) -> a -> b
$ FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av
let decompressed :: ByteString
decompressed = DecompressParams -> ByteString -> ByteString
Lzma.decompressWith (DecompressParams
Lzma.defaultDecompressParams { decompressAutoDecoder :: Bool
Lzma.decompressAutoDecoder= Bool
True }) ByteString
filecontents
Excepts '[ArchiveResult] m ()
-> Excepts '[UnknownArchive, ArchiveResult] m ()
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (Excepts '[ArchiveResult] m ()
-> Excepts '[UnknownArchive, ArchiveResult] m ())
-> Excepts '[ArchiveResult] m ()
-> Excepts '[UnknownArchive, ArchiveResult] m ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Excepts '[ArchiveResult] m ()
forall (m :: * -> *).
MonadIO m =>
ByteString -> Excepts '[ArchiveResult] m ()
untar ByteString
decompressed
| FilePath
".tar.bz2" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn ->
Excepts '[ArchiveResult] m ()
-> Excepts '[UnknownArchive, ArchiveResult] m ()
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (ByteString -> Excepts '[ArchiveResult] m ()
forall (m :: * -> *).
MonadIO m =>
ByteString -> Excepts '[ArchiveResult] m ()
untar (ByteString -> Excepts '[ArchiveResult] m ())
-> (ByteString -> ByteString)
-> ByteString
-> Excepts '[ArchiveResult] m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BZip.decompress (ByteString -> Excepts '[ArchiveResult] m ())
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[ArchiveResult] m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av)
| FilePath
".tar" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> Excepts '[ArchiveResult] m ()
-> Excepts '[UnknownArchive, ArchiveResult] m ()
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (ByteString -> Excepts '[ArchiveResult] m ()
forall (m :: * -> *).
MonadIO m =>
ByteString -> Excepts '[ArchiveResult] m ()
untar (ByteString -> Excepts '[ArchiveResult] m ())
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[ArchiveResult] m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av)
#if defined(TAR)
| FilePath
".zip" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> FilePath
-> ZipArchive () -> Excepts '[UnknownArchive, ArchiveResult] m ()
forall (m :: * -> *) a.
MonadIO m =>
FilePath -> ZipArchive a -> m a
withArchive FilePath
av (FilePath -> ZipArchive ()
unpackInto FilePath
dfp)
#else
| ".zip" `isSuffixOf` fn -> liftE (untar =<< rf av)
#endif
| Bool
otherwise -> UnknownArchive -> Excepts '[UnknownArchive, ArchiveResult] m ()
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE (UnknownArchive -> Excepts '[UnknownArchive, ArchiveResult] m ())
-> UnknownArchive -> Excepts '[UnknownArchive, ArchiveResult] m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> UnknownArchive
UnknownArchive FilePath
fn
getArchiveFiles :: (MonadReader env m, HasLog env, MonadIO m, MonadThrow m)
=> FilePath
-> Excepts '[ UnknownArchive
, ArchiveResult
] m [FilePath]
getArchiveFiles :: forall env (m :: * -> *).
(MonadReader env m, HasLog env, MonadIO m, MonadThrow m) =>
FilePath -> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
getArchiveFiles FilePath
av = do
let fn :: FilePath
fn = FilePath -> FilePath
takeFileName FilePath
av
#if defined(TAR)
let entries :: Monad m => BL.ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries :: forall (m :: * -> *).
Monad m =>
ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries =
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
Either e a -> Excepts es m a
lE @ArchiveResult
(Either ArchiveResult [FilePath]
-> Excepts '[ArchiveResult] m [FilePath])
-> (ByteString -> Either ArchiveResult [FilePath])
-> ByteString
-> Excepts '[ArchiveResult] m [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenEntry FilePath FilePath
-> Either ArchiveResult [FilePath]
-> Either ArchiveResult [FilePath])
-> Either ArchiveResult [FilePath]
-> (Either FormatError DecodeLongNamesError
-> Either ArchiveResult [FilePath])
-> GenEntries
FilePath FilePath (Either FormatError DecodeLongNamesError)
-> Either ArchiveResult [FilePath]
forall tarPath linkTarget a e.
(GenEntry tarPath linkTarget -> a -> a)
-> a -> (e -> a) -> GenEntries tarPath linkTarget e -> a
Tar.foldEntries
(\GenEntry FilePath FilePath
e Either ArchiveResult [FilePath]
x -> ([FilePath] -> [FilePath])
-> Either ArchiveResult [FilePath]
-> Either ArchiveResult [FilePath]
forall a b.
(a -> b) -> Either ArchiveResult a -> Either ArchiveResult b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (GenEntry FilePath FilePath -> FilePath
forall tarPath linkTarget. GenEntry tarPath linkTarget -> tarPath
Tar.entryTarPath GenEntry FilePath FilePath
e FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
:) Either ArchiveResult [FilePath]
x)
([FilePath] -> Either ArchiveResult [FilePath]
forall a b. b -> Either a b
Right [])
(\Either FormatError DecodeLongNamesError
_ -> ArchiveResult -> Either ArchiveResult [FilePath]
forall a b. a -> Either a b
Left ArchiveResult
ArchiveFailed)
(GenEntries
FilePath FilePath (Either FormatError DecodeLongNamesError)
-> Either ArchiveResult [FilePath])
-> (ByteString
-> GenEntries
FilePath FilePath (Either FormatError DecodeLongNamesError))
-> ByteString
-> Either ArchiveResult [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Entries FormatError
-> GenEntries
FilePath FilePath (Either FormatError DecodeLongNamesError)
forall e.
Entries e
-> GenEntries FilePath FilePath (Either e DecodeLongNamesError)
Tar.decodeLongNames
(Entries FormatError
-> GenEntries
FilePath FilePath (Either FormatError DecodeLongNamesError))
-> (ByteString -> Entries FormatError)
-> ByteString
-> GenEntries
FilePath FilePath (Either FormatError DecodeLongNamesError)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Entries FormatError
Tar.read
rf :: MonadIO m => FilePath -> Excepts '[ArchiveResult] m BL.ByteString
rf :: forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf = IO ByteString -> Excepts '[ArchiveResult] m ByteString
forall a. IO a -> Excepts '[ArchiveResult] m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> Excepts '[ArchiveResult] m ByteString)
-> (FilePath -> IO ByteString)
-> FilePath
-> Excepts '[ArchiveResult] m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO ByteString
BL.readFile
#else
let entries :: Monad m => BL.ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries = (fmap . fmap) filepath . lE . readArchiveBSL
rf :: MonadIO m => FilePath -> Excepts '[ArchiveResult] m BL.ByteString
rf = liftIO . BL.readFile
#endif
if
| FilePath
".tar.gz" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> Excepts '[ArchiveResult] m [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE
(ByteString -> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *).
Monad m =>
ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries (ByteString -> Excepts '[ArchiveResult] m [FilePath])
-> (ByteString -> ByteString)
-> ByteString
-> Excepts '[ArchiveResult] m [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
GZip.decompress (ByteString -> Excepts '[ArchiveResult] m [FilePath])
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av)
| FilePath
".tar.xz" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> do
ByteString
filecontents <- Excepts '[ArchiveResult] m ByteString
-> Excepts '[UnknownArchive, ArchiveResult] m ByteString
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (Excepts '[ArchiveResult] m ByteString
-> Excepts '[UnknownArchive, ArchiveResult] m ByteString)
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[UnknownArchive, ArchiveResult] m ByteString
forall a b. (a -> b) -> a -> b
$ FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av
let decompressed :: ByteString
decompressed = DecompressParams -> ByteString -> ByteString
Lzma.decompressWith (DecompressParams
Lzma.defaultDecompressParams { decompressAutoDecoder :: Bool
Lzma.decompressAutoDecoder= Bool
True }) ByteString
filecontents
Excepts '[ArchiveResult] m [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (Excepts '[ArchiveResult] m [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath])
-> Excepts '[ArchiveResult] m [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall a b. (a -> b) -> a -> b
$ ByteString -> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *).
Monad m =>
ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries ByteString
decompressed
| FilePath
".tar.bz2" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn ->
Excepts '[ArchiveResult] m [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (ByteString -> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *).
Monad m =>
ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries (ByteString -> Excepts '[ArchiveResult] m [FilePath])
-> (ByteString -> ByteString)
-> ByteString
-> Excepts '[ArchiveResult] m [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BZip.decompress (ByteString -> Excepts '[ArchiveResult] m [FilePath])
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av)
| FilePath
".tar" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn -> Excepts '[ArchiveResult] m [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (ByteString -> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *).
Monad m =>
ByteString -> Excepts '[ArchiveResult] m [FilePath]
entries (ByteString -> Excepts '[ArchiveResult] m [FilePath])
-> Excepts '[ArchiveResult] m ByteString
-> Excepts '[ArchiveResult] m [FilePath]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> Excepts '[ArchiveResult] m ByteString
forall (m :: * -> *).
MonadIO m =>
FilePath -> Excepts '[ArchiveResult] m ByteString
rf FilePath
av)
| FilePath
".zip" FilePath -> FilePath -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` FilePath
fn ->
#if defined(TAR)
FilePath
-> ZipArchive [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall (m :: * -> *) a.
MonadIO m =>
FilePath -> ZipArchive a -> m a
withArchive FilePath
av (ZipArchive [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath])
-> ZipArchive [FilePath]
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall a b. (a -> b) -> a -> b
$ do
Map EntrySelector EntryDescription
entries' <- ZipArchive (Map EntrySelector EntryDescription)
getEntries
[FilePath] -> ZipArchive [FilePath]
forall a. a -> ZipArchive a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([FilePath] -> ZipArchive [FilePath])
-> [FilePath] -> ZipArchive [FilePath]
forall a b. (a -> b) -> a -> b
$ (EntrySelector -> FilePath) -> [EntrySelector] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap EntrySelector -> FilePath
unEntrySelector ([EntrySelector] -> [FilePath]) -> [EntrySelector] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ Map EntrySelector EntryDescription -> [EntrySelector]
forall k a. Map k a -> [k]
Map.keys Map EntrySelector EntryDescription
entries'
#else
liftE (entries =<< rf av)
#endif
| Bool
otherwise -> UnknownArchive
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE (UnknownArchive
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath])
-> UnknownArchive
-> Excepts '[UnknownArchive, ArchiveResult] m [FilePath]
forall a b. (a -> b) -> a -> b
$ FilePath -> UnknownArchive
UnknownArchive FilePath
fn