hstar (empty) → 0.1.0.0
raw patch · 5 files changed
+255/−0 lines, 5 filesdep +archive-libarchivedep +archive-sigdep +archive-tar
Dependencies added: archive-libarchive, archive-sig, archive-tar, base, bytestring, bz2, lz4-hs, lzlib, lzma, optparse-applicative, zlib, zstd
Files
- LICENSE +11/−0
- hstar.cabal +73/−0
- src/Compression.hs +60/−0
- src/Main.hs +86/−0
- src/Version.cpphs +25/−0
+ LICENSE view
@@ -0,0 +1,11 @@+Copyright Vanessa McHale (c) 2019-2020++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ hstar.cabal view
@@ -0,0 +1,73 @@+cabal-version: 2.0+name: hstar+version: 0.1.0.0+license: BSD3+license-file: LICENSE+copyright: Copyright: (c) 2019-2020 Vanessa McHale+maintainer: vamchale@gmail.com+author: Vanessa McHale+synopsis: Haskell version of tar CLI utility+description:+ Haskell implementation of the tar utility, demonstrating backpack++category: Codec, Tar, Archive+build-type: Simple++source-repository head+ type: git+ location: https://github.com/vmchale/archive-backpack+ subdir: hstar++flag development+ description: Enable `-Werror`+ default: False+ manual: True++flag pure+ description: Use Haskell backend instead of libarchive+ default: False++executable hstar+ main-is: Main.hs+ build-tool-depends: cpphs:cpphs -any+ hs-source-dirs: src+ other-modules:+ Compression+ Paths_hstar+ Version++ autogen-modules: Paths_hstar+ default-language: Haskell2010+ ghc-options:+ -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates+ -Wredundant-constraints -Widentities -Wmissing-export-lists++ build-depends:+ base >=4.11 && <5,+ archive-sig >=0.2.1.2,+ optparse-applicative -any,+ bytestring -any,+ lzma -any,+ bz2 >=1.0.0.0,+ zlib -any,+ zstd -any,+ lz4-hs >=0.1.1.0,+ lzlib >=1.0.1.0++ if impl(ghc >=8.10)+ ghc-options: -Wunused-packages++ if flag(pure)+ build-depends: archive-tar -any++ else+ build-depends: archive-libarchive -any++ if flag(pure)+ mixins: archive-tar (Archive.Tar as Archive)++ else+ mixins: archive-libarchive (Archive.FFI as Archive)++ if flag(development)+ ghc-options: -Werror
+ src/Compression.hs view
@@ -0,0 +1,60 @@+module Compression ( compressionByFileExt+ , decompressor+ , compressor+ ) where++import qualified Codec.Compression.BZip as BZip+import qualified Codec.Compression.GZip as GZip+import qualified Codec.Compression.Lzma as Lzma+import qualified Codec.Compression.Zlib as Zlib+import qualified Codec.Compression.Zstd.Lazy as Zstd+import qualified Codec.Lz4 as Lz4+import Codec.Lzip as Lzip+import qualified Data.ByteString.Lazy as BSL+import Data.List (isSuffixOf)++data Compressor = Lzma+ | Lz+ | Bz2+ | GZip+ | Zstd+ | Deflate+ | Lz4+ | None++compressionByFileExt :: FilePath -> Compressor+compressionByFileExt fp | ".tgz" `isSuffixOf` fp = GZip+ | ".tar.bz2" `isSuffixOf` fp = Bz2+ | ".tar.bz" `isSuffixOf` fp = Bz2+ | ".tbz2" `isSuffixOf` fp = Bz2+ | ".tbz" `isSuffixOf` fp = Bz2+ | ".tar.gz" `isSuffixOf` fp = GZip+ | ".tar.xz" `isSuffixOf` fp = Lzma+ | ".txz" `isSuffixOf` fp = Lzma+ | ".tar.lz" `isSuffixOf` fp = Lz+ | ".tlz" `isSuffixOf` fp = Lz+ | ".tar.zst" `isSuffixOf` fp = Zstd+ | ".tar.Z" `isSuffixOf` fp = Deflate+ | ".tar.lz4" `isSuffixOf` fp = Lz4+ | ".tar" `isSuffixOf` fp = None+ | otherwise = error "Suffix not supported or invalid."++decompressor :: Compressor -> (BSL.ByteString -> BSL.ByteString)+decompressor Lzma = Lzma.decompress+decompressor Bz2 = BZip.decompress+decompressor GZip = GZip.decompress+decompressor Lz = Lzip.decompress+decompressor Zstd = Zstd.decompress+decompressor Deflate = Zlib.decompress+decompressor Lz4 = Lz4.decompress+decompressor None = id++compressor :: Compressor -> (BSL.ByteString -> BSL.ByteString)+compressor Lzma = Lzma.compress+compressor Bz2 = BZip.compress+compressor GZip = GZip.compress+compressor Lz = Lzip.compress+compressor Zstd = Zstd.compress 3+compressor Deflate = Zlib.compress+compressor Lz4 = Lz4.compress+compressor None = id
+ src/Main.hs view
@@ -0,0 +1,86 @@+module Main ( main ) where++import Archive.Compression+import Compression+import Data.Maybe (fromMaybe)+import Options.Applicative+import Version++-- pack a directory/list of files?+data Command = PackDir !FilePath !FilePath+ | Pack ![FilePath] !FilePath+ | Unpack !FilePath !(Maybe FilePath)+ | PackSrc !FilePath !FilePath++run :: Command -> IO ()+run (Unpack src dest) =+ let dec = decompressor (compressionByFileExt src)+ in unpackFileToDirAndDecompress dec src (fromMaybe "." dest)+run (PackDir dir' tar) =+ let comp = compressor (compressionByFileExt tar)+ in packFromDirAndCompress comp dir' tar+run (Pack fs tar) =+ let comp = compressor (compressionByFileExt tar)+ in packFromFilesAndCompress comp tar fs+run (PackSrc dir' tar) =+ let comp = compressor (compressionByFileExt tar)+ in packSrcDirAndCompress comp dir' tar++unpack :: Parser Command+unpack = Unpack+ <$> argument str+ (metavar "SRC"+ -- <> completer (bashCompleter "file -X '!*.*tar' -o plusdirs")+ <> help "Archive to unpack")+ <*> optional (argument str+ (metavar "DEST"+ <> help "Where to unpack it"))++packDir :: Parser Command+packDir = PackDir+ <$> dir+ <*> archive++packSrc :: Parser Command+packSrc = PackSrc+ <$> dir+ <*> archive++dir :: Parser FilePath+dir = argument str+ (metavar "DIR"+ <> help "Directory to pack up")++archive :: Parser FilePath+archive = argument str+ (metavar "ARCHIVE"+ <> help "File to pack it to")++pack :: Parser Command+pack = Pack+ <$> some (strOption+ (metavar "FILE"+ <> long "file"+ <> short 'f'+ <> help "File to add to archive"))+ <*> archive++cmd :: Parser Command+cmd = hsubparser+ (command "unpack" (info unpack (progDesc "Unpack an archive"))+ <> command "pack-dir" (info packDir (progDesc "Pack a directory's contents into an archive"))+ <> command "pack" (info pack (progDesc "Pack an archive from a list of files"))+ <> command "pack-src" (info packSrc (progDesc "Pack up a source directory as a bundle, ignoring version control and artifact directories"))+ )++versionMod :: Parser (a -> a)+versionMod = infoOption allVersionsString (short 'V' <> long "version" <> help "Show version")++topLevel :: ParserInfo Command+topLevel = info (helper <*> versionMod <*> cmd)+ (fullDesc+ <> progDesc "A Haskell archiver tool"+ <> header "hstar - a flexible archiving tool")++main :: IO ()+main = run =<< execParser topLevel
+ src/Version.cpphs view
@@ -0,0 +1,25 @@+module Version ( allVersionsString ) where++import Archive+import Archive.Generic+import Codec.Compression.BZip+import Codec.Lz4 (lZ4VersionString)+import Codec.Lzip+import qualified Data.Version as V+import qualified Paths_hstar as P++allVersionsString :: String+allVersionsString =+ "hstar version: " ++ V.showVersion P.version ++ "\n"+ ++ "archive-sig version: " ++ V.showVersion archiveSigVersion ++ "\n"+ ++ versionInfo ++ "\n"+ ++ "lzlib-hs: " ++ VERSION_lzlib ++ "\n"+ ++ "lzlib: " ++ lZVersion ++ "\n"+ ++ "lzlib API: " ++ show (lZApiVersion :: Int) ++ "\n"+ ++ "zlib-hs: " ++ VERSION_zlib ++ "\n"+ ++ "lzma-hs: " ++ VERSION_lzma ++ "\n"+ ++ "lz4-hs: " ++ VERSION_lz4_hs ++ "\n"+ ++ "lz4: " ++ lZ4VersionString ++ "\n"+ ++ "zstd-hs: " ++ VERSION_zstd ++ "\n"+ ++ "bz2-hs: " ++ VERSION_bz2 ++ "\n"+ ++ "bz2: " ++ bZ2BzlibVersion