Hello community,

here is the log from the commit of package ghc-zip-archive for openSUSE:Factory 
checked in at 2018-05-30 12:16:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-zip-archive (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-zip-archive.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-zip-archive"

Wed May 30 12:16:11 2018 rev:10 rq:607959 version:0.3.2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-zip-archive/ghc-zip-archive.changes  
2017-07-06 00:03:58.709405162 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-zip-archive.new/ghc-zip-archive.changes     
2018-05-30 12:28:01.104782987 +0200
@@ -1,0 +2,20 @@
+Mon May 14 17:02:11 UTC 2018 - psim...@suse.com
+
+- Update zip-archive to version 0.3.2.4.
+  * Use createSymbolicLink instead of createFileLink in tests. This allows
+    us to lower the directory lower bound (#40).
+
+  * Fixes for handling of symbolic links (#39, Tommaso Piazza).
+
+  * Fixes for symbolic link tests, and additional tests.
+
+  * Add ZipOption to preserve symbolic links (#37, Tommaso Piazza).
+    Add OptPreserveSymbolicLinks constructor to ZipOption.  If this option
+    is set, symbolic links will be preserved.  Symbolic links are not
+    supported on Windows.
+
+  * Require binary >= 0.6 (#36).
+
+  * Improve exit handling in zip-archive program.
+
+-------------------------------------------------------------------

Old:
----
  zip-archive-0.3.1.1.tar.gz

New:
----
  zip-archive-0.3.2.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-zip-archive.spec ++++++
--- /var/tmp/diff_new_pack.mslXzy/_old  2018-05-30 12:28:01.808758131 +0200
+++ /var/tmp/diff_new_pack.mslXzy/_new  2018-05-30 12:28:01.808758131 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-zip-archive
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,12 +19,12 @@
 %global pkg_name zip-archive
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.3.1.1
+Version:        0.3.2.4
 Release:        0
 Summary:        Library for creating and modifying zip archives
 License:        BSD-3-Clause
-Group:          Development/Languages/Other
-Url:            https://hackage.haskell.org/package/%{pkg_name}
+Group:          Development/Libraries/Haskell
+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
 BuildRequires:  ghc-array-devel
@@ -42,7 +42,7 @@
 BuildRequires:  ghc-time-devel
 BuildRequires:  ghc-unix-devel
 BuildRequires:  ghc-zlib-devel
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+BuildRequires:  unzip
 %if %{with tests}
 BuildRequires:  ghc-HUnit-devel
 BuildRequires:  ghc-process-devel
@@ -55,7 +55,7 @@
 
 %package devel
 Summary:        Haskell %{pkg_name} library development files
-Group:          Development/Libraries/Other
+Group:          Development/Libraries/Haskell
 Requires:       %{name} = %{version}-%{release}
 Requires:       ghc-compiler = %{ghc_version}
 Requires(post): ghc-compiler = %{ghc_version}
@@ -83,11 +83,9 @@
 %ghc_pkg_recache
 
 %files -f %{name}.files
-%defattr(-,root,root,-)
-%doc LICENSE
+%license LICENSE
 
 %files devel -f %{name}-devel.files
-%defattr(-,root,root,-)
 %doc README.markdown changelog
 
 %changelog

++++++ zip-archive-0.3.1.1.tar.gz -> zip-archive-0.3.2.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zip-archive-0.3.1.1/Main.hs 
new/zip-archive-0.3.2.4/Main.hs
--- old/zip-archive-0.3.1.1/Main.hs     2017-06-04 13:08:55.000000000 +0200
+++ new/zip-archive-0.3.2.4/Main.hs     2018-01-22 21:11:33.000000000 +0100
@@ -44,6 +44,14 @@
    , Option ['h']   ["help"]       (NoArg Help)          "help"
    ]
 
+quit :: Bool -> String -> IO a
+quit failure msg = do
+  hPutStr stderr msg
+  _ <- exitWith $ if failure
+                     then ExitFailure 1
+                     else ExitSuccess
+  return undefined
+
 main :: IO ()
 main = do
   argv <- getArgs
@@ -53,9 +61,10 @@
       (o, _, _)      | Version `elem` o -> do
         putStrLn ("version " ++ showVersion version)
         exitWith ExitSuccess
-      (o, _, _)      | Help `elem` o    -> error $ usageInfo header options
+      (o, _, _)      | Help `elem` o    -> quit False $ usageInfo header 
options
       (o, (a:as), [])                   -> return (o, a:as)
-      (_, _, errs)                      -> error $ concat errs ++ "\n" ++ 
usageInfo header options
+      (_, [], [])                       -> quit True $ usageInfo header options
+      (_, _, errs)                      -> quit True $ concat errs ++ "\n" ++ 
usageInfo header options
   let verbosity = if Quiet `elem` opts then [] else [OptVerbose]
   let debug = Debug `elem` opts
   let cmd = case filter (`notElem` [Quiet, Help, Version, Debug]) opts of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zip-archive-0.3.1.1/Setup.hs 
new/zip-archive-0.3.2.4/Setup.hs
--- old/zip-archive-0.3.1.1/Setup.hs    2017-06-04 13:52:37.000000000 +0200
+++ new/zip-archive-0.3.2.4/Setup.hs    2018-02-12 19:12:13.000000000 +0100
@@ -1,2 +1,8 @@
 import Distribution.Simple
-main = defaultMain
+import Distribution.Simple.Program
+
+main :: IO ()
+main = defaultMainWithHooks simpleUserHooks
+  { hookedPrograms = [ simpleProgram "unzip"
+                     ]
+  }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zip-archive-0.3.1.1/changelog 
new/zip-archive-0.3.2.4/changelog
--- old/zip-archive-0.3.1.1/changelog   2017-06-19 10:39:30.000000000 +0200
+++ new/zip-archive-0.3.2.4/changelog   2018-02-21 23:27:59.000000000 +0100
@@ -1,3 +1,33 @@
+zip-archive 0.3.2.4
+
+  * Make build-tools stanza conditional on non-windows. Closes #44.
+
+zip-archive 0.3.2.3
+
+  * Use custom-setup stanza and specify build-tools.  Closes #41.
+
+zip-archive 0.3.2.2
+
+  * Use createSymbolicLink instead of createFileLink in tests. This allows
+    us to lower the directory lower bound (#40).
+
+zip-archive 0.3.2.1
+
+  * Fixes for handling of symbolic links (#39, Tommaso Piazza).
+
+  * Fixes for symbolic link tests, and additional tests.
+
+zip-archive 0.3.2
+
+  * Add ZipOption to preserve symbolic links (#37, Tommaso Piazza).
+    Add OptPreserveSymbolicLinks constructor to ZipOption.  If this option
+    is set, symbolic links will be preserved.  Symbolic links are not
+    supported on Windows.
+
+  * Require binary >= 0.6 (#36).
+
+  * Improve exit handling in zip-archive program.
+
 zip-archive 0.3.1.1
 
   * readEntry:  Read file as a strict ByteString.  This avoids
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zip-archive-0.3.1.1/src/Codec/Archive/Zip.hs 
new/zip-archive-0.3.2.4/src/Codec/Archive/Zip.hs
--- old/zip-archive-0.3.1.1/src/Codec/Archive/Zip.hs    2017-06-19 
10:31:55.000000000 +0200
+++ new/zip-archive-0.3.2.4/src/Codec/Archive/Zip.hs    2018-01-22 
21:12:49.000000000 +0100
@@ -48,10 +48,18 @@
        , findEntryByPath
        , fromEntry
        , toEntry
+#ifndef _WINDOWS
+       , isEntrySymbolicLink
+       , symbolicLinkEntryTarget
+       , entryCMode
+#endif
 
        -- * IO functions for working with zip archives
        , readEntry
        , writeEntry
+#ifndef _WINDOWS
+       , writeSymbolicLinkEntry
+#endif
        , addFilesToArchive
        , extractFilesFromArchive
 
@@ -65,8 +73,9 @@
 import Data.Binary
 import Data.Binary.Get
 import Data.Binary.Put
-import Data.List ( nub, find, intercalate )
+import Data.List ( nub, find, intercalate, partition)
 import Data.Data (Data)
+import Data.Maybe (fromJust)
 import Data.Typeable (Typeable)
 import Text.Printf
 import System.FilePath
@@ -81,12 +90,14 @@
 import Control.Applicative
 #endif
 #ifndef _WINDOWS
-import System.Posix.Files ( setFileTimes, setFileMode, fileMode, getFileStatus 
)
+import System.Posix.Files ( setFileTimes, setFileMode, fileMode, 
getSymbolicLinkStatus, symbolicLinkMode, readSymbolicLink, isSymbolicLink, 
unionFileModes, createSymbolicLink )
+import System.Posix.Types ( CMode(..) )
 #endif
 
 -- from bytestring
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as B
+import qualified Data.ByteString.Lazy.Char8 as C (pack, unpack)
 
 -- text
 import qualified Data.Text.Lazy as TL
@@ -155,6 +166,7 @@
                | OptVerbose                 -- ^ Print information to stderr
                | OptDestination FilePath    -- ^ Directory in which to extract
                | OptLocation FilePath Bool  -- ^ Where to place file when 
adding files and whether to append current path
+               | OptPreserveSymbolicLinks   -- ^ Preserve symbolic links as 
such. This option is ignored on Windows.
                deriving (Read, Show, Eq)
 
 data ZipException =
@@ -252,17 +264,34 @@
 readEntry :: [ZipOption] -> FilePath -> IO Entry
 readEntry opts path = do
   isDir <- doesDirectoryExist path
-  -- make sure directories end in / and deal with the OptLocation option
+#ifdef _WINDOWS
+  let isSymLink = False
+#else
+  fs <- getSymbolicLinkStatus path
+  let isSymLink = isSymbolicLink fs
+#endif
+ -- make sure directories end in / and deal with the OptLocation option
   let path' = let p = path ++ (case reverse path of
                                     ('/':_) -> ""
-                                    _ | isDir -> "/"
+                                    _ | isDir && not isSymLink -> "/"
+                                    _ | isDir && isSymLink -> ""
                                       | otherwise -> "") in
               (case [(l,a) | OptLocation l a <- opts] of
                     ((l,a):_) -> if a then l </> p else l </> takeFileName p
                     _         -> p)
-  contents <- if isDir
-                 then return B.empty
-                 else B.fromStrict <$> S.readFile path
+  contents <-
+#ifndef _WINDOWS
+              if isSymLink
+                 then do
+                   linkTarget <- readSymbolicLink path
+                   return $ C.pack linkTarget
+                 else
+#endif
+                   if isDir
+                      then
+                        return B.empty
+                      else
+                        B.fromStrict <$> S.readFile path
 #if MIN_VERSION_directory(1,2,0)
   modEpochTime <- fmap (floor . utcTimeToPOSIXSeconds)
                    $ getModificationTime path
@@ -275,7 +304,11 @@
 #ifdef _WINDOWS
         return $ entry
 #else
-        do fm <- fmap fileMode $ getFileStatus path
+        do
+           let fm = if isSymLink
+                      then unionFileModes symbolicLinkMode (fileMode fs)
+                      else fileMode fs
+
            let modes = fromIntegral $ shiftL (toInteger fm) 16
            return $ entry { eExternalFileAttributes = modes,
                             eVersionMadeBy = versionMadeBy }
@@ -319,20 +352,62 @@
 #ifndef _WINDOWS
        let modes = fromIntegral $ shiftR (eExternalFileAttributes entry) 16
        when (eVersionMadeBy entry .&. 0xFF00 == 0x0300 &&
-             modes /= 0) $ setFileMode path modes
+         modes /= 0) $ setFileMode path modes
 #endif
-
   -- Note that last modified times are supported only for POSIX, not for
   -- Windows.
   setFileTimeStamp path (eLastModified entry)
 
+#ifndef _WINDOWS
+-- | Write an 'Entry' representing a symbolic link to a file.
+-- If the 'Entry' does not represent a symbolic link or
+-- the options do not contain 'OptPreserveSymbolicLinks`, this
+-- function behaves like `writeEntry`.
+writeSymbolicLinkEntry :: [ZipOption] -> Entry -> IO ()
+writeSymbolicLinkEntry opts entry = do
+  if OptPreserveSymbolicLinks `notElem` opts
+     then writeEntry opts entry
+     else do
+        if (isEntrySymbolicLink entry)
+           then do
+             let prefixPath = case [d | OptDestination d <- opts] of
+                                   (x:_) -> x
+                                   _     -> ""
+             let targetPath = fromJust . symbolicLinkEntryTarget $ entry
+             let symlinkPath = prefixPath </> eRelativePath entry
+             when (OptVerbose `elem` opts) $ do
+               hPutStrLn stderr $ "linking " ++ symlinkPath ++ " to " ++ 
targetPath
+             createSymbolicLink targetPath symlinkPath
+           else writeEntry opts entry
+
+
+-- | Get the target of a 'Entry' representing a symbolic link. This might fail
+-- if the 'Entry' does not represent a symbolic link
+symbolicLinkEntryTarget :: Entry -> Maybe FilePath
+symbolicLinkEntryTarget entry | isEntrySymbolicLink entry = Just . C.unpack $ 
fromEntry entry
+                              | otherwise = Nothing
+
+-- | Check if an 'Entry' represents a symbolic link
+isEntrySymbolicLink :: Entry -> Bool
+isEntrySymbolicLink entry = entryCMode entry .&. symbolicLinkMode == 
symbolicLinkMode
+
+-- | Get the 'eExternalFileAttributes' of an 'Entry' as a 'CMode' a.k.a. 
'FileMode'
+entryCMode :: Entry -> CMode
+entryCMode entry = CMode (fromIntegral $ shiftR (eExternalFileAttributes 
entry) 16)
+#endif
+
 -- | Add the specified files to an 'Archive'.  If 'OptRecursive' is specified,
--- recursively add files contained in directories.  If 'OptVerbose' is 
specified,
+-- recursively add files contained in directories. if 
'OptPreserveSymbolicLinks'
+-- is specified, don't recurse into it. If 'OptVerbose' is specified,
 -- print messages to stderr.
 addFilesToArchive :: [ZipOption] -> Archive -> [FilePath] -> IO Archive
 addFilesToArchive opts archive files = do
   filesAndChildren <- if OptRecursive `elem` opts
+#ifdef _WINDOWS
                          then mapM getDirectoryContentsRecursive files >>= 
return . nub . concat
+#else
+                         then mapM (getDirectoryContentsRecursive' opts) files 
>>= return . nub . concat
+#endif
                          else return files
   entries <- mapM (readEntry opts) filesAndChildren
   return $ foldr addEntryToArchive archive entries
@@ -342,8 +417,17 @@
 -- Note that the last-modified time is set correctly only in POSIX,
 -- not in Windows.
 extractFilesFromArchive :: [ZipOption] -> Archive -> IO ()
-extractFilesFromArchive opts archive =
-  mapM_ (writeEntry opts) $ zEntries archive
+extractFilesFromArchive opts archive = do
+  if OptPreserveSymbolicLinks `elem` opts
+    then do
+#ifdef _WINDOWS
+      mapM_ (writeEntry opts) $ zEntries archive
+#else
+      let (symbolicLinkEntries, nonSymbolicLinkEntries) = partition 
isEntrySymbolicLink $ zEntries archive
+      mapM_ (writeEntry opts) $ nonSymbolicLinkEntries
+      mapM_ (writeSymbolicLinkEntry opts) $ symbolicLinkEntries
+#endif
+    else mapM_ (writeEntry opts) $ zEntries archive
 
 
--------------------------------------------------------------------------------
 -- Internal functions for reading and writing zip binary format.
@@ -426,18 +510,38 @@
       (TOD epochsecs _) = addToClockTime timeSinceEpoch (TOD 0 0)
   in  epochsecs
 
+#ifndef _WINDOWS
+getDirectoryContentsRecursive' :: [ZipOption] -> FilePath -> IO [FilePath]
+getDirectoryContentsRecursive' opts path = do
+  if OptPreserveSymbolicLinks `elem` opts
+     then do
+       isDir <- doesDirectoryExist path
+       if isDir
+          then do
+            isSymLink <- fmap isSymbolicLink $ getSymbolicLinkStatus path
+            if isSymLink
+               then return [path]
+               else getDirectoryContentsRecursivelyBy 
(getDirectoryContentsRecursive' opts) path
+          else return [path]
+     else getDirectoryContentsRecursive path
+#endif
+
 getDirectoryContentsRecursive :: FilePath -> IO [FilePath]
 getDirectoryContentsRecursive path = do
   isDir <- doesDirectoryExist path
   if isDir
-     then do
+     then getDirectoryContentsRecursivelyBy getDirectoryContentsRecursive path
+     else return [path]
+
+getDirectoryContentsRecursivelyBy :: (FilePath -> IO [FilePath]) -> FilePath 
-> IO [FilePath]
+getDirectoryContentsRecursivelyBy exploreMethod path = do
        contents <- getDirectoryContents path
        let contents' = map (path </>) $ filter (`notElem` ["..","."]) contents
-       children <- mapM getDirectoryContentsRecursive contents'
+       children <- mapM exploreMethod contents'
        if path == "."
           then return (concat children)
           else return (path : concat children)
-     else return [path]
+
 
 setFileTimeStamp :: FilePath -> Integer -> IO ()
 setFileTimeStamp file epochtime = do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zip-archive-0.3.1.1/tests/test-zip-archive.hs 
new/zip-archive-0.3.2.4/tests/test-zip-archive.hs
--- old/zip-archive-0.3.1.1/tests/test-zip-archive.hs   2017-06-19 
10:17:27.000000000 +0200
+++ new/zip-archive-0.3.2.4/tests/test-zip-archive.hs   2018-02-12 
19:09:05.000000000 +0100
@@ -4,17 +4,21 @@
 -- runghc Test.hs
 
 import Codec.Archive.Zip
-import System.Directory
+import Control.Applicative
+import System.Directory hiding (isSymbolicLink)
 import Test.HUnit.Base
 import Test.HUnit.Text
 import qualified Data.ByteString.Char8 as BS
 import qualified Data.ByteString.Lazy as BL
-import Control.Applicative
 import System.Exit
 import System.IO.Temp (withTempDirectory)
 
 #ifndef _WINDOWS
+import System.FilePath.Posix
 import System.Posix.Files
+import System.Process (rawSystem)
+#else
+import System.FilePath.Windows
 #endif
 
 -- define equality for Archives so timestamps aren't distinguished if they
@@ -25,6 +29,23 @@
              && (all id $ zipWith (\x y -> x { eLastModified = eLastModified x 
`div` 2  } ==
                                            y { eLastModified = eLastModified y 
`div` 2  }) (zEntries a1) (zEntries a2))
 
+#ifndef _WINDOWS
+
+createTestDirectoryWithSymlinks :: FilePath -> FilePath -> IO FilePath
+createTestDirectoryWithSymlinks prefixDir  baseDir = do
+  let testDir = prefixDir </> baseDir
+  createDirectoryIfMissing True testDir
+  createDirectoryIfMissing True (testDir </> "1")
+  writeFile (testDir </> "1/file.txt") "hello"
+  cwd <- getCurrentDirectory
+  createSymbolicLink (cwd </> testDir </> "1/file.txt") (testDir </> 
"link_to_file")
+  createSymbolicLink (cwd </> testDir </> "1") (testDir </> 
"link_to_directory")
+  return testDir
+
+#endif
+
+
+
 main :: IO Counts
 main = withTempDirectory "." "test-zip-archive." $ \tmpDir -> do
   res   <- runTestTT $ TestList $ map (\f -> f tmpDir)
@@ -37,6 +58,9 @@
                                 , testExtractFiles
 #ifndef _WINDOWS
                                 , testExtractFilesWithPosixAttrs
+                                , testArchiveExtractSymlinks
+                                , testExtractExternalZipWithSymlinks
+                                , testArchiveAndUnzip
 #endif
                                 ]
   exitWith $ case (failures res + errors res) of
@@ -46,8 +70,8 @@
 testReadWriteArchive :: FilePath -> Test
 testReadWriteArchive tmpDir = TestCase $ do
   archive <- addFilesToArchive [OptRecursive] emptyArchive ["LICENSE", "src"]
-  BL.writeFile (tmpDir ++ "/test1.zip") $ fromArchive archive
-  archive' <- toArchive <$> BL.readFile (tmpDir ++ "/test1.zip")
+  BL.writeFile (tmpDir </> "test1.zip") $ fromArchive archive
+  archive' <- toArchive <$> BL.readFile (tmpDir </> "test1.zip")
   assertEqual "for writing and reading test1.zip" archive archive'
   assertEqual "for writing and reading test1.zip" archive archive'
 
@@ -69,9 +93,14 @@
                       BL.empty (fromEntry f)
 
 testFromToArchive :: FilePath -> Test
-testFromToArchive _tmpDir = TestCase $ do
-  archive <- addFilesToArchive [OptRecursive] emptyArchive ["LICENSE", "src"]
-  assertEqual "for (toArchive $ fromArchive archive)" archive (toArchive $ 
fromArchive archive)
+testFromToArchive tmpDir = TestCase $ do
+  archive1 <- addFilesToArchive [OptRecursive] emptyArchive ["LICENSE", "src"]
+  assertEqual "for (toArchive $ fromArchive archive)" archive1 (toArchive $ 
fromArchive archive1)
+#ifndef _WINDOWS
+  testDir <- createTestDirectoryWithSymlinks tmpDir "test_dir_with_symlinks"
+  archive2 <- addFilesToArchive [OptRecursive, OptPreserveSymbolicLinks] 
emptyArchive [testDir]
+  assertEqual "for (toArchive $ fromArchive archive)" archive2 (toArchive $ 
fromArchive archive2)
+#endif
 
 testReadWriteEntry :: FilePath -> Test
 testReadWriteEntry tmpDir = TestCase $ do
@@ -79,16 +108,26 @@
   setCurrentDirectory tmpDir
   writeEntry [] entry
   setCurrentDirectory ".."
-  entry' <- readEntry [] (tmpDir ++ "/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 :: FilePath -> Test
-testAddFilesOptions _tmpDir = TestCase $ do
+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))
+#ifndef _WINDOWS
+  testDir <- createTestDirectoryWithSymlinks tmpDir "test_dir_with_symlinks2"
+  archive3 <- addFilesToArchive [OptVerbose, OptRecursive] emptyArchive 
[testDir]
+  archive4 <- addFilesToArchive [OptVerbose, OptRecursive, 
OptPreserveSymbolicLinks] emptyArchive [testDir]
+  mapM_ putStrLn $ filesInArchive archive3
+  mapM_ putStrLn $ filesInArchive archive4
+  assertBool "for recursive and recursive by preserving symlinks 
addFilesToArchive"
+     (length (filesInArchive archive4) < length (filesInArchive archive3))
+#endif
+
 
 testDeleteEntries :: FilePath -> Test
 testDeleteEntries _tmpDir = TestCase $ do
@@ -99,33 +138,88 @@
 
 testExtractFiles :: FilePath -> Test
 testExtractFiles tmpDir = TestCase $ do
-  createDirectory (tmpDir ++ "/dir1")
-  createDirectory (tmpDir ++ "/dir1/dir2")
+  createDirectory (tmpDir </> "dir1")
+  createDirectory (tmpDir </> "dir1/dir2")
   let hiMsg = BS.pack "hello there"
   let helloMsg = BS.pack "Hello there. This file is very long.  Longer than 31 
characters."
-  BS.writeFile (tmpDir ++ "/dir1/hi") hiMsg
-  BS.writeFile (tmpDir ++ "/dir1/dir2/hello") helloMsg
-  archive <- addFilesToArchive [OptRecursive] emptyArchive [(tmpDir ++ 
"/dir1")]
-  removeDirectoryRecursive (tmpDir ++ "/dir1")
+  BS.writeFile (tmpDir </> "dir1/hi") hiMsg
+  BS.writeFile (tmpDir </> "dir1/dir2/hello") helloMsg
+  archive <- addFilesToArchive [OptRecursive] emptyArchive [(tmpDir </> 
"dir1")]
+  removeDirectoryRecursive (tmpDir </> "dir1")
   extractFilesFromArchive [OptVerbose] archive
-  hi <- BS.readFile (tmpDir ++ "/dir1/hi")
-  hello <- BS.readFile (tmpDir ++ "/dir1/dir2/hello")
-  assertEqual ("contents of " ++ tmpDir ++ "/dir1/hi") hiMsg hi
-  assertEqual ("contents of " ++ tmpDir ++ "/dir1/dir2/hello") helloMsg hello
+  hi <- BS.readFile (tmpDir </> "dir1/hi")
+  hello <- BS.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")
+  createDirectory (tmpDir </> "dir3")
   let hiMsg = "hello there"
-  writeFile (tmpDir ++ "/dir3/hi") hiMsg
+  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")
+  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")
+  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
+  assertEqual ("contents of " </> tmpDir </> "dir3/hi") hiMsg hi
+
+testArchiveExtractSymlinks :: FilePath -> Test
+testArchiveExtractSymlinks tmpDir = TestCase $ do
+  testDir <- createTestDirectoryWithSymlinks tmpDir "test_dir_with_symlinks3"
+  let locationDir = "location_dir"
+  archive <- addFilesToArchive [OptRecursive, OptPreserveSymbolicLinks, 
OptLocation locationDir True] emptyArchive [testDir]
+  removeDirectoryRecursive testDir
+  let destination = "test_dest"
+  extractFilesFromArchive [OptPreserveSymbolicLinks, OptDestination 
destination] archive
+  isDirSymlink <- pathIsSymbolicLink (destination </> locationDir </> testDir 
</> "link_to_directory")
+  isFileSymlink <- pathIsSymbolicLink (destination </> locationDir </> testDir 
</> "link_to_file")
+  assertBool "Symbolic link to directory is preserved" isDirSymlink
+  assertBool "Symbolic link to file is preserved" isFileSymlink
+  removeDirectoryRecursive destination
+
+testExtractExternalZipWithSymlinks :: FilePath -> Test
+testExtractExternalZipWithSymlinks tmpDir = TestCase $ do
+  archive <- toArchive <$> BL.readFile "tests/zip_with_symlinks.zip"
+  extractFilesFromArchive [OptPreserveSymbolicLinks, OptDestination tmpDir] 
archive
+  let zipRootDir = "zip_test_dir_with_symlinks"
+      symlinkDir = tmpDir </> zipRootDir </> "symlink_to_dir_1"
+      symlinkFile = tmpDir </> zipRootDir </> "symlink_to_file_1"
+  isDirSymlink <- pathIsSymbolicLink symlinkDir
+  targetDirExists <- doesDirectoryExist symlinkDir
+  isFileSymlink <- pathIsSymbolicLink symlinkFile
+  targetFileExists <- doesFileExist symlinkFile
+  assertBool "Symbolic link to directory is preserved" isDirSymlink
+  assertBool "Target directory exists" targetDirExists
+  assertBool "Symbolic link to file is preserved" isFileSymlink
+  assertBool "Target file exists" targetFileExists
+  removeDirectoryRecursive tmpDir
+
+testArchiveAndUnzip :: FilePath -> Test
+testArchiveAndUnzip tmpDir = TestCase $ do
+  let dir = "test_dir_with_symlinks4"
+  testDir <- createTestDirectoryWithSymlinks tmpDir dir
+  archive <- addFilesToArchive [OptRecursive, OptPreserveSymbolicLinks] 
emptyArchive [testDir]
+  removeDirectoryRecursive testDir
+  let zipFile = tmpDir </> "testUnzip.zip"
+  BL.writeFile zipFile $ fromArchive archive
+  ec <- rawSystem "unzip" [zipFile]
+  assertBool "unzip succeeds" $ ec == ExitSuccess
+  let symlinkDir = testDir </> "link_to_directory"
+      symlinkFile = testDir </> "link_to_file"
+  isDirSymlink <- pathIsSymbolicLink symlinkDir
+  targetDirExists <- doesDirectoryExist symlinkDir
+  isFileSymlink <- pathIsSymbolicLink symlinkFile
+  targetFileExists <- doesFileExist symlinkFile
+  assertBool "Symbolic link to directory is preserved" isDirSymlink
+  assertBool "Target directory exists" targetDirExists
+  assertBool "Symbolic link to file is preserved" isFileSymlink
+  assertBool "Target file exists" targetFileExists
+  removeDirectoryRecursive tmpDir
+
 #endif
Binary files old/zip-archive-0.3.1.1/tests/zip_with_symlinks.zip and 
new/zip-archive-0.3.2.4/tests/zip_with_symlinks.zip differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zip-archive-0.3.1.1/zip-archive.cabal 
new/zip-archive-0.3.2.4/zip-archive.cabal
--- old/zip-archive-0.3.1.1/zip-archive.cabal   2017-06-19 09:47:36.000000000 
+0200
+++ new/zip-archive-0.3.2.4/zip-archive.cabal   2018-02-21 23:27:40.000000000 
+0100
@@ -1,23 +1,24 @@
 Name:                zip-archive
-Version:             0.3.1.1
+Version:             0.3.2.4
 Cabal-Version:       >= 1.10
-Build-type:          Simple
+Build-type:          Custom
 Synopsis:            Library for creating and modifying zip archives.
 Description:         The zip-archive library provides functions for creating, 
modifying,
                      and extracting files from zip archives.
 Category:            Codec
-Tested-with:         GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.2
+Tested-with:         GHC == 7.8.2, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2
 License:             BSD3
 License-file:        LICENSE
 Homepage:            http://github.com/jgm/zip-archive
 Author:              John MacFarlane
 Maintainer:          j...@berkeley.edu
-Extra-Source-Files:  changelog,
-                     README.markdown,
-                     tests/test4.zip,
-                     tests/test4/a.txt,
-                     tests/test4/b.bin,
+Extra-Source-Files:  changelog
+                     README.markdown
+                     tests/test4.zip
+                     tests/test4/a.txt
+                     tests/test4/b.bin
                      "tests/test4/c/with spaces.txt"
+                     tests/zip_with_symlinks.zip
 
 Source-repository    head
   type:              git
@@ -35,7 +36,7 @@
     Build-depends:   base >= 3 && < 5, pretty, containers
   else
     Build-depends:   base < 3
-  Build-depends:     binary >= 0.5, zlib, filepath, bytestring >= 0.10.0,
+  Build-depends:     binary >= 0.6, zlib, filepath, bytestring >= 0.10.0,
                      array, mtl, text >= 0.11, old-time, digest >= 0.0.0.1,
                      directory, time
   Exposed-modules:   Codec.Archive.Zip
@@ -46,6 +47,10 @@
     cpp-options:     -D_WINDOWS
   else
     Build-depends:   unix
+    Build-tools:     unzip
+
+custom-setup
+  setup-depends: base, Cabal
 
 Executable zip-archive
   if flag(executable)
@@ -65,8 +70,8 @@
   Main-Is:        test-zip-archive.hs
   Hs-Source-Dirs: tests
   Build-Depends:  base >= 4.2 && < 5,
-                  directory, bytestring >= 0.9.0, process, time, old-time,
-                  HUnit, zip-archive, temporary
+                  directory >= 1.3, bytestring >= 0.9.0, process, time, 
old-time, 
+                  HUnit, zip-archive, temporary, filepath
   Default-Language:  Haskell98
   Ghc-Options:    -Wall
   if os(windows)


Reply via email to