Commit 8fe7607f authored by Alexis Williams's avatar Alexis Williams
Browse files

Add zip sdist support

parent e1c7b4d0
......@@ -54,17 +54,20 @@ import Distribution.Verbosity
import qualified Codec.Archive.Tar as Tar
import qualified Codec.Archive.Tar.Entry as Tar
import qualified Codec.Archive.Zip as Zip
import qualified Codec.Compression.GZip as GZip
import Control.Exception
( throwIO )
import Control.Monad
( when, forM_ )
( when, forM, forM_ )
import Control.Monad.IO.Class
( liftIO )
import Control.Monad.State.Lazy
( StateT, modify, gets, evalStateT )
import Control.Monad.Writer.Lazy
( WriterT, tell, execWriterT )
import Data.Bits
( shiftL )
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.Either
( partitionEithers )
......@@ -175,6 +178,9 @@ sdistAction SdistFlags{..} targetStrings globalFlags = do
Left errs -> die' verbosity . unlines . fmap renderTargetProblem $ errs
Right pkgs -> mapM_ (\pkg -> packageToSdist verbosity listSources archiveFormat (outputPath pkg) pkg) pkgs
data IsExec = Exec | NoExec
deriving (Show, Eq)
packageToSdist :: Verbosity -> Bool -> ArchiveFormat -> FilePath -> UnresolvedSourcePackage -> IO ()
packageToSdist verbosity listSources archiveFormat outputFile pkg = do
dir <- case packageSource pkg of
......@@ -182,7 +188,8 @@ packageToSdist verbosity listSources archiveFormat outputFile pkg = do
_ -> die' verbosity "The impossible happened: a local package isn't local"
setCurrentDirectory dir
(fmap ((Tar.ordinaryFilePermissions, ) . normalise) -> nonexec, fmap ((Tar.executableFilePermissions, ) . normalise) -> exec) <-
let norm flag = fmap ((flag, ) . normalise)
(norm NoExec -> nonexec, norm Exec -> exec) <-
listPackageSources verbosity (flattenPackageDescription $ packageDescription pkg) knownSuffixHandlers
let write = if outputFile == "-" then BSL.putStrLn else BSL.writeFile outputFile
......@@ -196,6 +203,9 @@ packageToSdist verbosity listSources archiveFormat outputFile pkg = do
let entriesM :: StateT [FilePath] (WriterT [Tar.Entry] IO) ()
entriesM = forM_ files $ \(perm, file) -> do
let fileDir = takeDirectory file
perm' = case perm of
Exec -> Tar.executableFilePermissions
NoExec -> Tar.ordinaryFilePermissions
needsEntry <- gets (notElem fileDir)
when needsEntry $ do
......@@ -207,13 +217,23 @@ packageToSdist verbosity listSources archiveFormat outputFile pkg = do
contents <- liftIO $ BSL.readFile file
case Tar.toTarPath False file of
Left err -> liftIO $ die' verbosity ("Error packing sdist: " ++ err)
Right path -> tell [(Tar.fileEntry path contents) { Tar.entryPermissions = perm }]
Right path -> tell [(Tar.fileEntry path contents) { Tar.entryPermissions = perm' }]
entries <- execWriterT (evalStateT entriesM [])
write . GZip.compress . Tar.write $ entries
notice verbosity $ "Wrote tarball sdist to " ++ outputFile ++ "\n"
| archiveFormat == ZipFormat ->
die' verbosity "'.zip' sdists are not yet supported."
| archiveFormat == ZipFormat -> do
entries <- forM files $ \(perm, file) -> do
let perm' = case perm of
-- -rwxr-xr-x
Exec -> 0o010755 `shiftL` 16
-- -rw-r--r--
NoExec -> 0o010644 `shiftL` 16
contents <- BSL.readFile file
return $ (Zip.toEntry file 0 contents) { Zip.eExternalFileAttributes = perm' }
let archive = foldr Zip.addEntryToArchive Zip.emptyArchive entries
write (Zip.fromArchive archive)
notice verbosity $ "Wrote zip sdist to " ++ outputFile ++ "\n"
--
......
......@@ -261,6 +261,15 @@ HACKAGE_SECURITY_VER="0.5.3.0"; HACKAGE_SECURITY_VER_REGEXP="0\.5\.((2\.[2-9]|[3
# >= 0.5.2 && < 0.6
TAR_VER="0.5.1.0"; TAR_VER_REGEXP="0\.5\.([1-9]|1[0-9]|0\.[3-9]|0\.1[0-9])\.?"
# >= 0.5.0.3 && < 0.6
# These two are temporary: https://github.com/jgm/zip-archive/pull/47
OLD_LOCALE_VER="1.0.0.7"; OLD_LOCALE_REGEXP="1\.0\.?\.?"
# >= 1.0.0.0 && < 1.1.0.0
OLD_TIME_VER="1.1.0.3"; OLD_TIME_REGEXP="1\.1\.(0\.[3-9]|[1-9]\.?)"
# >= 1.1.0.3 && < 1.2
DIGEST_VER="0.0.1.2"; DIGEST_REGEXP="0\.0\.(1\.[2-9]|[2-9]\.?)"
# >= 0.0.1.2 && < 0.1
ZIP_ARCHIVE_VER="0.3.2.5"; ZIP_ARCHIVE_REGEXP="0\.3\.(2\.[5-9]|[3-9]\.?)"
# >= 0.3.2.5 && < 0.4
HACKAGE_URL="https://hackage.haskell.org/package"
......@@ -452,6 +461,10 @@ info_pkg "echo" ${ECHO_VER} ${ECHO_VER_REGEXP}
info_pkg "edit-distance" ${EDIT_DISTANCE_VER} ${EDIT_DISTANCE_VER_REGEXP}
info_pkg "ed25519" ${ED25519_VER} ${ED25519_VER_REGEXP}
info_pkg "tar" ${TAR_VER} ${TAR_VER_REGEXP}
info_pkg "old-locale" ${OLD_LOCALE_VER} ${OLD_LOCALE_REGEXP}
info_pkg "old-time" ${OLD_TIME_VER} ${OLD_TIME_REGEXP}
info_pkg "digest" ${DIGEST_VER} ${DIGEST_REGEXP}
info_pkg "zip-archive" ${ZIP_ARCHIVE_VER} ${ZIP_ARCHIVE_REGEXP}
info_pkg "hackage-security" ${HACKAGE_SECURITY_VER} \
${HACKAGE_SECURITY_VER_REGEXP}
......@@ -488,6 +501,10 @@ do_pkg "echo" ${ECHO_VER} ${ECHO_VER_REGEXP}
do_pkg "edit-distance" ${EDIT_DISTANCE_VER} ${EDIT_DISTANCE_VER_REGEXP}
do_pkg "ed25519" ${ED25519_VER} ${ED25519_VER_REGEXP}
do_pkg "tar" ${TAR_VER} ${TAR_VER_REGEXP}
do_pkg "old-locale" ${OLD_LOCALE_VER} ${OLD_LOCALE_REGEXP}
do_pkg "old-time" ${OLD_TIME_VER} ${OLD_TIME_REGEXP}
do_pkg "digest" ${DIGEST_VER} ${DIGEST_REGEXP}
do_pkg "zip-archive" ${ZIP_ARCHIVE_VER} ${ZIP_ARCHIVE_REGEXP}
do_pkg "hackage-security" ${HACKAGE_SECURITY_VER} \
${HACKAGE_SECURITY_VER_REGEXP}
......
......@@ -319,7 +319,8 @@ library
time >= 1.4 && < 1.10,
zlib >= 0.5.3 && < 0.7,
hackage-security >= 0.5.2.2 && < 0.6,
text >= 1.2.3 && < 1.3
text >= 1.2.3 && < 1.3,
zip-archive >= 0.3.2.5 && < 0.4
if flag(native-dns)
if os(windows)
......@@ -397,7 +398,8 @@ executable cabal
time >= 1.4 && < 1.10,
zlib >= 0.5.3 && < 0.7,
hackage-security >= 0.5.2.2 && < 0.6,
text >= 1.2.3 && < 1.3
text >= 1.2.3 && < 1.3,
zip-archive >= 0.3.2.5 && < 0.4
other-modules:
Distribution.Client.BuildReports.Anonymous
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment