commit ghc-zip-archive for openSUSE:Factory
![](https://seccdn.libravatar.org/avatar/e2145bc5cf53dda95c308a3c75e8fef3.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package ghc-zip-archive for openSUSE:Factory checked in at 2016-10-19 13:04:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-zip-archive (Old) and /work/SRC/openSUSE:Factory/.ghc-zip-archive.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "ghc-zip-archive" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-zip-archive/ghc-zip-archive.changes 2016-07-20 09:22:25.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-zip-archive.new/ghc-zip-archive.changes 2016-10-19 13:05:01.000000000 +0200 @@ -1,0 +2,5 @@ +Thu Sep 15 06:55:45 UTC 2016 - psimons@suse.com + +- Update to version 0.3.0.5 revision 0 with cabal2obs. + +------------------------------------------------------------------- Old: ---- zip-archive-0.2.3.7.tar.gz New: ---- zip-archive-0.3.0.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-zip-archive.spec ++++++ --- /var/tmp/diff_new_pack.6op0HY/_old 2016-10-19 13:05:03.000000000 +0200 +++ /var/tmp/diff_new_pack.6op0HY/_new 2016-10-19 13:05:03.000000000 +0200 @@ -19,15 +19,14 @@ %global pkg_name zip-archive %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.2.3.7 +Version: 0.3.0.5 Release: 0 Summary: Library for creating and modifying zip archives License: BSD-3-Clause -Group: System/Libraries +Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel -# Begin cabal-rpm deps: BuildRequires: ghc-array-devel BuildRequires: ghc-binary-devel BuildRequires: ghc-bytestring-devel @@ -47,8 +46,8 @@ %if %{with tests} BuildRequires: ghc-HUnit-devel BuildRequires: ghc-process-devel +BuildRequires: ghc-temporary-devel %endif -# End cabal-rpm deps %description The zip-archive library provides functions for creating, modifying, and @@ -68,20 +67,14 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %check -%if %{with tests} -%{cabal} test -%endif - +%cabal_test %post devel %ghc_pkg_recache ++++++ zip-archive-0.2.3.7.tar.gz -> zip-archive-0.3.0.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2.3.7/Zip.hs new/zip-archive-0.3.0.5/Zip.hs --- old/zip-archive-0.2.3.7/Zip.hs 2015-01-21 20:09:49.000000000 +0100 +++ new/zip-archive-0.3.0.5/Zip.hs 2016-09-12 14:00:23.000000000 +0200 @@ -17,6 +17,8 @@ import System.Console.GetOpt import Control.Monad ( when ) import Control.Applicative ( (<$>) ) +import Data.Version ( showVersion ) +import Paths_zip_archive ( version ) data Flag = Quiet @@ -45,7 +47,9 @@ progname <- getProgName let header = "Usage: " ++ progname ++ " [OPTION...] archive files..." (opts, args) <- case getOpt Permute options argv of - (o, _, _) | Version `elem` o -> putStrLn "version 0.1.1.4" >> exitWith ExitSuccess + (o, _, _) | Version `elem` o -> do + putStrLn ("version " ++ showVersion version) + exitWith ExitSuccess (o, _, _) | Help `elem` o -> error $ usageInfo header options (o, (a:as), []) -> return (o, a:as) (_, _, errs) -> error $ concat errs ++ "\n" ++ usageInfo header options diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2.3.7/changelog new/zip-archive-0.3.0.5/changelog --- old/zip-archive-0.2.3.7/changelog 2015-01-21 20:09:49.000000000 +0100 +++ new/zip-archive-0.3.0.5/changelog 2016-09-12 14:59:09.000000000 +0200 @@ -1,3 +1,49 @@ +zip-archive 0.3.0.5 + + * Fix `OptLocation` option handling (EugeneN). + +zip-archive 0.3.0.4 + + * Fix `toArchive` so it doesn't use too much memory when a data + data descriptor holds the size (Michael Stahl, #29). + The size fields in the local file headers may not contain valid values, + in which case the sizes are stored in a "data descriptor" that follows + the file data. Previously handling this case required reading the + entire archive is a `[Word8]` list. With this change, `getWordsTilSig` + iteratively reads chunks as strict ByteStrings and converts them to + a lazy ByteString at the end. + +zip-archive 0.3.0.3 + + * Test suite: use withTempDir to create temporary directory. + This should help fix problems some have encountered with the + test suite leaving a temporary directory behind. + +zip-archive 0.3.0.2 + + * Fix test suite so it runs on Windows. + * Zip executable: get version from cabal `Paths_zip_archive` (#27). + +zip-archive 0.3.0.1 + + * Set `eVersionMadeBy` to 0 (default) in `toEntry`, since we are + setting external attributes to 0. See jgm/pandoc#2822. + Only to `eVersionMadeBy` to UNIX if we actually read file + attributes on a UNIX system. + +zip-archive 0.3 + + * Support preservation of file modes on Posix (Dan Aloni, #26). + * Add `eVersionMadeBy` field to `Entry` (API change). + * Export `ZipException` (API change). + * `fromEntry` no longer checks for CRC32 match. Previously, it issued + `error` if the match failed. CRC32 match is now checked in `writeEntry` + instead, and a `CRC32Exception` is raised if the checksum doesn't match. + * Test suite: return nonzero status if there are test failures. + Previously we mistakenly did this only on 'errors', not failures. + * Test suite: don't use -9 with zip as it isn't always available. + * Use .travis.yml that builds on both stack and cabal. + zip-archive 0.2.3.7 * Declared test suite's dependency on 'zip' using custom Setup.lhs (#21,#22). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2.3.7/src/Codec/Archive/Zip.hs new/zip-archive-0.3.0.5/src/Codec/Archive/Zip.hs --- old/zip-archive-0.2.3.7/src/Codec/Archive/Zip.hs 2015-01-21 20:09:49.000000000 +0100 +++ new/zip-archive-0.3.0.5/src/Codec/Archive/Zip.hs 2016-09-12 14:00:23.000000000 +0200 @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveDataTypeable #-} ------------------------------------------------------------------------ -- | -- Module : Codec.Archive.Zip @@ -34,6 +35,7 @@ , Entry (..) , CompressionMethod (..) , ZipOption (..) + , ZipException (..) , emptyArchive -- * Pure functions for working with zip archives @@ -64,10 +66,13 @@ import Data.Binary.Get import Data.Binary.Put import Data.List ( nub, find, intercalate ) +import Data.Data (Data) +import Data.Typeable (Typeable) import Text.Printf import System.FilePath import System.Directory ( doesDirectoryExist, getDirectoryContents, createDirectoryIfMissing ) import Control.Monad ( when, unless, zipWithM ) +import qualified Control.Exception as E import System.Directory ( getModificationTime ) import System.IO ( stderr, hPutStrLn ) import qualified Data.Digest.CRC32 as CRC32 @@ -76,10 +81,11 @@ import Control.Applicative #endif #ifndef _WINDOWS -import System.Posix.Files ( setFileTimes ) +import System.Posix.Files ( setFileTimes, setFileMode, fileMode, getFileStatus ) #endif -- from bytestring +import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as B -- text @@ -89,6 +95,13 @@ -- from zlib import qualified Codec.Compression.Zlib.Raw as Zlib +versionMadeBy :: Word16 +#ifdef _WINDOWS +versionMadeBy = 0x0000 -- FAT/VFAT/VFAT32 file attributes +#else +versionMadeBy = 0x0300 -- UNIX file attributes +#endif + #if !MIN_VERSION_binary(0, 6, 0) manySig :: Word32 -> Get a -> Get [a] manySig sig p = do @@ -126,6 +139,7 @@ , eUncompressedSize :: Word32 -- ^ Uncompressed size in bytes , eExtraField :: B.ByteString -- ^ Extra field - unused by this library , eFileComment :: B.ByteString -- ^ File comment - unused by this library + , eVersionMadeBy :: Word16 -- ^ Version made by field , eInternalFileAttributes :: Word16 -- ^ Internal file attributes - unused by this library , eExternalFileAttributes :: Word32 -- ^ External file attributes (system-dependent) , eCompressedData :: B.ByteString -- ^ Compressed contents of file @@ -143,6 +157,12 @@ | OptLocation FilePath Bool -- ^ Where to place file when adding files and whether to append current path deriving (Read, Show, Eq) +data ZipException = + CRC32Mismatch FilePath + deriving (Show, Typeable, Data) + +instance E.Exception ZipException + -- | A zip archive with no contents. emptyArchive :: Archive emptyArchive = Archive @@ -197,10 +217,7 @@ -- | Returns uncompressed contents of zip entry. fromEntry :: Entry -> B.ByteString fromEntry entry = - let uncompressedData = decompressData (eCompressionMethod entry) (eCompressedData entry) - in if eCRC32 entry == CRC32.crc32 uncompressedData - then uncompressedData - else error "CRC32 mismatch" + decompressData (eCompressionMethod entry) (eCompressedData entry) -- | Create an 'Entry' with specified file path, modification time, and contents. toEntry :: FilePath -- ^ File path for entry @@ -225,6 +242,7 @@ , eUncompressedSize = fromIntegral uncompressedSize , eExtraField = B.empty , eFileComment = B.empty + , eVersionMadeBy = 0 -- FAT , eInternalFileAttributes = 0 -- potentially non-text , eExternalFileAttributes = 0 -- appropriate if from stdin , eCompressedData = finalData @@ -240,7 +258,7 @@ _ | isDir -> "/" | otherwise -> "") in (case [(l,a) | OptLocation l a <- opts] of - ((l,a):_) -> if a then l > p else l + ((l,a):_) -> if a then l > p else l > takeFileName p _ -> p) contents <- if isDir then return B.empty @@ -252,16 +270,29 @@ (TOD modEpochTime _) <- getModificationTime path #endif let entry = toEntry path' modEpochTime contents + + entryE <- +#ifdef _WINDOWS + return $ entry +#else + do fm <- fmap fileMode $ getFileStatus path + let modes = fromIntegral $ shiftL (toInteger fm) 16 + return $ entry { eExternalFileAttributes = modes, + eVersionMadeBy = versionMadeBy } +#endif + when (OptVerbose `elem` opts) $ do - let compmethod = case eCompressionMethod entry of + let compmethod = case eCompressionMethod entryE of Deflate -> "deflated" NoCompression -> "stored" hPutStrLn stderr $ - printf " adding: %s (%s %.f%%)" (eRelativePath entry) - compmethod (100 - (100 * compressionRatio entry)) - return entry - --- | Writes contents of an 'Entry' to a file. + printf " adding: %s (%s %.f%%)" (eRelativePath entryE) + compmethod (100 - (100 * compressionRatio entryE)) + return entryE + +-- | Writes contents of an 'Entry' to a file. Throws a +-- 'CRC32Mismatch' exception if the CRC32 checksum for the entry +-- does not match the uncompressed data. writeEntry :: [ZipOption] -> Entry -> IO () writeEntry opts entry = do let path = case [d | OptDestination d <- opts] of @@ -281,7 +312,16 @@ hPutStrLn stderr $ case eCompressionMethod entry of Deflate -> " inflating: " ++ path NoCompression -> "extracting: " ++ path - B.writeFile path (fromEntry entry) + let uncompressedData = fromEntry entry + if eCRC32 entry == CRC32.crc32 uncompressedData + then B.writeFile path uncompressedData + else E.throwIO $ CRC32Mismatch path +#ifndef _WINDOWS + let modes = fromIntegral $ shiftR (eExternalFileAttributes entry) 16 + when (eVersionMadeBy entry == 0x0300 && + modes /= 0) $ setFileMode path modes +#endif + -- Note that last modified times are supported only for POSIX, not for -- Windows. setFileTimeStamp path (eLastModified entry) @@ -465,7 +505,7 @@ locals <- manySig 0x04034b50 getLocalFile files <- manySig 0x02014b50 (getFileHeader (M.fromList locals)) digSig <- lookAheadM getDigitalSignature -#endif +#endif endSig <- getWord32le unless (endSig == 0x06054b50) $ fail "Did not find end of central directory signature" @@ -566,20 +606,64 @@ skip 4 -- crc32 cs <- getWord32le -- compressed size skip 4 -- uncompressed size - if fromIntegral cs == length raw - then return $ B.pack raw - else fail "Content size mismatch in data descriptor record" + if fromIntegral cs == B.length raw + then return $ raw + else fail "Content size mismatch in data descriptor record" return (fromIntegral offset, compressedData) -getWordsTilSig :: Word32 -> Get [Word8] -getWordsTilSig sig = go [] - where - go acc = do +getWordsTilSig :: Word32 -> Get B.ByteString #if MIN_VERSION_binary(0, 6, 0) - (getWord32le >>= ensure (== sig) >> return (reverse acc)) <|> - do w <- getWord8 - go (w:acc) +getWordsTilSig sig = (B.fromChunks . reverse) `fmap` go Nothing [] + where + sig' = S.pack [fromIntegral $ sig .&. 0xFF, + fromIntegral $ sig `shiftR` 8 .&. 0xFF, + fromIntegral $ sig `shiftR` 16 .&. 0xFF, + fromIntegral $ sig `shiftR` 24 .&. 0xFF] + chunkSize = 16384 + --chunkSize = 4 -- for testing prefix match + checkChunk chunk = do -- find in content + let (prefix, start) = S.breakSubstring sig' chunk + if S.null start + then return $ Right chunk + else return $ Left $ S.length prefix + go :: Maybe (Word8, Word8, Word8) -> [S.ByteString] -> Get [S.ByteString] + go prefixes acc = do + -- note: lookAheadE will rewind if the result is Left + eitherChunkOrIndex <- lookAheadE $ do + chunk <- getByteString chunkSize <|> B.toStrict `fmap` getRemainingLazyByteString + case prefixes of + Just (byte3,byte2,byte1) -> + let len = S.length chunk in + if len >= 1 && + S.pack [byte3,byte2,byte1,S.index chunk 0] == sig' + then return $ Left $ -3 + else if len >= 2 && + S.pack [byte2,byte1,S.index chunk 0,S.index chunk 1] == sig' + then return $ Left $ -2 + else if len >= 3 && + S.pack [byte1,S.index chunk 0,S.index chunk 1,S.index chunk 2] == sig' + then return $ Left $ -1 + else checkChunk chunk + Nothing -> checkChunk chunk + case eitherChunkOrIndex of + Left index -> if index < 0 + then do -- prefix match + skip (4 + index) -- skip over partial match in next chunk + return $ (S.take (S.length (head acc) + index) (head acc)) : (tail acc) + else do -- match inside this chunk + lastchunk <- getByteString index -- must read again + skip 4 + return (lastchunk:acc) + Right chunk -> if len == chunkSize + then go prefixes' (chunk:acc) + else fail $ "getWordsTilSig: signature not found before EOF" + where + len = S.length chunk + prefixes' = Just $ (S.index chunk (len - 3), S.index chunk (len - 2), S.index chunk (len - 1)) #else +getWordsTilSig sig = B.pack `fmap` go [] + where + go acc = do sig' <- lookAhead getWord32le if sig == sig' then skip 4 >> return (reverse acc) @@ -637,7 +721,7 @@ -> Get Entry getFileHeader locals = do getWord32le >>= ensure (== 0x02014b50) - skip 2 -- version made by + vmb <- getWord16le -- version made by versionNeededToExtract <- getWord8 skip 1 -- upper byte indicates OS part of "version needed to extract" unless (versionNeededToExtract <= 20) $ @@ -678,6 +762,7 @@ , eUncompressedSize = uncompressedSize , eExtraField = extraField , eFileComment = fileComment + , eVersionMadeBy = vmb , eInternalFileAttributes = internalFileAttributes , eExternalFileAttributes = externalFileAttributes , eCompressedData = compressedData @@ -688,7 +773,7 @@ -> Put putFileHeader offset local = do putWord32le 0x02014b50 - putWord16le 0 -- version made by + putWord16le $ eVersionMadeBy local putWord16le 20 -- version needed to extract (>= 2.0) putWord16le 0x802 -- general purpose bit flag (bit 1 = max compression, bit 11 = UTF-8) putWord16le $ case eCompressionMethod local of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2.3.7/tests/test-zip-archive.hs new/zip-archive-0.3.0.5/tests/test-zip-archive.hs --- old/zip-archive-0.2.3.7/tests/test-zip-archive.hs 2015-01-21 20:09:49.000000000 +0100 +++ new/zip-archive-0.3.0.5/tests/test-zip-archive.hs 2016-09-12 14:00:23.000000000 +0200 @@ -1,4 +1,5 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} +{-# LANGUAGE CPP #-} -- Test suite for Codec.Archive.Zip -- runghc Test.hs @@ -10,6 +11,11 @@ import qualified Data.ByteString.Lazy as B import Control.Applicative import System.Exit +import System.IO.Temp (withTempDirectory) + +#ifndef _WINDOWS +import System.Posix.Files +#endif -- define equality for Archives so timestamps aren't distinguished if they -- correspond to the same MSDOS datetime. @@ -20,33 +26,37 @@ y { eLastModified = eLastModified y `div` 2 }) (zEntries a1) (zEntries a2)) main :: IO Counts -main = do - createDirectory "test-temp" - res <- runTestTT $ TestList [ testReadWriteArchive +main = withTempDirectory "." "test-zip-archive." $ \tmpDir -> do + res <- runTestTT $ TestList $ map (\f -> f tmpDir) + [ testReadWriteArchive , testReadExternalZip , testFromToArchive , testReadWriteEntry , testAddFilesOptions , testDeleteEntries , testExtractFiles +#ifndef _WINDOWS + , testExtractFilesWithPosixAttrs +#endif ] - removeDirectoryRecursive "test-temp" - exitWith $ case errors res of + exitWith $ case (failures res + errors res) of 0 -> ExitSuccess n -> ExitFailure n -testReadWriteArchive :: Test -testReadWriteArchive = TestCase $ do +testReadWriteArchive :: FilePath -> Test +testReadWriteArchive tmpDir = TestCase $ do archive <- addFilesToArchive [OptRecursive] emptyArchive ["LICENSE", "src"] - B.writeFile "test-temp/test1.zip" $ fromArchive archive - archive' <- toArchive <$> B.readFile "test-temp/test1.zip" + B.writeFile (tmpDir ++ "/test1.zip") $ fromArchive archive + archive' <- toArchive <$> B.readFile (tmpDir ++ "/test1.zip") assertEqual "for writing and reading test1.zip" archive archive' assertEqual "for writing and reading test1.zip" archive archive' -testReadExternalZip :: Test -testReadExternalZip = TestCase $ do - _ <- runCommand "zip -q -9 test-temp/test4.zip zip-archive.cabal src/Codec/Archive/Zip.hs" >>= waitForProcess - archive <- toArchive <$> B.readFile "test-temp/test4.zip" +testReadExternalZip :: FilePath -> Test +testReadExternalZip tmpDir = TestCase $ do + _ <- runCommand ("zip -q " ++ tmpDir ++ + "/test4.zip zip-archive.cabal src/Codec/Archive/Zip.hs") >>= + waitForProcess + archive <- toArchive <$> B.readFile (tmpDir ++ "/test4.zip") let files = filesInArchive archive assertEqual "for results of filesInArchive" ["zip-archive.cabal", "src/Codec/Archive/Zip.hs"] files cabalContents <- B.readFile "zip-archive.cabal" @@ -54,48 +64,64 @@ Nothing -> assertFailure "zip-archive.cabal not found in archive" Just f -> assertEqual "for contents of zip-archive.cabal in archive" cabalContents (fromEntry f) -testFromToArchive :: Test -testFromToArchive = TestCase $ do +testFromToArchive :: FilePath -> Test +testFromToArchive _tmpDir = TestCase $ do archive <- addFilesToArchive [OptRecursive] emptyArchive ["LICENSE", "src"] assertEqual "for (toArchive $ fromArchive archive)" archive (toArchive $ fromArchive archive) -testReadWriteEntry :: Test -testReadWriteEntry = TestCase $ do +testReadWriteEntry :: FilePath -> Test +testReadWriteEntry tmpDir = TestCase $ do entry <- readEntry [] "zip-archive.cabal" - setCurrentDirectory "test-temp" + setCurrentDirectory tmpDir writeEntry [] entry setCurrentDirectory ".." - entry' <- readEntry [] "test-temp/zip-archive.cabal" + entry' <- readEntry [] (tmpDir ++ "/zip-archive.cabal") let entry'' = entry' { eRelativePath = eRelativePath entry, eLastModified = eLastModified entry } assertEqual "for readEntry -> writeEntry -> readEntry" entry entry'' -testAddFilesOptions :: Test -testAddFilesOptions = TestCase $ do +testAddFilesOptions :: FilePath -> Test +testAddFilesOptions _tmpDir = TestCase $ do archive1 <- addFilesToArchive [OptVerbose] emptyArchive ["LICENSE", "src"] archive2 <- addFilesToArchive [OptRecursive, OptVerbose] archive1 ["LICENSE", "src"] assertBool "for recursive and nonrecursive addFilesToArchive" (length (filesInArchive archive1) < length (filesInArchive archive2)) -testDeleteEntries :: Test -testDeleteEntries = TestCase $ do +testDeleteEntries :: FilePath -> Test +testDeleteEntries _tmpDir = TestCase $ do archive1 <- addFilesToArchive [] emptyArchive ["LICENSE", "src"] let archive2 = deleteEntryFromArchive "LICENSE" archive1 let archive3 = deleteEntryFromArchive "src" archive2 assertEqual "for deleteFilesFromArchive" emptyArchive archive3 -testExtractFiles :: Test -testExtractFiles = TestCase $ do - createDirectory "test-temp/dir1" - createDirectory "test-temp/dir1/dir2" +testExtractFiles :: FilePath -> Test +testExtractFiles tmpDir = TestCase $ do + createDirectory (tmpDir ++ "/dir1") + createDirectory (tmpDir ++ "/dir1/dir2") let hiMsg = "hello there" let helloMsg = "Hello there. This file is very long. Longer than 31 characters." - writeFile "test-temp/dir1/hi" hiMsg - writeFile "test-temp/dir1/dir2/hello" helloMsg - archive <- addFilesToArchive [OptRecursive] emptyArchive ["test-temp/dir1"] - removeDirectoryRecursive "test-temp/dir1" + writeFile (tmpDir ++ "/dir1/hi") hiMsg + writeFile (tmpDir ++ "/dir1/dir2/hello") helloMsg + archive <- addFilesToArchive [OptRecursive] emptyArchive [(tmpDir ++ "/dir1")] + removeDirectoryRecursive (tmpDir ++ "/dir1") extractFilesFromArchive [OptVerbose] archive - hi <- readFile "test-temp/dir1/hi" - hello <- readFile "test-temp/dir1/dir2/hello" - assertEqual "contents of test-temp/dir1/hi" hiMsg hi - assertEqual "contents of test-temp/dir1/dir2/hello" helloMsg hello - + hi <- readFile (tmpDir ++ "/dir1/hi") + hello <- readFile (tmpDir ++ "/dir1/dir2/hello") + assertEqual ("contents of " ++ tmpDir ++ "/dir1/hi") hiMsg hi + assertEqual ("contents of " ++ tmpDir ++ "/dir1/dir2/hello") helloMsg hello + +#ifndef _WINDOWS +testExtractFilesWithPosixAttrs :: FilePath -> Test +testExtractFilesWithPosixAttrs tmpDir = TestCase $ do + createDirectory (tmpDir ++ "/dir3") + let hiMsg = "hello there" + writeFile (tmpDir ++ "/dir3/hi") hiMsg + let perms = unionFileModes ownerReadMode $ unionFileModes ownerWriteMode ownerExecuteMode + setFileMode (tmpDir ++ "/dir3/hi") perms + archive <- addFilesToArchive [OptRecursive] emptyArchive [(tmpDir ++ "/dir3")] + removeDirectoryRecursive (tmpDir ++ "/dir3") + extractFilesFromArchive [OptVerbose] archive + hi <- readFile (tmpDir ++ "/dir3/hi") + fm <- fmap fileMode $ getFileStatus (tmpDir ++ "/dir3/hi") + assertEqual "file modes" perms (intersectFileModes perms fm) + assertEqual ("contents of " ++ tmpDir ++ "/dir3/hi") hiMsg hi +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2.3.7/zip-archive.cabal new/zip-archive-0.3.0.5/zip-archive.cabal --- old/zip-archive-0.2.3.7/zip-archive.cabal 2015-01-21 20:09:49.000000000 +0100 +++ new/zip-archive-0.3.0.5/zip-archive.cabal 2016-09-12 14:57:27.000000000 +0200 @@ -1,5 +1,5 @@ Name: zip-archive -Version: 0.2.3.7 +Version: 0.3.0.5 Cabal-Version: >= 1.10 Build-type: Custom Synopsis: Library for creating and modifying zip archives. @@ -51,6 +51,7 @@ Hs-Source-Dirs: . Build-Depends: base >= 4.2 && < 5, directory >= 1.1, bytestring >= 0.9.0, zip-archive + Other-Modules: Paths_zip_archive Ghc-Options: -Wall Default-Language: Haskell98 @@ -60,7 +61,11 @@ Hs-Source-Dirs: tests Build-Depends: base >= 4.2 && < 5, directory, bytestring >= 0.9.0, process, time, old-time, - HUnit, zip-archive + HUnit, zip-archive, temporary Default-Language: Haskell98 Ghc-Options: -Wall Build-Tools: zip + if os(windows) + cpp-options: -D_WINDOWS + else + Build-depends: unix
participants (1)
-
root@hilbert.suse.de