{-# 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
  { $sel:libProfile:BuildOpts :: 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)
      )
  , $sel:exeProfile:BuildOpts :: 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)
      )
  , $sel:libStrip:BuildOpts :: 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)
      )
  , $sel:exeStrip:BuildOpts :: 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)
      )
  , $sel:buildHaddocks:BuildOpts :: Bool
buildHaddocks = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.buildHaddocks
  , $sel:haddockOpts:BuildOpts :: HaddockOpts
haddockOpts = HaddockOptsMonoid -> HaddockOpts
haddockOptsFromMonoid BuildOptsMonoid
buildMonoid.haddockOpts
  , $sel:openHaddocks:BuildOpts :: Bool
openHaddocks =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.openHaddocks
  , $sel:haddockDeps:BuildOpts :: 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
  , $sel:haddockInternal:BuildOpts :: Bool
haddockInternal =
         Bool -> Bool
not Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
&& FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.haddockInternal
  , $sel:haddockHyperlinkSource:BuildOpts :: Bool
haddockHyperlinkSource =
         Bool
isHaddockFromHackage
      Bool -> Bool -> Bool
|| FirstTrue -> Bool
fromFirstTrue BuildOptsMonoid
buildMonoid.haddockHyperlinkSource
  , $sel:haddockForHackage:BuildOpts :: Bool
haddockForHackage = Bool
isHaddockFromHackage
  , $sel:installExes:BuildOpts :: Bool
installExes = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.installExes
  , $sel:installCompilerTool:BuildOpts :: Bool
installCompilerTool = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.installCompilerTool
  , $sel:preFetch:BuildOpts :: Bool
preFetch = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.preFetch
  , $sel:keepGoing:BuildOpts :: Maybe Bool
keepGoing = First Bool -> Maybe Bool
forall a. First a -> Maybe a
getFirst BuildOptsMonoid
buildMonoid.keepGoing
  , $sel:keepTmpFiles:BuildOpts :: Bool
keepTmpFiles = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.keepTmpFiles
  , $sel:forceDirty:BuildOpts :: Bool
forceDirty = Bool
isHaddockFromHackage Bool -> Bool -> Bool
|| FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.forceDirty
  , $sel:tests:BuildOpts :: Bool
tests = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.tests
  , $sel:testOpts:BuildOpts :: TestOpts
testOpts = TestOptsMonoid -> Maybe [String] -> TestOpts
testOptsFromMonoid BuildOptsMonoid
buildMonoid.testOpts Maybe [String]
additionalArgs
  , $sel:benchmarks:BuildOpts :: Bool
benchmarks = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.benchmarks
  , $sel:benchmarkOpts:BuildOpts :: BenchmarkOpts
benchmarkOpts =
      BenchmarkOptsMonoid -> Maybe [String] -> BenchmarkOpts
benchmarkOptsFromMonoid BuildOptsMonoid
buildMonoid.benchmarkOpts Maybe [String]
additionalArgs
  , $sel:reconfigure:BuildOpts :: Bool
reconfigure = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.reconfigure
  , $sel:cabalVerbose:BuildOpts :: CabalVerbosity
cabalVerbose = CabalVerbosity -> First CabalVerbosity -> CabalVerbosity
forall a. a -> First a -> a
fromFirst (Verbosity -> CabalVerbosity
CabalVerbosity Verbosity
normal) BuildOptsMonoid
buildMonoid.cabalVerbose
  , $sel:splitObjs:BuildOpts :: Bool
splitObjs = FirstFalse -> Bool
fromFirstFalse BuildOptsMonoid
buildMonoid.splitObjs
  , $sel:skipComponents:BuildOpts :: [Text]
skipComponents = BuildOptsMonoid
buildMonoid.skipComponents
  , $sel:interleavedOutput:BuildOpts :: Bool
interleavedOutput = FirstTrue -> Bool
fromFirstTrue BuildOptsMonoid
buildMonoid.interleavedOutput
  , $sel:progressBar:BuildOpts :: ProgressBarFormat
progressBar = ProgressBarFormat -> First ProgressBarFormat -> ProgressBarFormat
forall a. a -> First a -> a
fromFirst ProgressBarFormat
CappedBar BuildOptsMonoid
buildMonoid.progressBar
  , $sel:ddumpDir:BuildOpts :: 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
    }