packages feed

cassava-conduit-0.2.1: Setup.hs

#!/usr/bin/env runhaskell
{-# OPTIONS_GHC -Wall #-}
module Main (main) where

import Data.List ( nub )
import Data.Maybe ( catMaybes )
import Data.Version ( showVersion )
import Distribution.Package ( PackageName(PackageName), PackageId, InstalledPackageId, packageVersion, packageName )
import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )
import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )
import Distribution.Simple.Compiler ( PackageDB(..), PackageDBStack )
import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose, findProgramVersion, currentDir )
import Distribution.Simple.BuildPaths ( autogenModulesDir )
import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), fromFlag )
import Distribution.Simple.LocalBuildInfo ( withLibLBI, withPackageDB, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) )
import Distribution.Verbosity ( Verbosity )
import Distribution.Version ( Version )
import System.Directory ( getDirectoryContents )
import System.FilePath ( (</>) )

main :: IO ()
main = defaultMainWithHooks simpleUserHooks
    {   buildHook = \pkg lbi hooks flags -> do
            generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi
            buildHook simpleUserHooks pkg lbi hooks flags
    }

generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
generateBuildModule verbosity pkg lbi = do
    let dir = autogenModulesDir lbi
    createDirectoryIfMissingVerbose verbosity True dir
    withLibLBI pkg lbi $ \_ libcfg ->
        withTestLBI pkg lbi $ \suite suitecfg -> do
            ghcOpts <-
                    generateCabalDevOpts
                <$> isCabalDevPresent
                <*> getGhcVersion verbosity
            rewriteFile (dir </> "Build_" ++ testName suite ++ ".hs") $ unlines
                [   "module Build_" ++ testName suite ++ " where"
                ,   "deps :: [String]"
                ,   "deps = " ++ show (formatdeps (testDeps libcfg suitecfg))
                ,   "opts :: [String]"
                ,   "opts = " ++ show ghcOpts
                ,   "specificPackageDBs :: [FilePath]"
                ,   "specificPackageDBs = " ++ show (getSpecificDBs (withPackageDB lbi))
                ]
    where
        formatdeps = map (formatone . snd)
        formatone p = case packageName p of
            PackageName n -> n ++ "-" ++ showVersion (packageVersion p)

getFilePath :: PackageDB -> Maybe FilePath
getFilePath GlobalPackageDB         = Nothing
getFilePath UserPackageDB           = Nothing
getFilePath (SpecificPackageDB fp)  = Just fp

getSpecificDBs :: PackageDBStack -> [FilePath]
getSpecificDBs = catMaybes . fmap getFilePath


isCabalDevPresent :: IO Bool
isCabalDevPresent = do
    contents <- getDirectoryContents currentDir
    return $ "cabal-dev" `elem` contents

getGhcVersion :: Verbosity -> IO (Maybe Version)
getGhcVersion verb = findProgramVersion
    "--version"
    (last . words)
    verb
    "ghc"

generateCabalDevOpts :: Bool -> Maybe Version -> [String]
generateCabalDevOpts isCabalDev version =
    case version of
        Nothing -> []
        Just version' ->
            let
                baseOpts =  [   "-Lcabal-dev/lib"
                            ,   "-package-conf=cabal-dev/packages-" ++ showVersion version' ++ ".conf"
                            ]
            in
                if isCabalDev then baseOpts else []

testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]
testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys