packages feed

libarchive 2.1.0.1 → 2.1.1.0

raw patch · 13 files changed

+139/−105 lines, 13 files

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # libarchive +## 2.1.1.0++  * Remove weeds, export things that were missing from past releases+ ## 2.1.0.1    * `packEntries` and friends now detect hardlinks
README.md view
@@ -18,7 +18,7 @@ To run the test suite, first run  ```-./bash/setup+make -j ```  so that you have appropriate test data downloaded.
libarchive.cabal view
@@ -1,6 +1,6 @@ cabal-version:   1.18 name:            libarchive-version:         2.1.0.1+version:         2.1.1.0 license:         BSD3 license-file:    LICENSE copyright:       Copyright: (c) 2018-2019 Vanessa McHale@@ -82,6 +82,10 @@     type:             exitcode-stdio-1.0     main-is:          Spec.hs     hs-source-dirs:   test+    other-modules:+        Codec.Archive.Roundtrip+        Codec.Archive.Test+     default-language: Haskell2010     other-extensions: OverloadedStrings     ghc-options:@@ -97,7 +101,7 @@         filepath -any,         temporary -any,         mtl >=2.2.2,-        dir-traverse,+        dir-traverse -any,         composition-prelude >=2.0.5.0      if impl(ghc >=8.4)
src/Codec/Archive/Foreign/Archive.chs view
@@ -203,6 +203,8 @@                                      , archiveReadDiskSetBehavior                                      , archiveReadDiskSetMatching                                      , archiveReadDiskSetMetadataFilterCallback+                                     , archiveReadDiskNoAcl+                                     , archiveReadDiskNoFFlags                                      -- * Version macros                                      , archiveVersionNumberMacro                                      , archiveVersionOnlyString
src/Codec/Archive/Foreign/Archive/Macros.chs view
@@ -142,11 +142,11 @@ archiveReadDiskNoXattr :: ReadDiskFlags archiveReadDiskNoXattr = ReadDiskFlags {# const ARCHIVE_READDISK_NO_XATTR #} --- | @since 2.0.0.0+-- | @since 2.1.1.0 archiveReadDiskNoAcl :: ReadDiskFlags archiveReadDiskNoAcl = ReadDiskFlags {# const ARCHIVE_READDISK_NO_ACL #} --- | @since 2.0.0.0+-- | @since 2.1.1.0 archiveReadDiskNoFFlags :: ReadDiskFlags archiveReadDiskNoFFlags = ReadDiskFlags {# const ARCHIVE_READDISK_NO_FFLAGS #} 
src/Codec/Archive/Foreign/ArchiveEntry.chs view
@@ -196,6 +196,10 @@                                           , archiveEntryACLEveryone                                           , archiveEntryACLStyleExtraID                                           , archiveEntryACLStyleMarkDefault+                                          , archiveEntryACLEntryInherited+                                          , archiveEntryACLStyleCompact+                                          , archiveEntryACLStyleSeparatorComma+                                          , archiveEntryACLStyleSolaris                                           -- * Abstract types                                           , ArchiveEntry                                           , Stat
src/Codec/Archive/Foreign/ArchiveEntry/Macros.chs view
@@ -105,7 +105,7 @@ archiveEntryACLSynchronize :: EntryACL archiveEntryACLSynchronize = EntryACL {# const ARCHIVE_ENTRY_ACL_SYNCHRONIZE #} --- | @since 2.0.0.0+-- | @since 2.1.1.0 archiveEntryACLEntryInherited :: EntryACL archiveEntryACLEntryInherited = EntryACL {# const ARCHIVE_ENTRY_ACL_ENTRY_INHERITED #} @@ -172,14 +172,14 @@ archiveEntryACLStyleMarkDefault :: EntryACL archiveEntryACLStyleMarkDefault = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT #} --- | @since 2.0.0.0+-- | @since 2.1.1.0 archiveEntryACLStyleSolaris :: EntryACL archiveEntryACLStyleSolaris = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_SOLARIS #} --- | @since 2.0.0.0+-- | @since 2.1.1.0 archiveEntryACLStyleSeparatorComma :: EntryACL archiveEntryACLStyleSeparatorComma = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA #} --- | @since 2.0.0.0+-- | @since 2.1.1.0 archiveEntryACLStyleCompact :: EntryACL archiveEntryACLStyleCompact = EntryACL {# const ARCHIVE_ENTRY_ACL_STYLE_COMPACT #}
src/Codec/Archive/Monad.hs view
@@ -4,7 +4,6 @@                            -- * Bracketed resources within 'ArchiveM'                            , withCStringArchiveM                            , useAsCStringLenArchiveM-                           , allocaArchiveM                            , allocaBytesArchiveM                            , ArchiveM                            ) where@@ -49,9 +48,6 @@            -> (b -> ExceptT c IO d) -- ^ The action            -> ExceptT c IO d genBracket f x = flipExceptIO . f x . (runExceptT .)--allocaArchiveM :: Storable a => (Ptr a -> ExceptT b IO c) -> ExceptT b IO c-allocaArchiveM = genBracket (pure alloca) ()  allocaBytesArchiveM :: Int -> (Ptr a -> ExceptT b IO c) -> ExceptT b IO c allocaBytesArchiveM = genBracket allocaBytes
src/Codec/Archive/Pack/Common.hs view
@@ -2,15 +2,14 @@  import           Codec.Archive.Types import qualified Data.ByteString          as BS-import           System.PosixCompat.Files (fileGroup, fileMode, fileOwner,-                                           getFileStatus, isDirectory,-                                           isRegularFile, isSymbolicLink,-                                           linkCount, readSymbolicLink)+import           System.PosixCompat.Files (FileStatus, fileGroup, fileMode, fileOwner, getFileStatus, isDirectory, isRegularFile, isSymbolicLink, linkCount,+                                           readSymbolicLink) -mkContent :: FilePath -> IO EntryContent-mkContent fp = do-    status <- getFileStatus fp+mkContent :: FilePath -> FileStatus -> IO EntryContent+mkContent fp status =     let res = (isRegularFile status, isDirectory status, isSymbolicLink status, linkCount status)+    in+     case res of         (True, False, False, 1) -> NormalFile <$> BS.readFile fp         (True, False, False, _) -> pure $ Hardlink fp@@ -21,6 +20,6 @@ mkEntry :: FilePath -> IO Entry mkEntry fp = do     status <- getFileStatus fp-    content' <- mkContent fp+    content' <- mkContent fp status     pure $ Entry fp content' (fileMode status) (Ownership Nothing Nothing (fromIntegral $ fileOwner status) (fromIntegral $ fileGroup status)) Nothing 
src/Codec/Archive/Unpack.hs view
@@ -74,17 +74,17 @@         <*> readTimes entry  -- | Yield the next entry in an archive-getHsEntry :: MonadIO m => Ptr Archive -> m (Maybe Entry)+getHsEntry :: Ptr Archive -> IO (Maybe Entry) getHsEntry a = do-    entry <- liftIO $ getEntry a+    entry <- getEntry a     case entry of         Nothing -> pure Nothing-        Just x  -> Just <$> liftIO (readEntry a x)+        Just x  -> Just <$> readEntry a x  -- | Return a list of 'Entry's. hsEntries :: MonadIO m => Ptr Archive -> m [Entry] hsEntries a = do-    next <- getHsEntry a+    next <- liftIO $ getHsEntry a     case next of         Nothing -> pure []         Just x  -> (x:) <$> hsEntries a
+ test/Codec/Archive/Roundtrip.hs view
@@ -0,0 +1,75 @@+module Codec.Archive.Roundtrip ( itPacksUnpacks+                               , itPacksUnpacksViaFS+                               , roundtrip+                               ) where++import           Codec.Archive+import           Control.Composition        (thread, (.@))+import           Control.Monad.Except       (liftEither)+import           Control.Monad.IO.Class     (liftIO)+import qualified Data.ByteString            as BS+import qualified Data.ByteString.Lazy       as BSL+import           Data.List                  (intersperse, sort)+import           System.Directory           (withCurrentDirectory)+import           System.Directory.Recursive (getDirRecursive)+import           System.IO.Temp             (withSystemTempDirectory)+import           Test.Hspec++newtype TestEntries = TestEntries [Entry]+    deriving (Eq)++instance Show TestEntries where+    showsPrec _ (TestEntries entries) = ("(TestEntries [" ++) . joinBy (", "++) (map showsEntry entries) . ("])" ++) where+        showsEntry entry = ("Entry " ++) .+            ("{filepath=" ++) . shows (filepath entry) .+            (", content=" ++) . showsContent (content entry) .+            (", permissions=" ++) . shows (permissions entry) .+            (", ownership=" ++) . shows (ownership entry) .+            (", time=" ++) . shows (time entry) .+            ("}" ++)+        showsContent (NormalFile bytes) = ("(NormalFile $ " ++) . shows (BS.take 10 bytes) . (" <> undefined)" ++)+        showsContent Directory          = ("Directory" ++)+        showsContent (Symlink target)   = ("(Symlink " ++) . shows target . (')':)+        showsContent (Hardlink target)  = ("(Hardlink " ++) . shows target . (')':)+        joinBy :: ShowS -> [ShowS] -> ShowS+        joinBy sep = thread . intersperse sep++roundtrip :: FilePath -> IO (Either ArchiveResult BSL.ByteString)+roundtrip = fmap (fmap entriesToBSL . readArchiveBSL) . BSL.readFile++itPacksUnpacks :: [Entry] -> Spec+itPacksUnpacks entries = parallel $ it "packs/unpacks successfully without loss" $+    let+        packed = entriesToBSL entries+        unpacked = readArchiveBSL packed+    in+        (TestEntries <$> unpacked) `shouldBe` Right (TestEntries entries)++itPacksUnpacksViaFS :: [Entry] -> Spec+itPacksUnpacksViaFS entries = parallel $ unpackedFromFS $ it "packs/unpacks on filesystem successfully without loss" $ \unpacked ->+        fmap (fmap stripDotSlash . testEntries) unpacked `shouldBe` Right (testEntries entries)++    where++        -- Use this to test content as well+        -- testEntries = TestEntries . sortOn filepath . map (stripOwnership . stripPermissions)+        testEntries = sort . map filepath+        unpackedFromFS = around $ \action ->+            withSystemTempDirectory "spec-" $ \tmpdir -> do+            unpacked <- {- withCurrentDirectory tmpdir . -} runArchiveM $ do+                entriesToDir tmpdir entries+                packed <- liftIO . withCurrentDirectory tmpdir $ do+                    files <- getDirRecursive "."+                    packFiles files+                liftEither $ readArchiveBSL packed++            action unpacked++        stripDotSlash :: FilePath -> FilePath+        stripDotSlash ('.':'/':fp) = fp+        stripDotSlash fp           = fp++-- TODO: expose something like this via archive_write_disk+-- entriesToDir :: Foldable t => FilePath -> t Entry -> ArchiveM ()+entriesToDir :: FilePath -> [Entry] -> ArchiveM ()+entriesToDir = entriesToBSL .@ unpackToDirLazy
+ test/Codec/Archive/Test.hs view
@@ -0,0 +1,20 @@+module Codec.Archive.Test ( simpleFile+                          , simpleDir+                          , stripOwnership+                          , stripTime+                          ) where++import           Codec.Archive++simpleFile :: FilePath -> EntryContent -> Entry+simpleFile name what = Entry name what standardPermissions (Ownership (Just "root") (Just "root") 0 0) (Just (0, 0))++simpleDir :: FilePath -> Entry+simpleDir name = Entry name Directory dirPermissions (Ownership (Just "root") (Just "root") 0 0) (Just (0, 0))++dirPermissions :: Permissions+dirPermissions = executablePermissions++stripOwnership, stripTime :: Entry -> Entry+stripOwnership entry = entry { ownership = Ownership Nothing Nothing 0 0 }+stripTime entry = entry { time = Nothing }
test/Spec.hs view
@@ -2,81 +2,29 @@ module Main ( main ) where  import           Codec.Archive-import           Control.Composition        (thread, (.@))-import           Control.Monad.Except-import qualified Data.ByteString            as BS-import qualified Data.ByteString.Lazy       as BSL-import           Data.Either                (isRight)-import           Data.Foldable              (traverse_)-import           Data.List                  (intersperse, sort)-import           System.Directory           (doesDirectoryExist, listDirectory, withCurrentDirectory)-import           System.Directory.Recursive (getDirRecursive)-import           System.FilePath            ((</>))-import           System.IO.Temp             (withSystemTempDirectory)+import           Codec.Archive.Roundtrip (itPacksUnpacks, itPacksUnpacksViaFS, roundtrip)+import           Codec.Archive.Test+import           Data.Either             (isRight)+import           Data.Foldable           (traverse_)+import           System.Directory        (doesDirectoryExist, listDirectory)+import           System.FilePath         ((</>)) import           Test.Hspec --newtype TestEntries = TestEntries [Entry]-    deriving (Eq)--instance Show TestEntries where-    showsPrec _ (TestEntries entries) = ("(TestEntries [" ++) . joinBy (", "++) (map showsEntry entries) . ("])" ++) where-        showsEntry entry = ("Entry " ++) .-            ("{filepath=" ++) . shows (filepath entry) .-            (", content=" ++) . showsContent (content entry) .-            (", permissions=" ++) . shows (permissions entry) .-            (", ownership=" ++) . shows (ownership entry) .-            (", time=" ++) . shows (time entry) .-            ("}" ++)-        showsContent (NormalFile bytes) = ("(NormalFile $ " ++) . shows (BS.take 10 bytes) . (" <> undefined)" ++)-        showsContent Directory          = ("Directory" ++)-        showsContent (Symlink target)   = ("(Symlink " ++) . shows target . (')':)-        showsContent (Hardlink target)  = ("(Hardlink " ++) . shows target . (')':)-        joinBy :: ShowS -> [ShowS] -> ShowS-        joinBy sep = thread . intersperse sep--roundtrip :: FilePath -> IO (Either ArchiveResult BSL.ByteString)-roundtrip = fmap (fmap entriesToBSL . readArchiveBSL) . BSL.readFile--itPacksUnpacks :: HasCallStack => [Entry] -> Spec-itPacksUnpacks entries = parallel $ it "packs/unpacks successfully without loss" $-        (TestEntries <$> unpacked) `shouldBe` Right (TestEntries entries)-    where-        packed = entriesToBSL entries-        unpacked = readArchiveBSL packed--itPacksUnpacksViaFS :: HasCallStack => [Entry] -> Spec-itPacksUnpacksViaFS entries = parallel $ unpackedFromFS $ it "packs/unpacks on filesystem successfully without loss" $ \unpacked ->-        fmap (fmap stripDotSlash . testEntries) unpacked `shouldBe` Right (testEntries entries)-    where-        -- Use this to test content as well-        -- testEntries = TestEntries . sortOn filepath . map (stripOwnership . stripPermissions)-        testEntries = sort . map filepath-        unpackedFromFS = around $ \action ->-            withSystemTempDirectory "spec-" $ \tmpdir -> do-            unpacked <- {- withCurrentDirectory tmpdir . -} runArchiveM $ do-                entriesToDir tmpdir entries-                packed <- liftIO . withCurrentDirectory tmpdir $ do-                    files <- getDirRecursive "."-                    packFiles files-                liftEither $ readArchiveBSL packed--            action unpacked-        stripDotSlash :: FilePath -> FilePath-        stripDotSlash ('.':'/':fp) = fp-        stripDotSlash fp           = fp- testFp :: HasCallStack => FilePath -> Spec testFp fp = parallel $ it ("sucessfully unpacks/packs (" ++ fp ++ ")") $     roundtrip fp >>= (`shouldSatisfy` isRight)  main :: IO () main = do+     dir <- doesDirectoryExist "test/data"     tarballs <- if dir then listDirectory "test/data" else pure []+     hspec $         describe "roundtrip" $ do+             traverse_ testFp (("test/data" </>) <$> tarballs)+             context "with symlinks" $ do                 let entries =                         [ simpleDir "x/"@@ -108,21 +56,3 @@                 [ stripOwnership (simpleFile "a.txt" (NormalFile "text")) ]             xcontext "having entry without timestamp" . itPacksUnpacks $                 [ stripTime (simpleFile "a.txt" (NormalFile "text")) ]--simpleFile :: FilePath -> EntryContent -> Entry-simpleFile name what = Entry name what standardPermissions (Ownership (Just "root") (Just "root")  0 0) (Just (0,0))--simpleDir :: FilePath -> Entry-simpleDir name = Entry name Directory dirPermissions (Ownership (Just "root") (Just "root")  0 0) (Just (0,0))--dirPermissions :: Permissions-dirPermissions = executablePermissions---- TODO: expose something like this via archive_write_disk--- entriesToDir :: Foldable t => FilePath -> t Entry -> ArchiveM ()-entriesToDir :: FilePath -> [Entry] -> ArchiveM ()-entriesToDir = entriesToBSL .@ unpackToDirLazy--stripOwnership, stripTime :: Entry -> Entry-stripOwnership entry = entry { ownership = Ownership Nothing Nothing 0 0 }-stripTime entry = entry { time = Nothing }