{-# Language TemplateHaskell, PatternGuards #-} 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 -- | The conditional variables that are used to resolve the conditionals inside of -- the cabal file. Holds the enable state of the cabal flags and the used OS and ARCH. data CondVars = CondVars { flags :: FlagMap -- ^ initialized with the default flag values which are accordingly -- modified by the explicitely given flag values by the user , os :: OS -- ^ the used OS, by default the one cabal was build on or given explicitely by the user , arch :: Arch -- ^ the used ARCH, by default the one cabal was build on or given explicitely by the user } deriving (Show) makeLensesFor [ ("flags", "flagsL") ] ''CondVars -- | Create a 'CondVars' from the default flags of the cabal package description. -- The 'os' and 'arch' fields are initialized by the ones the cabal library was build on. 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) -- | Enable the given flag in 'CondVars'. enableFlag :: FlagName -> CondVars -> CondVars enableFlag flag condVars = condVars & flagsL %~ (HM.insert flag True) -- | Disable the given flag in 'CondVars'. disableFlag :: FlagName -> CondVars -> CondVars disableFlag flag condVars = condVars & flagsL %~ (HM.insert flag False) -- | Evaluate the 'Condition' using the 'CondVars'. 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