module Development.Shake.BinDist ( -- * Rules
                                   tarLzip
                                 , tarZstd
                                 , tarBz2
                                 , tarGz
                                   -- * Actions
                                 , tarLzipA
                                 , tarZstdA
                                 , tarBz2A
                                 , tarGzA
                                 ) where

import           Archive.Compression                     (packFromFilesAndCompress)
import qualified Codec.Compression.BZip      as Bz2
import qualified Codec.Compression.GZip      as GZip
import qualified Codec.Compression.Zstd.Lazy as Zstd
import qualified Codec.Lzip                  as Lzip
import qualified Data.ByteString.Lazy        as BSL
import           Development.Shake           hiding (action)

tarGenericA :: String -- ^ Rule name
            -> (BSL.ByteString -> BSL.ByteString) -- ^ Compression function
            -> [FilePath] -- ^ Files to pack up
            -> FilePath -- ^ File name of resultant tarball
            -> Action ()
tarGenericA :: String
-> (ByteString -> ByteString) -> [String] -> String -> Action ()
tarGenericA rn :: String
rn f :: ByteString -> ByteString
f fps :: [String]
fps tar :: String
tar = do
    Partial => [String] -> Action ()
[String] -> Action ()
need [String]
fps
    String -> IO () -> Action ()
forall a. String -> IO a -> Action a
traced String
rn (IO () -> Action ()) -> IO () -> Action ()
forall a b. (a -> b) -> a -> b
$ (ByteString -> ByteString) -> String -> [String] -> IO ()
packFromFilesAndCompress ByteString -> ByteString
f String
tar [String]
fps

mkRule :: (a -> FilePath -> Action ()) -> a -> FilePattern -> Rules ()
mkRule :: (a -> String -> Action ()) -> a -> String -> Rules ()
mkRule action :: a -> String -> Action ()
action x :: a
x pat :: String
pat =
    String
pat Partial => String -> (String -> Action ()) -> Rules ()
String -> (String -> Action ()) -> Rules ()
%> \out :: String
out ->
        a -> String -> Action ()
action a
x String
out

-- | The [lzip](http://www.nongnu.org/lzip/lzip.html) format is suitable for
-- archiving.
--
-- Note that 'tarLzip' doesn't stream in memory; the others do.
tarLzip :: [FilePath] -- ^ Files to pack up
        -> FilePattern -- ^ Resultant tarball
        -> Rules ()
tarLzip :: [String] -> String -> Rules ()
tarLzip = ([String] -> String -> Action ()) -> [String] -> String -> Rules ()
forall a. (a -> String -> Action ()) -> a -> String -> Rules ()
mkRule [String] -> String -> Action ()
tarLzipA

tarZstd :: [FilePath] -- ^ Files to pack up
        -> FilePattern -- ^ Resultant tarball
        -> Rules ()
tarZstd :: [String] -> String -> Rules ()
tarZstd = ([String] -> String -> Action ()) -> [String] -> String -> Rules ()
forall a. (a -> String -> Action ()) -> a -> String -> Rules ()
mkRule [String] -> String -> Action ()
tarZstdA

tarGz :: [FilePath] -- ^ Files to pack up
      -> FilePattern -- ^ Resultant tarball
      -> Rules ()
tarGz :: [String] -> String -> Rules ()
tarGz = ([String] -> String -> Action ()) -> [String] -> String -> Rules ()
forall a. (a -> String -> Action ()) -> a -> String -> Rules ()
mkRule [String] -> String -> Action ()
tarGzA

tarBz2 :: [FilePath] -- ^ Files to pack up
      -> FilePattern -- ^ Resultant tarball
      -> Rules ()
tarBz2 :: [String] -> String -> Rules ()
tarBz2 = ([String] -> String -> Action ()) -> [String] -> String -> Rules ()
forall a. (a -> String -> Action ()) -> a -> String -> Rules ()
mkRule [String] -> String -> Action ()
tarBz2A

tarLzipA :: [FilePath] -- ^ Files to pack up
         -> FilePath -- ^ File name of resultant tarball
         -> Action ()
tarLzipA :: [String] -> String -> Action ()
tarLzipA = String
-> (ByteString -> ByteString) -> [String] -> String -> Action ()
tarGenericA "tar-lzip" ByteString -> ByteString
Lzip.compressBest

tarZstdA :: [FilePath] -- ^ Files to pack up
         -> FilePath -- ^ File name of resultant tarball
         -> Action ()
tarZstdA :: [String] -> String -> Action ()
tarZstdA = String
-> (ByteString -> ByteString) -> [String] -> String -> Action ()
tarGenericA "tar-zstd" (Int -> ByteString -> ByteString
Zstd.compress Int
Zstd.maxCLevel)

tarGzA :: [FilePath] -- ^ Files to pack up
         -> FilePath -- ^ File name of resultant tarball
         -> Action ()
tarGzA :: [String] -> String -> Action ()
tarGzA = String
-> (ByteString -> ByteString) -> [String] -> String -> Action ()
tarGenericA "tar-gz" ByteString -> ByteString
GZip.compress

tarBz2A :: [FilePath] -- ^ Files to pack up
         -> FilePath -- ^ File name of resultant tarball
         -> Action ()
tarBz2A :: [String] -> String -> Action ()
tarBz2A = String
-> (ByteString -> ByteString) -> [String] -> String -> Action ()
tarGenericA "tar-bz2" ByteString -> ByteString
Bz2.compress