@@ -7,6 +7,7 @@ module File
7 , writeUtf8
7 , writeUtf8
9 , writeBuilder
9 , writeBuilder
12 , removeDir
13 , removeDir
@@ -14,18 +15,22 @@ module File
18+import qualified Codec.Archive.Zip as Zip
17import Control.Exception (catch)
19import Control.Exception (catch)
18import qualified Data.Binary as Binary
20import qualified Data.Binary as Binary
19import qualified Data.ByteString as BS
21import qualified Data.ByteString as BS
20import qualified Data.ByteString.Internal as BS
22import qualified Data.ByteString.Internal as BS
21import qualified Data.ByteString.Builder as B
23import qualified Data.ByteString.Builder as B
24+import qualified Data.ByteString.Lazy as LBS
22import qualified Data.Fixed as Fixed
25import qualified Data.Fixed as Fixed
26+import qualified Data.List as List
23import qualified Data.Time.Clock.POSIX as Time
27import qualified Data.Time.Clock.POSIX as Time
24import qualified Foreign.ForeignPtr as FPtr
28import qualified Foreign.ForeignPtr as FPtr
25import GHC.IO.Exception (IOException, IOErrorType(InvalidArgument))
29import GHC.IO.Exception (IOException, IOErrorType(InvalidArgument))
26import qualified System.Directory as Dir
30import qualified System.Directory as Dir
27import qualified System.FileLock as Lock
31import qualified System.FileLock as Lock
28import qualified System.FilePath as FP
32import qualified System.FilePath as FP
33+import System.FilePath ((</>))
29import qualified System.IO as IO
34import qualified System.IO as IO
30import System.IO.Error (ioeGetErrorType, annotateIOError, modifyIOError)
35import System.IO.Error (ioeGetErrorType, annotateIOError, modifyIOError)
@@ -73,10 +78,15 @@ writeBinary path value =
74readBinary :: (Binary.Binary a) => FilePath -> IO (Maybe a)
79readBinary :: (Binary.Binary a) => FilePath -> IO (Maybe a)
75readBinary path =
80readBinary path =
81+ do pathExists <- Dir.doesFileExist path
76− do result <- Binary.decodeFileOrFail path
84+ do result <- Binary.decodeFileOrFail path
77− case result of
85+ case result of
78− Right a -> return (Just a)
86+ Right a -> return (Just a)
79− Left _ -> return Nothing
87+ Left e -> return Nothing
@@ -153,6 +163,34 @@ writeBuilder path builder =
169+writePackage :: FilePath -> Zip.Archive -> IO ()
170+writePackage destination archive =
171+ case Zip.zEntries archive of
176+ do let root = length (Zip.eRelativePath entry)
177+ mapM_ (writeEntry destination root) entries
180+writeEntry :: FilePath -> Int -> Zip.Entry -> IO ()
181+writeEntry destination root entry =
183+ path = drop root (Zip.eRelativePath entry)
185+ if List.isPrefixOf "src/" path then
186+ if not (null path) && last path == '/'
187+ then Dir.createDirectoryIfMissing True (destination </> path)
188+ else LBS.writeFile (destination </> path) (Zip.fromEntry entry)