ztar 0.1.0 → 0.1.1
raw patch · 3 files changed
+83/−3 lines, 3 filesdep +processdep +textdep +unix-compatdep −tar
Dependencies added: process, text, unix-compat
Dependencies removed: tar
Files
- CHANGELOG.md +6/−1
- src/Codec/Archive/Tar.hs +70/−0
- ztar.cabal +7/−2
CHANGELOG.md view
@@ -1,7 +1,12 @@+# ztar 0.1.1++Changes:+* Use the Unix `tar` command instead, because of issues with the Haskell `tar` library+ # ztar 0.1.0 Breaking changes:-* Works against zip-0.2.0, will revert in 0.2.0+* Works against zip-0.2.0, will revert in future release # ztar 0.0.3
+ src/Codec/Archive/Tar.hs view
@@ -0,0 +1,70 @@+{-|+Module : Codec.Archive.Tar+Maintainer : Brandon Chinn <brandonchinn178@gmail.com>+Stability : experimental+Portability : portable++The Haskell @tar@ library has a lot of bugs, including:++* Does not preserve executability (https://github.com/haskell/tar/issues/25)+* Does not preserve symbolic links (https://github.com/haskell/tar/issues/34)+* Does not allow symbolic links to `..` in a nested directory (https://github.com/haskell/tar/issues/32)++Because of these bugs, we will be using the @tar@ Unix command, which should be commonly available+on most systems. This module should be deprecated when the Haskell @tar@ library is updated.++Note that this module contains the same security considerations as the @tar@ Unix command. Follow+the same security guidelines you would with the @tar@ Unix command when using this module.+-}+{-# LANGUAGE LambdaCase #-}++module Codec.Archive.Tar where++import qualified Data.ByteString.Lazy as BS+import qualified Data.Text.IO as Text+import qualified Data.Text.Lazy as TextL+import qualified Data.Text.Lazy.Encoding as TextL+import GHC.IO.Handle (hClose)+import Prelude hiding (read)+import System.Directory (createDirectoryIfMissing, removeFile)+import System.Exit (ExitCode(..), exitWith)+import System.PosixCompat.Temp (mkstemp)+import System.Process (readProcessWithExitCode)++-- | Runs the UNIX @tar@ command with the given arguments.+tar :: [String] -> IO ()+tar args = readProcessWithExitCode "tar" args "" >>= \case+ (ExitSuccess, _, _) -> return ()+ (ExitFailure n, _, _) -> exitWith $ ExitFailure n++create :: FilePath -> FilePath -> [FilePath] -> IO ()+create archive base paths = BS.writeFile archive . write =<< pack base paths++extract :: FilePath -> FilePath -> IO ()+extract dir archive = unpack dir . read =<< BS.readFile archive++newtype TarArchive = TarArchive { unTar :: BS.ByteString }++read :: BS.ByteString -> TarArchive+read = TarArchive++write :: TarArchive -> BS.ByteString+write = unTar++pack :: FilePath -> [FilePath] -> IO TarArchive+pack base paths = do+ (archive, h) <- mkstemp "tar-pack"+ hClose h+ tar $ ["-cf", archive, "-C", base] ++ paths+ contents <- TextL.encodeUtf8 . TextL.fromStrict <$> Text.readFile archive+ removeFile archive+ return $ TarArchive contents++unpack :: FilePath -> TarArchive -> IO ()+unpack dir (TarArchive contents) = do+ (archive, h) <- mkstemp "tar-unpack"+ hClose h+ BS.writeFile archive contents+ createDirectoryIfMissing True dir+ tar ["-xf", archive, "-C", dir]+ removeFile archive
ztar.cabal view
@@ -1,5 +1,5 @@ name: ztar-version: 0.1.0+version: 0.1.1 license: BSD3 license-file: LICENSE.md author: Brandon Chinn <brandonchinn178@gmail.com>@@ -27,14 +27,19 @@ Codec.Archive.ZTar.GZip Codec.Archive.ZTar.Tar Codec.Archive.ZTar.Zip+ Codec.Archive.Tar build-depends: base >= 4.7 && < 5 , bytestring >= 0.10.8 && < 0.11 , directory >= 1.3 && < 1.4 , filepath >= 1.4.1 && < 1.5 , path- , tar >= 0.5 && < 0.6+ -- , tar >= 0.5 && < 0.6 , zip >= 0.2 && < 0.3 , zlib >= 0.6 && < 0.7+ -- For Codec.Archive.Tar+ , process+ , text+ , unix-compat ghc-options: -Wall if flag(dev) ghc-options: -Werror