{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedRecordDot   #-}

-- | Build configuration

module Stack.Config.Build
 ( buildOptsFromMonoid
 , haddockOptsFromMonoid
 , testOptsFromMonoid
 , benchmarkOptsFromMonoid
 ) where

import           Distribution.Verbosity ( normal )
import           Stack.BuildOpts
                   ( defaultBenchmarkOpts, defaultHaddockOpts, defaultTestOpts )
import           Stack.Prelude
import           Stack.Types.BuildOpts
                   ( BenchmarkOpts (..), BuildOpts (..), HaddockOpts (..)
                   , TestOpts (..)
                   )
import qualified Stack.Types.BuildOpts as BenchmarkOpts ( BenchmarkOpts (..) )
import qualified Stack.Types.BuildOpts as HaddockOpts ( HaddockOpts (..) )
import qualified Stack.Types.BuildOpts as TestOpts ( TestOpts (..) )
import           Stack.Types.BuildOptsMonoid
                   ( BenchmarkOptsMonoid (..), BuildOptsMonoid (..)
                   , CabalVerbosity (..), HaddockOptsMonoid (..)
                   , ProgressBarFormat (..), TestOptsMonoid (..)
                   )

-- | Interprets BuildOptsMonoid options.

buildOptsFromMonoid :: BuildOptsMonoid -> BuildOpts
buildOptsFromMonoid :: BuildOptsMonoid -> BuildOpts
buildOptsFromMonoid BuildOptsMonoid
buildMonoid = BuildOpts
  { libProfile :: Bool
libProfile = FirstFalse -> Bool
fromFirstFalse
      (  BuildOptsMonoid
buildMonoid.libProfile
      FirstFalse -> FirstFalse -> FirstFalse
forall a. Semigroup a => a -> a -> a
<> Maybe Bool -> FirstFalse
FirstFalse (if Bool
tracing Bool -> Bool -> Bool
|| Bool
profiling then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True else Maybe Bool
forall a. Maybe a
Nothing)
      )
  , exeProfile :: Bool
exeProfile = FirstFalse -> Bool
fromFirstFalse
      (  BuildOptsMonoid
buildMonoid.exeProfile
      FirstFalse -> FirstFalse -> FirstFalse
forall a. Semigroup a => a -> a -> a
<> Maybe Bool -> FirstFalse
FirstFalse (if Bool
tracing Bool -> Bool -> Bool
|| Bool
profiling then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True else Maybe Bool
forall a. Maybe a
Nothing)
      )
  , libStrip :: Bool
libStrip = FirstTrue -> Bool
fromFirstTrue
      (  BuildOptsMonoid
buildMonoid.libStrip
      FirstTrue -> FirstTrue -> FirstTrue
forall a. Semigroup a => a -> a -> a
<> Maybe Bool -> FirstTrue
FirstTrue (if Bool
noStripping then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False else Maybe Bool
forall a. Maybe a
Nothing)
      )
  , exeStrip :: Bool
exeStrip = FirstTrue -> Bool
fromFirstTrue
      (  BuildOptsMonoid
buildMonoid.exeStrip
      FirstTrue -> FirstTrue -> FirstTrue
forall a. Semigroup a => a -> a -> a
<> Maybe Bool -> FirstTrue
FirstTrue (if Bool
noStripping then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False else Maybe Bool
forall a. Maybe a
Nothing)
      )
  , buildHaddocks :: Bool
buildHaddocks = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.buildHaddocks
  , haddockOpts :: HaddockOpts
haddockOpts = HaddockOptsMonoid -> HaddockOpts
haddockOptsFromMonoid BuildOptsMonoid
buildMonoid.haddockOpts
  , openHaddocks :: Bool
openHaddocks =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.openHaddocks
  , haddockDeps :: Maybe Bool
haddockDeps = if Bool
isHaddockFromHackage
      then Maybe Bool
forall a. Maybe a
Nothing
      else First Bool -> Maybe Bool
forall a. First a -> Maybe a
getFirst BuildOptsMonoid
buildMonoid.haddockDeps
  , haddockExecutables :: Bool
haddockExecutables =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.haddockExecutables
  , haddockTests :: Bool
haddockTests =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.haddockTests
  , haddockBenchmarks :: Bool
haddockBenchmarks =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.haddockBenchmarks
  , haddockInternal :: Bool
haddockInternal =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.haddockInternal
  , haddockHyperlinkSource :: Bool
haddockHyperlinkSource =
         Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
|| FirstTrue -> Bool
fromFirstTrue BuildOptsMonoid
buildMonoid.haddockHyperlinkSource
  , haddockForHackage :: Bool
haddockForHackage = Bool
isHaddockFromHackage
  , installExes :: Bool
installExes = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.installExes
  , installCompilerTool :: Bool
installCompilerTool = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.installCompilerTool
  , preFetch :: Bool
preFetch = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.preFetch
  , keepGoing :: Maybe Bool
keepGoing = First Bool -> Maybe Bool
forall a. First a -> Maybe a
getFirst BuildOptsMonoid
buildMonoid.keepGoing
  , keepTmpFiles :: Bool
keepTmpFiles = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.keepTmpFiles
  , forceDirty :: Bool
forceDirty = Bool
isHaddockFromHackage Bool -> Bool -> Bool
|| FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.forceDirty
  , tests :: Bool
tests = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.tests
  , testOpts :: TestOpts
testOpts = TestOptsMonoid -> Maybe [String] -> TestOpts
testOptsFromMonoid BuildOptsMonoid
buildMonoid.testOpts Maybe [String]
additionalArgs
  , benchmarks :: Bool
benchmarks = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.benchmarks
  , benchmarkOpts :: BenchmarkOpts
benchmarkOpts =
      BenchmarkOptsMonoid -> Maybe [String] -> BenchmarkOpts
benchmarkOptsFromMonoid BuildOptsMonoid
buildMonoid.benchmarkOpts Maybe [String]
additionalArgs
  , reconfigure :: Bool
reconfigure = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.reconfigure
  , cabalVerbose :: CabalVerbosity
cabalVerbose = CabalVerbosity -> First CabalVerbosity -> CabalVerbosity
forall a. a -> First a -> a
fromFirst (Verbosity -> CabalVerbosity
CabalVerbosity Verbosity
normal) BuildOptsMonoid
buildMonoid.cabalVerbose
  , splitObjs :: Bool
splitObjs = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.splitObjs
  , skipComponents :: [StackUnqualCompName]
skipComponents = BuildOptsMonoid
buildMonoid.skipComponents
  , interleavedOutput :: Bool
interleavedOutput = FirstTrue -> Bool
fromFirstTrue BuildOptsMonoid
buildMonoid.interleavedOutput
  , progressBar :: ProgressBarFormat
progressBar = ProgressBarFormat -> First ProgressBarFormat -> ProgressBarFormat
forall a. a -> First a -> a
fromFirst ProgressBarFormat
CappedBar BuildOptsMonoid
buildMonoid.progressBar
  , ddumpDir :: Maybe Text
ddumpDir = First Text -> Maybe Text
forall a. First a -> Maybe a
getFirst BuildOptsMonoid
buildMonoid.ddumpDir
  }
 where
  isHaddockFromHackage :: Bool
isHaddockFromHackage = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.haddockForHackage
  -- These options are not directly used in bopts, instead they

  -- transform other options.

  tracing :: Bool
tracing = Any -> Bool
getAny BuildOptsMonoid
buildMonoid.trace
  profiling :: Bool
profiling = Any -> Bool
getAny BuildOptsMonoid
buildMonoid.profile
  noStripping :: Bool
noStripping = Any -> Bool
getAny BuildOptsMonoid
buildMonoid.noStrip
  -- Additional args for tracing / profiling

  additionalArgs :: Maybe [String]
additionalArgs =
    if Bool
tracing Bool -> Bool -> Bool
|| Bool
profiling
      then [String] -> Maybe [String]
forall a. a -> Maybe a
Just ([String] -> Maybe [String]) -> [String] -> Maybe [String]
forall a b. (a -> b) -> a -> b
$ String
"+RTS" String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [Maybe String] -> [String]
forall a. [Maybe a] -> [a]
catMaybes [Maybe String
trac, Maybe String
prof, String -> Maybe String
forall a. a -> Maybe a
Just String
"-RTS"]
      else Maybe [String]
forall a. Maybe a
Nothing
  trac :: Maybe String
trac =
    if Bool
tracing
      then String -> Maybe String
forall a. a -> Maybe a
Just String
"-xc"
      else Maybe String
forall a. Maybe a
Nothing
  prof :: Maybe String
prof =
    if Bool
profiling
      then String -> Maybe String
forall a. a -> Maybe a
Just String
"-p"
      else Maybe String
forall a. Maybe a
Nothing

-- | Interprets HaddockOptsMonoid options.

haddockOptsFromMonoid :: HaddockOptsMonoid -> HaddockOpts
haddockOptsFromMonoid :: HaddockOptsMonoid -> HaddockOpts
haddockOptsFromMonoid HaddockOptsMonoid
hoMonoid = HaddockOpts
defaultHaddockOpts
  { HaddockOpts.additionalArgs = hoMonoid.additionalArgs }

-- | Interprets TestOptsMonoid options.

testOptsFromMonoid :: TestOptsMonoid -> Maybe [String] -> TestOpts
testOptsFromMonoid :: TestOptsMonoid -> Maybe [String] -> TestOpts
testOptsFromMonoid TestOptsMonoid
toMonoid Maybe [String]
madditional = TestOpts
defaultTestOpts
  { TestOpts.rerunTests = fromFirstTrue toMonoid.rerunTests
  , TestOpts.additionalArgs =
      fromMaybe [] madditional <> toMonoid.additionalArgs
  , TestOpts.coverage = fromFirstFalse toMonoid.coverage
  , TestOpts.disableRun = fromFirstFalse toMonoid.disableRun
  , TestOpts.maximumTimeSeconds =
      fromFirst
        defaultTestOpts.maximumTimeSeconds
        toMonoid.maximumTimeSeconds
  , TestOpts.allowStdin = fromFirstTrue toMonoid.allowStdin
  }

-- | Interprets BenchmarkOptsMonoid options.

benchmarkOptsFromMonoid ::
     BenchmarkOptsMonoid
  -> Maybe [String]
  -> BenchmarkOpts
benchmarkOptsFromMonoid :: BenchmarkOptsMonoid -> Maybe [String] -> BenchmarkOpts
benchmarkOptsFromMonoid BenchmarkOptsMonoid
beoMonoid Maybe [String]
madditional =
  BenchmarkOpts
defaultBenchmarkOpts
    { BenchmarkOpts.additionalArgs =
        fmap (\[String]
args -> [String] -> String
unwords [String]
args String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" ") madditional <>
        getFirst beoMonoid.additionalArgs
    , BenchmarkOpts.disableRun = fromFirst
        defaultBenchmarkOpts.disableRun
        beoMonoid.disableRun
    }