packages feed

shake-bindist-1.1.0.0: src/Development/Shake/BinDist.hs

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

import           Archive.Compression         (packFromFilesAndCompress)
import qualified Codec.Compression.BZip      as Bz2
import qualified Codec.Compression.GZip      as GZip
import qualified Codec.Compression.Lzma      as Lzma
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)
import           System.IO                   (IOMode (ReadMode), hFileSize,
                                              withFile)

fileSize :: FilePath -> IO Integer
fileSize fp = withFile fp ReadMode hFileSize

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

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

-- | The [lzip](http://www.nongnu.org/lzip/lzip.html) format is suitable for
-- archiving.
tarLzip :: [FilePath] -- ^ Files to pack up
        -> FilePattern -- ^ Resultant tarball
        -> Rules ()
tarLzip = mkRule tarLzipA

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

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

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

-- | @since 1.0.1.0
tarXz :: [FilePath] -- ^ Files to pack up
      -> FilePattern -- ^ Resultant tarball
      -> Rules ()
tarXz = mkRule tarXzA

tarLzipA :: [FilePath] -- ^ Files to pack up
         -> FilePath -- ^ File name of resultant tarball
         -> Action ()
tarLzipA fps tar = do
    guessSz <- liftIO (sum <$> traverse (fmap fromIntegral . fileSize) fps)
    tarGenericA "tar-lzip" (flip Lzip.compressSzBest guessSz) fps tar

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

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

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

-- | @since 1.0.1.0
tarXzA :: [FilePath] -- ^ Files to pack up
       -> FilePath -- ^ File name of resultant tarball
       -> Action ()
tarXzA = tarGenericA "lzma" Lzma.compress