{-# LANGUAGE FlexibleInstances, RecordWildCards, OverloadedStrings #-} -- | Configuration options for building. module Stack.Types.Config.Build ( BuildOpts(..) , BuildCommand(..) , defaultBuildOpts , defaultBuildOptsCLI , BuildOptsCLI(..) , BuildOptsMonoid(..) , TestOpts(..) , defaultTestOpts , TestOptsMonoid(..) , BenchmarkOpts(..) , defaultBenchmarkOpts , BenchmarkOptsMonoid(..) , FileWatchOpts(..) , BuildSubset(..) ) where import Data.Aeson.Extended import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import Data.Monoid import Data.Text (Text) import Stack.Types.FlagName import Stack.Types.PackageName import Control.Applicative -- | Build options that is interpreted by the build command. -- This is built up from BuildOptsCLI and BuildOptsMonoid data BuildOpts = BuildOpts {boptsLibProfile :: !Bool ,boptsExeProfile :: !Bool ,boptsHaddock :: !Bool -- ^ Build haddocks? ,boptsOpenHaddocks :: !Bool -- ^ Open haddocks in the browser? ,boptsHaddockDeps :: !(Maybe Bool) -- ^ Build haddocks for dependencies? ,boptsInstallExes :: !Bool -- ^ Install executables to user path after building? ,boptsPreFetch :: !Bool -- ^ Fetch all packages immediately -- ^ Watch files for changes and automatically rebuild ,boptsKeepGoing :: !(Maybe Bool) -- ^ Keep building/running after failure ,boptsForceDirty :: !Bool -- ^ Force treating all local packages as having dirty files ,boptsTests :: !Bool -- ^ Turn on tests for local targets ,boptsTestOpts :: !TestOpts -- ^ Additional test arguments ,boptsBenchmarks :: !Bool -- ^ Turn on benchmarks for local targets ,boptsBenchmarkOpts :: !BenchmarkOpts -- ^ Additional test arguments -- ^ Commands (with arguments) to run after a successful build -- ^ Only perform the configure step when building ,boptsReconfigure :: !Bool -- ^ Perform the configure step even if already configured ,boptsCabalVerbose :: !Bool -- ^ Ask Cabal to be verbose in its builds ,boptsSplitObjs :: !Bool -- ^ Whether to enable split-objs. } deriving (Show) defaultBuildOpts :: BuildOpts defaultBuildOpts = BuildOpts { boptsLibProfile = False , boptsExeProfile = False , boptsHaddock = False , boptsOpenHaddocks = False , boptsHaddockDeps = Nothing , boptsInstallExes = False , boptsPreFetch = False , boptsKeepGoing = Nothing , boptsForceDirty = False , boptsTests = False , boptsTestOpts = defaultTestOpts , boptsBenchmarks = False , boptsBenchmarkOpts = defaultBenchmarkOpts , boptsReconfigure = False , boptsCabalVerbose = False , boptsSplitObjs = False } defaultBuildOptsCLI ::BuildOptsCLI defaultBuildOptsCLI = BuildOptsCLI { boptsCLITargets = [] , boptsCLIDryrun = False , boptsCLIFlags = Map.empty , boptsCLIGhcOptions = [] , boptsCLIBuildSubset = BSAll , boptsCLIFileWatch = NoFileWatch , boptsCLIExec = [] , boptsCLIOnlyConfigure = False , boptsCLICommand = Build } -- | Build options that may only be specified from the CLI data BuildOptsCLI = BuildOptsCLI { boptsCLITargets :: ![Text] , boptsCLIDryrun :: !Bool , boptsCLIGhcOptions :: ![Text] , boptsCLIFlags :: !(Map (Maybe PackageName) (Map FlagName Bool)) , boptsCLIBuildSubset :: !BuildSubset , boptsCLIFileWatch :: !FileWatchOpts , boptsCLIExec :: ![(String, [String])] , boptsCLIOnlyConfigure :: !Bool , boptsCLICommand :: !BuildCommand } deriving Show -- | Command sum type for conditional arguments. data BuildCommand = Build | Test | Haddock | Bench | Install deriving (Eq, Show) -- | Build options that may be specified in the stack.yaml or from the CLI data BuildOptsMonoid = BuildOptsMonoid { buildMonoidLibProfile :: !(Maybe Bool) , buildMonoidExeProfile :: !(Maybe Bool) , buildMonoidHaddock :: !(Maybe Bool) , buildMonoidOpenHaddocks :: !(Maybe Bool) , buildMonoidHaddockDeps :: !(Maybe Bool) , buildMonoidInstallExes :: !(Maybe Bool) , buildMonoidPreFetch :: !(Maybe Bool) , buildMonoidKeepGoing :: !(Maybe Bool) , buildMonoidForceDirty :: !(Maybe Bool) , buildMonoidTests :: !(Maybe Bool) , buildMonoidTestOpts :: !TestOptsMonoid , buildMonoidBenchmarks :: !(Maybe Bool) , buildMonoidBenchmarkOpts :: !BenchmarkOptsMonoid , buildMonoidReconfigure :: !(Maybe Bool) , buildMonoidCabalVerbose :: !(Maybe Bool) , buildMonoidSplitObjs :: !(Maybe Bool) } deriving (Show) instance FromJSON (WithJSONWarnings BuildOptsMonoid) where parseJSON = withObjectWarnings "BuildOptsMonoid" (\o -> do buildMonoidLibProfile <- o ..:? buildMonoidLibProfileArgName buildMonoidExeProfile <- o ..:? buildMonoidExeProfileArgName buildMonoidHaddock <- o ..:? buildMonoidHaddockArgName buildMonoidOpenHaddocks <- o ..:? buildMonoidOpenHaddocksArgName buildMonoidHaddockDeps <- o ..:? buildMonoidHaddockDepsArgName buildMonoidInstallExes <- o ..:? buildMonoidInstallExesArgName buildMonoidPreFetch <- o ..:? buildMonoidPreFetchArgName buildMonoidKeepGoing <- o ..:? buildMonoidKeepGoingArgName buildMonoidForceDirty <- o ..:? buildMonoidForceDirtyArgName buildMonoidTests <- o ..:? buildMonoidTestsArgName buildMonoidTestOpts <- jsonSubWarnings (o ..:? buildMonoidTestOptsArgName ..!= mempty) buildMonoidBenchmarks <- o ..:? buildMonoidBenchmarksArgName buildMonoidBenchmarkOpts <- jsonSubWarnings (o ..:? buildMonoidBenchmarkOptsArgName ..!= mempty) buildMonoidReconfigure <- o ..:? buildMonoidReconfigureArgName buildMonoidCabalVerbose <- o ..:? buildMonoidCabalVerboseArgName buildMonoidSplitObjs <- o ..:? buildMonoidSplitObjsName return BuildOptsMonoid{..}) buildMonoidLibProfileArgName :: Text buildMonoidLibProfileArgName = "library-profiling" buildMonoidExeProfileArgName :: Text buildMonoidExeProfileArgName = "executable-profiling" buildMonoidHaddockArgName :: Text buildMonoidHaddockArgName = "haddock" buildMonoidOpenHaddocksArgName :: Text buildMonoidOpenHaddocksArgName = "open-haddocks" buildMonoidHaddockDepsArgName :: Text buildMonoidHaddockDepsArgName = "haddock-deps" buildMonoidInstallExesArgName :: Text buildMonoidInstallExesArgName = "copy-bins" buildMonoidPreFetchArgName :: Text buildMonoidPreFetchArgName = "prefetch" buildMonoidKeepGoingArgName :: Text buildMonoidKeepGoingArgName = "keep-going" buildMonoidForceDirtyArgName :: Text buildMonoidForceDirtyArgName = "force-dirty" buildMonoidTestsArgName :: Text buildMonoidTestsArgName = "test" buildMonoidTestOptsArgName :: Text buildMonoidTestOptsArgName = "test-arguments" buildMonoidBenchmarksArgName :: Text buildMonoidBenchmarksArgName = "bench" buildMonoidBenchmarkOptsArgName :: Text buildMonoidBenchmarkOptsArgName = "benchmark-opts" buildMonoidReconfigureArgName :: Text buildMonoidReconfigureArgName = "reconfigure" buildMonoidCabalVerboseArgName :: Text buildMonoidCabalVerboseArgName = "cabal-verbose" buildMonoidSplitObjsName :: Text buildMonoidSplitObjsName = "split-objs" instance Monoid BuildOptsMonoid where mempty = BuildOptsMonoid {buildMonoidLibProfile = Nothing ,buildMonoidExeProfile = Nothing ,buildMonoidHaddock = Nothing ,buildMonoidOpenHaddocks = Nothing ,buildMonoidHaddockDeps = Nothing ,buildMonoidInstallExes = Nothing ,buildMonoidPreFetch = Nothing ,buildMonoidKeepGoing = Nothing ,buildMonoidForceDirty = Nothing ,buildMonoidTests = Nothing ,buildMonoidTestOpts = mempty ,buildMonoidBenchmarks = Nothing ,buildMonoidBenchmarkOpts = mempty ,buildMonoidReconfigure = Nothing ,buildMonoidCabalVerbose = Nothing ,buildMonoidSplitObjs = Nothing } mappend l r = BuildOptsMonoid {buildMonoidLibProfile = buildMonoidLibProfile l <|> buildMonoidLibProfile r ,buildMonoidExeProfile = buildMonoidExeProfile l <|> buildMonoidExeProfile r ,buildMonoidHaddock = buildMonoidHaddock l <|> buildMonoidHaddock r ,buildMonoidOpenHaddocks = buildMonoidOpenHaddocks l <|> buildMonoidOpenHaddocks r ,buildMonoidHaddockDeps = buildMonoidHaddockDeps l <|> buildMonoidHaddockDeps r ,buildMonoidInstallExes = buildMonoidInstallExes l <|> buildMonoidInstallExes r ,buildMonoidPreFetch = buildMonoidPreFetch l <|> buildMonoidPreFetch r ,buildMonoidKeepGoing = buildMonoidKeepGoing l <|> buildMonoidKeepGoing r ,buildMonoidForceDirty = buildMonoidForceDirty l <|> buildMonoidForceDirty r ,buildMonoidTests = buildMonoidTests l <|> buildMonoidTests r ,buildMonoidTestOpts = buildMonoidTestOpts l <> buildMonoidTestOpts r ,buildMonoidBenchmarks = buildMonoidBenchmarks l <|> buildMonoidBenchmarks r ,buildMonoidBenchmarkOpts = buildMonoidBenchmarkOpts l <> buildMonoidBenchmarkOpts r ,buildMonoidReconfigure = buildMonoidReconfigure l <|> buildMonoidReconfigure r ,buildMonoidCabalVerbose = buildMonoidCabalVerbose l <|> buildMonoidCabalVerbose r ,buildMonoidSplitObjs = buildMonoidSplitObjs l <|> buildMonoidSplitObjs r } -- | Which subset of packages to build data BuildSubset = BSAll | BSOnlySnapshot -- ^ Only install packages in the snapshot database, skipping -- packages intended for the local database. | BSOnlyDependencies deriving (Show, Eq) -- | Options for the 'FinalAction' 'DoTests' data TestOpts = TestOpts {toRerunTests :: !Bool -- ^ Whether successful tests will be run gain ,toAdditionalArgs :: ![String] -- ^ Arguments passed to the test program ,toCoverage :: !Bool -- ^ Generate a code coverage report ,toDisableRun :: !Bool -- ^ Disable running of tests } deriving (Eq,Show) defaultTestOpts :: TestOpts defaultTestOpts = TestOpts { toRerunTests = True , toAdditionalArgs = [] , toCoverage = False , toDisableRun = False } data TestOptsMonoid = TestOptsMonoid { toMonoidRerunTests :: !(Maybe Bool) , toMonoidAdditionalArgs :: ![String] , toMonoidCoverage :: !(Maybe Bool) , toMonoidDisableRun :: !(Maybe Bool) } deriving (Show) instance FromJSON (WithJSONWarnings TestOptsMonoid) where parseJSON = withObjectWarnings "TestOptsMonoid" (\o -> do toMonoidRerunTests <- o ..:? toMonoidRerunTestsArgName toMonoidAdditionalArgs <- o ..:? toMonoidAdditionalArgsName ..!= [] toMonoidCoverage <- o ..:? toMonoidCoverageArgName toMonoidDisableRun <- o ..:? toMonoidDisableRunArgName return TestOptsMonoid{..}) toMonoidRerunTestsArgName :: Text toMonoidRerunTestsArgName = "rerun-tests" toMonoidAdditionalArgsName :: Text toMonoidAdditionalArgsName = "additional-args" toMonoidCoverageArgName :: Text toMonoidCoverageArgName = "coverage" toMonoidDisableRunArgName :: Text toMonoidDisableRunArgName = "no-run-tests" instance Monoid TestOptsMonoid where mempty = TestOptsMonoid { toMonoidRerunTests = Nothing , toMonoidAdditionalArgs = [] , toMonoidCoverage = Nothing , toMonoidDisableRun = Nothing } mappend l r = TestOptsMonoid { toMonoidRerunTests = toMonoidRerunTests l <|> toMonoidRerunTests r , toMonoidAdditionalArgs = toMonoidAdditionalArgs l <> toMonoidAdditionalArgs r , toMonoidCoverage = toMonoidCoverage l <|> toMonoidCoverage r , toMonoidDisableRun = toMonoidDisableRun l <|> toMonoidDisableRun r } -- | Options for the 'FinalAction' 'DoBenchmarks' data BenchmarkOpts = BenchmarkOpts { beoAdditionalArgs :: !(Maybe String) -- ^ Arguments passed to the benchmark program , beoDisableRun :: !Bool -- ^ Disable running of benchmarks } deriving (Eq,Show) defaultBenchmarkOpts :: BenchmarkOpts defaultBenchmarkOpts = BenchmarkOpts { beoAdditionalArgs = Nothing , beoDisableRun = False } data BenchmarkOptsMonoid = BenchmarkOptsMonoid { beoMonoidAdditionalArgs :: !(Maybe String) , beoMonoidDisableRun :: !(Maybe Bool) } deriving (Show) instance FromJSON (WithJSONWarnings BenchmarkOptsMonoid) where parseJSON = withObjectWarnings "BenchmarkOptsMonoid" (\o -> do beoMonoidAdditionalArgs <- o ..:? beoMonoidAdditionalArgsArgName beoMonoidDisableRun <- o ..:? beoMonoidDisableRunArgName return BenchmarkOptsMonoid{..}) beoMonoidAdditionalArgsArgName :: Text beoMonoidAdditionalArgsArgName = "benchmark-arguments" beoMonoidDisableRunArgName :: Text beoMonoidDisableRunArgName = "no-run-benchmarks" instance Monoid BenchmarkOptsMonoid where mempty = BenchmarkOptsMonoid { beoMonoidAdditionalArgs = Nothing , beoMonoidDisableRun = Nothing} mappend l r = BenchmarkOptsMonoid { beoMonoidAdditionalArgs = beoMonoidAdditionalArgs l <|> beoMonoidAdditionalArgs r , beoMonoidDisableRun = beoMonoidDisableRun l <|> beoMonoidDisableRun r} data FileWatchOpts = NoFileWatch | FileWatch | FileWatchPoll deriving (Show,Eq)