foliage/app/Foliage/PreparePackageVersion.hs
Andrea Bedini 9a4d097cde Rework internals and add consistency check
The function preparePackageVersion is now responsible for doing
everything we need to do to be able to include the package in the index.

The function also returns a denormalised view of the package information
which can be taken as a proof that everything is consistent.
2023-03-03 08:15:19 +08:00

85 lines
2.8 KiB
Haskell

{-# LANGUAGE PatternSynonyms #-}
module Foliage.PreparePackageVersion
( PreparedPackageVersion
( pkgId,
pkgTimestamp,
pkgVersionSource,
pkgVersionForce,
sdistPath,
cabalFilePath,
originalCabalFilePath,
cabalFileRevisions
),
pattern PreparedPackageVersion,
preparePackageVersion,
)
where
import Control.Monad (unless)
import Data.List (sortOn)
import Data.Ord (Down (Down))
import Development.Shake (Action)
import Distribution.Client.Compat.Prelude (prettyShow)
import Distribution.Types.PackageId
import Foliage.Meta (PackageVersionSource, PackageVersionSpec (..), RevisionSpec (..), UTCTime, latestRevisionNumber)
import Foliage.PrepareSdist (prepareSdist)
import Foliage.PrepareSource (prepareSource)
import System.FilePath (takeBaseName, takeFileName, (<.>), (</>))
data PreparedPackageVersion = PreparedPackageVersion
{ pkgId :: PackageId,
pkgTimestamp :: Maybe UTCTime,
pkgVersionSource :: PackageVersionSource,
pkgVersionForce :: Bool,
sdistPath :: FilePath,
cabalFilePath :: FilePath,
originalCabalFilePath :: FilePath,
cabalFileRevisions :: [(UTCTime, FilePath)]
}
preparePackageVersion :: FilePath -> PackageId -> PackageVersionSpec -> Action PreparedPackageVersion
preparePackageVersion inputDir pkgId pkgSpec = do
srcDir <- prepareSource pkgId pkgSpec
let PackageIdentifier pkgName pkgVersion = pkgId
originalCabalFilePath = srcDir </> prettyShow pkgName <.> "cabal"
cabalFileRevisionPath revisionNumber = inputDir </> prettyShow pkgName </> prettyShow pkgVersion </> "revisions" </> show revisionNumber <.> "cabal"
let cabalFilePath =
maybe
originalCabalFilePath
cabalFileRevisionPath
(latestRevisionNumber pkgSpec)
sdistPath <- prepareSdist srcDir
let expectedSdistName = prettyShow pkgId <.> "tar.gz"
unless (takeFileName sdistPath == expectedSdistName) $
fail $
unlines
[ "creating a source distribution for " ++ prettyShow pkgId ++ " has failed because",
"cabal has produced a source distribtion that does not match the expected file name:",
"actual: " ++ takeBaseName sdistPath,
"expected: " ++ expectedSdistName
]
let cabalFileRevisions =
sortOn
(Down . fst)
[ (revisionTimestamp, cabalFileRevisionPath revisionNumber)
| RevisionSpec {revisionTimestamp, revisionNumber} <- packageVersionRevisions pkgSpec
]
return
PreparedPackageVersion
{ pkgId,
pkgTimestamp = packageVersionTimestamp pkgSpec,
pkgVersionSource = packageVersionSource pkgSpec,
pkgVersionForce = packageVersionForce pkgSpec,
sdistPath,
cabalFilePath,
originalCabalFilePath,
cabalFileRevisions
}