module CabalCargs.CondVars
( CondVars(..)
, fromDefaults
, enableFlag
, disableFlag
, eval
) where
import qualified Distribution.PackageDescription as PD
import Distribution.PackageDescription (Condition(..))
import qualified Distribution.System as S
import Distribution.System (OS(..), Arch(..))
import qualified Data.HashMap.Strict as HM
import Control.Lens
type FlagName = String
type FlagMap = HM.HashMap FlagName Bool
data CondVars = CondVars
{ flags :: FlagMap
, os :: OS
, arch :: Arch
} deriving (Show)
makeLensesFor [ ("flags", "flagsL")
] ''CondVars
fromDefaults :: PD.GenericPackageDescription -> CondVars
fromDefaults pkgDescrp = CondVars { flags = flags, os = S.buildOS, arch = S.buildArch }
where
flags = HM.fromList $ map nameWithDflt (PD.genPackageFlags pkgDescrp)
nameWithDflt PD.MkFlag { PD.flagName = PD.FlagName name, PD.flagDefault = dflt } =
(name, dflt)
enableFlag :: FlagName -> CondVars -> CondVars
enableFlag flag condVars =
condVars & flagsL %~ (HM.insert flag True)
disableFlag :: FlagName -> CondVars -> CondVars
disableFlag flag condVars =
condVars & flagsL %~ (HM.insert flag False)
eval :: CondVars -> (Condition PD.ConfVar) -> Bool
eval condVars cond = eval' cond
where
eval' (Var var) = hasVar var
eval' (Lit val) = val
eval' (CNot c) = not $ eval' c
eval' (COr c1 c2) = eval' c1 || eval' c2
eval' (CAnd c1 c2) = eval' c1 && eval' c2
hasVar (PD.OS osVar) = osVar == os condVars
hasVar (PD.Arch archVar) = archVar == arch condVars
hasVar (PD.Impl _ _ ) = True
hasVar (PD.Flag (PD.FlagName name))
| Just v <- HM.lookup name (flags condVars)
= v
| otherwise
= False