stackage2nix-0.7.2: src/Distribution/Nixpkgs/Haskell/FromStack.hs
module Distribution.Nixpkgs.Haskell.FromStack where
import AllCabalHashes
import Control.Lens
import Data.Set.Lens
import Distribution.Compiler (CompilerInfo(..))
import Distribution.System (Platform(..))
import Distribution.Package (PackageName, PackageIdentifier(..), Dependency(..))
import Distribution.PackageDescription
import Distribution.Nixpkgs.Haskell.FromStack.Package
import Distribution.Nixpkgs.Haskell.PackageSourceSpec
import Distribution.Nixpkgs.Haskell.FromCabal
import Distribution.Nixpkgs.Haskell.Derivation
import Stackage.BuildPlan
import Stackage.Types (CabalFileInfo(..),PackageConstraints(..), DepInfo(..), SimpleDesc(..), TestState(..))
import qualified Distribution.Nixpkgs.Meta as Nix
import qualified Data.Map as Map
import qualified Data.Set as Set
data PackageSetConfig = PackageSetConfig
{ haskellResolver :: HaskellResolver
, nixpkgsResolver :: NixpkgsResolver
, packageLoader :: Maybe SHA1Hash -> PackageIdentifier -> IO Package
, targetPlatform :: Platform
, targetCompiler :: CompilerInfo }
data PackageConfig = PackageConfig
{ enableCheck :: Bool
, enableHaddock :: Bool }
removeTests :: GenericPackageDescription -> GenericPackageDescription
removeTests gd = gd { condTestSuites = [] }
removeBenches :: GenericPackageDescription -> GenericPackageDescription
removeBenches gd = gd { condBenchmarks = [] }
planDependencies :: PackagePlan -> [Dependency]
planDependencies = map makeDependency . Map.toList . sdPackages . ppDesc
where
makeDependency (name, depInfo) = Dependency name (diRange depInfo)
buildNode :: PackageSetConfig -> PackageConfig -> PackageName -> PackagePlan -> IO Node
buildNode conf pconf name plan = do
let
cabalHashes = maybe mempty cfiHashes $ ppCabalFileInfo plan
mGitSha1 = Map.lookup "GitSHA1" cabalHashes
pkg <- packageLoader conf mGitSha1 $ PackageIdentifier name (ppVersion plan)
pure . mkNode $ fromPackage conf pconf plan pkg
fromPackage :: PackageSetConfig -> PackageConfig -> PackagePlan -> Package -> Derivation
fromPackage conf pconf plan pkg =
let
constraints = ppConstraints plan
testsEnabled =
pcTests constraints == ExpectSuccess
haddocksEnabled =
pcHaddocks constraints == ExpectSuccess &&
not (Set.null (sdModules (ppDesc plan)))
configureTests
| pcTests constraints == Don'tBuild = removeTests
| otherwise = id
configureBenches
| pcBenches constraints == Don'tBuild = removeBenches
| otherwise = id
flags = Map.toList (pcFlagOverrides constraints)
(descr, missingDeps) = finalizeGenericPackageDescription
(haskellResolver conf)
(targetPlatform conf)
(targetCompiler conf)
(mkFlagAssignment flags)
(planDependencies plan)
(configureBenches . configureTests $ pkgCabal pkg)
genericDrv = fromPackageDescription
(haskellResolver conf)
(nixpkgsResolver conf)
missingDeps
(mkFlagAssignment flags)
descr
depName (Dependency name _) = name
testDeps = setOf
( to testSuites . folded
. to testBuildInfo . to targetBuildDepends
. folded . to depName )
hasIntersection a b = not . null $ Set.intersection a b
brokenEnabled =
testsEnabled &&
not (null missingDeps) &&
setOf (folded . to depName) missingDeps `hasIntersection` testDeps descr
in finalizePackage pkg pconf
$ genericDrv
& doCheck .~ testsEnabled
& runHaddock .~ haddocksEnabled
& metaSection . Nix.broken .~ brokenEnabled
finalizePackage :: Package -> PackageConfig -> Derivation -> Derivation
finalizePackage pkg pconf drv = drv
& src .~ pkgSource pkg
& doCheck &&~ enableCheck pconf
& testDepends %~ (if enableCheck pconf then id else const mempty)
& runHaddock &&~ enableHaddock pconf