cabal-buck2-0.1.0.0: src/Distribution/Client/Buck2/Unpack.hs
-- | Unpacking the source of packages that buck2 builds, without building
-- anything.
module Distribution.Client.Buck2.Unpack
( unpackInplaceSources
) where
import Distribution.Client.Compat.Prelude
import Prelude ()
import System.Directory (doesDirectoryExist, doesFileExist, renameDirectory)
import System.FilePath ((<.>), (</>))
import Distribution.Client.DistDirLayout (DistDirLayout (..))
import Distribution.Client.FetchUtils (fetchPackage)
import Distribution.Client.ProjectPlanning
( ElaboratedConfiguredPackage (..)
, ElaboratedSharedConfig
)
import Distribution.Client.ProjectPlanning.Types (elabDistDirParams)
import qualified Distribution.Client.Tar as Tar
import Distribution.Client.GlobalFlags (RepoContext)
import Distribution.Client.Types (PackageLocation (..))
import Distribution.Package (PackageId, packageId, packageName)
import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, die', info, writeFileAtomic)
import Distribution.Verbosity (Verbosity)
import qualified Data.ByteString.Lazy as LBS
-- | Fetch (if not already downloaded) and unpack the source of each given
-- package to where an inplace build of it would find it (under
-- 'distUnpackedSrcDirectory'). Packages whose source isn't a tarball (a
-- user-managed local directory, a source-repository checkout) need no
-- unpacking and are left alone.
unpackInplaceSources
:: Verbosity
-> DistDirLayout
-> ElaboratedSharedConfig
-> ((RepoContext -> IO ()) -> IO ())
-> [ElaboratedConfiguredPackage]
-> IO ()
unpackInplaceSources verbosity distDirLayout sharedConfig withRepoCtx pkgs =
unless (null pkgs) $
withRepoCtx $ \repoctx ->
for_ pkgs $ \pkg -> do
mtarball <- case elabPkgSourceLocation pkg of
LocalTarballPackage tarball -> return (Just tarball)
loc@RemoteTarballPackage{} -> fetched repoctx loc
loc@RepoTarballPackage{} -> fetched repoctx loc
_ -> return Nothing
for_ mtarball $ \tarball ->
unpackTarball
verbosity
distDirLayout
tarball
(packageId pkg)
(elabPkgDescriptionOverride pkg)
(distBuildDirectory distDirLayout (elabDistDirParams sharedConfig pkg))
where
fetched repoctx loc = do
loc' <- fetchPackage verbosity repoctx loc
return $ case loc' of
RemoteTarballPackage _ tarball -> Just tarball
RepoTarballPackage _ _ tarball -> Just tarball
_ -> Nothing
-- | Unpack a package's tarball to 'distUnpackedSrcDirectory', unless that's
-- already been done. If the index has a newer revision of the @.cabal@ file
-- than the tarball, that's the one used.
unpackTarball
:: Verbosity
-> DistDirLayout
-> FilePath
-> PackageId
-> Maybe LBS.ByteString
-> FilePath
-- ^ The package's build directory
-> IO ()
unpackTarball verbosity distDirLayout tarball pkgid cabalFileOverride buildDir = do
let srcdir = distUnpackedSrcDirectory distDirLayout pkgid
srcrootdir = distUnpackedSrcRootDirectory distDirLayout
exists <- doesDirectoryExist srcdir
unless exists $ do
createDirectoryIfMissingVerbose verbosity True srcrootdir
info verbosity $ "Extracting " ++ tarball ++ " to " ++ srcrootdir ++ "..."
Tar.extractTarGzFile srcrootdir (prettyShow pkgid) tarball
let cabalFile = srcdir </> prettyShow (packageName pkgid) <.> "cabal"
cabalFileExists <- doesFileExist cabalFile
unless cabalFileExists $
die' verbosity $
"The package description file " ++ cabalFile ++ " was not found in " ++ tarball
for_ cabalFileOverride $ \text -> do
info verbosity $ "Updating " ++ cabalFile ++ " with the latest revision from the index."
writeFileAtomic cabalFile text
-- Some packages ship pre-processed files in a @dist@ directory inside the
-- tarball: move it to where the build directory is.
let shippedDist = srcdir </> "dist"
shippedDistExists <- doesDirectoryExist shippedDist
when shippedDistExists $ renameDirectory shippedDist buildDir