196 lines
6.2 KiB
Haskell
196 lines
6.2 KiB
Haskell
{-# LANGUAGE TemplateHaskell, RecordWildCards, StandaloneDeriving #-}
|
|
module SetupCompat where
|
|
|
|
import Control.Arrow
|
|
import Control.Monad.Trans.State
|
|
import Data.List
|
|
import Data.Maybe
|
|
import Data.Functor
|
|
import Data.Function
|
|
import Distribution.Simple.LocalBuildInfo
|
|
import Distribution.PackageDescription
|
|
|
|
import Distribution.Simple
|
|
import Distribution.Simple.Setup
|
|
import Distribution.Simple.Install
|
|
|
|
import qualified Data.Map as M
|
|
import Data.Map (Map)
|
|
|
|
|
|
import NotCPP.Declarations
|
|
import Language.Haskell.TH
|
|
|
|
-- $(ifdefD "componentsConfigs" [d| deriving instance (Ord ComponentName) |] )
|
|
|
|
$(ifD [d|
|
|
|
|
showComponentName :: ComponentName -> String
|
|
showComponentName CLibName = "library"
|
|
showComponentName (CExeName name) = "executable '" ++ name ++ "'"
|
|
showComponentName (CTestName name) = "test suite '" ++ name ++ "'"
|
|
showComponentName (CBenchName name) = "benchmark '" ++ name ++ "'"
|
|
|
|
|])
|
|
|
|
$(ifelsedefD "componentsConfigs" [d|
|
|
|
|
setComponentsConfigs
|
|
:: LocalBuildInfo
|
|
-> [(ComponentName, ComponentLocalBuildInfo, [ComponentName])]
|
|
-> LocalBuildInfo
|
|
setComponentsConfigs lbi cs = $(recUpdE' (nE "lbi") (mkName "componentsConfigs") (VarE $ mkName "cs"))
|
|
|
|
|] [d|
|
|
|
|
setComponentsConfigs
|
|
:: LocalBuildInfo
|
|
-> [(ComponentName, ComponentLocalBuildInfo, a)]
|
|
-> LocalBuildInfo
|
|
setComponentsConfigs lbi cs = flip execState lbi $ mapM setClbis gcs
|
|
where
|
|
gcs = groupBy (sameKind `on` fst3) $ sortBy (compare `on` showComponentName . fst3) cs
|
|
|
|
fst3 (x,_,_) = x
|
|
|
|
sameKind CLibName CLibName = True
|
|
sameKind (CExeName _) (CExeName _) = True
|
|
sameKind (CTestName _) (CTestName _) = True
|
|
sameKind (CBenchName _) (CBenchName _) = True
|
|
sameKind _ _ = False
|
|
|
|
setClbis [(CLibName, clbi, _)] =
|
|
get >>= \lbi ->
|
|
put $ $(recUpdE' (nE "lbi") (mkName "libraryConfig") (AppE (ConE (mkName "Just")) (VarE (mkName "clbi"))))
|
|
|
|
setClbis cs@((CExeName _, _, _):_) =
|
|
let cfg = (\((CExeName n), clbi, _) -> (n, clbi)) <$> cs in
|
|
get >>= \lbi ->
|
|
put $ $(recUpdE' (nE "lbi") (mkName "executableConfigs") (VarE $ mkName "cfg"))
|
|
|
|
setClbis cs@((CTestName _, _, _):_) =
|
|
let cfg = (\((CTestName n), clbi, _) -> (n, clbi)) <$> cs in
|
|
get >>= \lbi ->
|
|
put $ $(recUpdE' (nE "lbi") (mkName "testSuiteConfigs") (VarE $ mkName "cfg"))
|
|
|
|
setClbis cs@((CBenchName _, _, _):_) =
|
|
let cfg = (\((CBenchName n), clbi, _) -> (n, clbi)) <$> cs in
|
|
get >>= \lbi ->
|
|
put $ $(recUpdE' (nE "lbi") (mkName "benchmarkConfigs") (VarE $ mkName "cfg"))
|
|
|
|
|])
|
|
|
|
|
|
$(ifD [d|
|
|
|
|
componentsConfigs ::
|
|
LocalBuildInfo -> [(ComponentName, ComponentLocalBuildInfo, [ComponentName])]
|
|
componentsConfigs LocalBuildInfo {..} =
|
|
(maybe [] (\c -> [(CLibName, c, [])]) $(nE "libraryConfig"))
|
|
++ ((\(n, clbi) -> (CExeName n, clbi, [])) <$> $(nE "executableConfigs"))
|
|
++ ((\(n, clbi) -> (CTestName n, clbi, [])) <$> $(nE "testSuiteConfigs"))
|
|
++ ((\(n, clbi) -> (CBenchName n, clbi, [])) <$> $(nE "benchmarkConfigs"))
|
|
|
|
getComponent :: PackageDescription -> ComponentName -> Component
|
|
getComponent pkg cname =
|
|
case lookupComponent pkg cname of
|
|
Just cpnt -> cpnt
|
|
Nothing -> missingComponent
|
|
where
|
|
missingComponent =
|
|
error $ "internal error: the package description contains no "
|
|
++ "component corresponding to " ++ show cname
|
|
|
|
lookupComponent :: PackageDescription -> ComponentName -> Maybe Component
|
|
lookupComponent pkg CLibName =
|
|
fmap CLib $ library pkg
|
|
lookupComponent pkg (CExeName name) =
|
|
fmap CExe $ find ((name ==) . exeName) (executables pkg)
|
|
lookupComponent pkg (CTestName name) =
|
|
fmap CTest $ find ((name ==) . testName) (testSuites pkg)
|
|
lookupComponent pkg (CBenchName name) =
|
|
fmap CBench $ find ((name ==) . benchmarkName) (benchmarks pkg)
|
|
|
|
-- We're lying here can't be bothered to order these
|
|
allComponentsInBuildOrder :: LocalBuildInfo
|
|
-> [(ComponentName, ComponentLocalBuildInfo)]
|
|
allComponentsInBuildOrder lbi =
|
|
[ (cname, clbi) | (cname, clbi, _) <- componentsConfigs lbi ]
|
|
|
|
getComponentLocalBuildInfo :: LocalBuildInfo -> ComponentName -> ComponentLocalBuildInfo
|
|
getComponentLocalBuildInfo lbi cname =
|
|
case [ clbi
|
|
| (cname', clbi, _) <- componentsConfigs lbi
|
|
, cname == cname' ] of
|
|
[clbi] -> clbi
|
|
_ -> missingComponent
|
|
where
|
|
missingComponent =
|
|
error $ "internal error: there is no configuration data "
|
|
++ "for component " ++ show cname
|
|
|
|
componentBuildInfo :: Component -> BuildInfo
|
|
componentBuildInfo =
|
|
foldComponent libBuildInfo buildInfo testBuildInfo benchmarkBuildInfo
|
|
|
|
|])
|
|
|
|
|
|
$(ifelsedefD "componentPackageRenaming" [d|
|
|
-- M.Map PackageName
|
|
newtype Deps = Deps { unDeps :: ([(InstalledPackageId, PackageId)], Map PackageName $(cT "ModuleRenaming")) }
|
|
-- $(return $ TySynD $(mkName "Deps") [] [t| |] )
|
|
|
|
noDeps = Deps ([], M.empty)
|
|
|
|
getDeps :: ComponentLocalBuildInfo -> Deps
|
|
getDeps = componentPackageDeps &&& $(nE "componentPackageRenaming") >>> Deps
|
|
|
|
setUnionDeps :: Deps -> ComponentLocalBuildInfo -> ComponentLocalBuildInfo
|
|
setUnionDeps (Deps (deps, rns)) clbi = let
|
|
clbi' = setComponentPackageRenaming clbi rns
|
|
cpdeps = componentPackageDeps clbi
|
|
in
|
|
clbi' {
|
|
componentPackageDeps = cpdeps `union` deps
|
|
}
|
|
|
|
setComponentPackageRenaming clbi cprn =
|
|
-- [| clbi { componentPackageRenaming = componentPackageRenaming clbi `M.union` cprn } |]
|
|
$(recUpdE'
|
|
(nE "clbi")
|
|
(mkName "componentPackageRenaming")
|
|
(InfixE
|
|
(Just
|
|
(AppE
|
|
(VarE
|
|
(mkName "componentPackageRenaming"))
|
|
(VarE (mkName "clbi"))
|
|
))
|
|
(VarE (mkName "M.union"))
|
|
(Just (VarE (mkName "cprn")))
|
|
)
|
|
)
|
|
|
|
|] [d|
|
|
|
|
newtype Deps = Deps { unDeps :: [(InstalledPackageId, PackageId)] }
|
|
|
|
noDeps = Deps []
|
|
|
|
getDeps :: ComponentLocalBuildInfo -> Deps
|
|
getDeps lbi = Deps $ componentPackageDeps lbi
|
|
|
|
setUnionDeps :: Deps -> ComponentLocalBuildInfo -> ComponentLocalBuildInfo
|
|
setUnionDeps (Deps deps) clbi = let
|
|
cpdeps = componentPackageDeps clbi
|
|
in
|
|
clbi {
|
|
componentPackageDeps = cpdeps `union` deps
|
|
}
|
|
|
|
|
|
-- setComponentPackageRenaming clbi _cprn = clbi
|
|
|
|
|])
|