@@ -7,6 +7,7 @@ module File
77 , writeUtf8
88 , readUtf8
99 , writeBuilder
10+ , writePackage
1011 , exists
1112 , remove
1213 , removeDir
@@ -14,18 +15,22 @@ module File
1415 where
1516
1617
18+import qualified Codec.Archive.Zip as Zip
1719import Control.Exception (catch)
1820import qualified Data.Binary as Binary
1921import qualified Data.ByteString as BS
2022import qualified Data.ByteString.Internal as BS
2123import qualified Data.ByteString.Builder as B
24+import qualified Data.ByteString.Lazy as LBS
2225import qualified Data.Fixed as Fixed
26+import qualified Data.List as List
2327import qualified Data.Time.Clock.POSIX as Time
2428import qualified Foreign.ForeignPtr as FPtr
2529import GHC.IO.Exception (IOException, IOErrorType(InvalidArgument))
2630import qualified System.Directory as Dir
2731import qualified System.FileLock as Lock
2832import qualified System.FilePath as FP
33+import System.FilePath ((</>))
2934import qualified System.IO as IO
3035import System.IO.Error (ioeGetErrorType, annotateIOError, modifyIOError)
3136
@@ -73,10 +78,15 @@ writeBinary path value =
7378
7479readBinary :: (Binary.Binary a) => FilePath -> IO (Maybe a)
7580readBinary path =
76− do result <- Binary.decodeFileOrFail path
77− case result of
78− Right a -> return (Just a)
79− Left _ -> return Nothing
81+ do pathExists <- Dir.doesFileExist path
82+ if pathExists
83+ then
84+ do result <- Binary.decodeFileOrFail path
85+ case result of
86+ Right a -> return (Just a)
87+ Left e -> return Nothing
88+ else
89+ return Nothing
8090
8191
8292
@@ -153,6 +163,34 @@ writeBuilder path builder =
153163
154164
155165
166+-- WRITE PACKAGE
167+
168+
169+writePackage :: FilePath -> Zip.Archive -> IO ()
170+writePackage destination archive =
171+ case Zip.zEntries archive of
172+ [] ->
173+ return ()
174+
175+ entry:entries ->
176+ do let root = length (Zip.eRelativePath entry)
177+ mapM_ (writeEntry destination root) entries
178+
179+
180+writeEntry :: FilePath -> Int -> Zip.Entry -> IO ()
181+writeEntry destination root entry =
182+ let
183+ path = drop root (Zip.eRelativePath entry)
184+ in
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)
189+ else
190+ return ()
191+
192+
193+
156194-- EXISTS
157195
158196