module Stack.SetupCmd
( setup
, setupParser
, SetupCmdOpts(..)
) where
import Control.Applicative
import Control.Monad.Logger ()
import Control.Monad.Reader
import qualified Data.Text as T
import qualified Options.Applicative as OA
import qualified Options.Applicative.Builder.Extra as OA
import qualified Options.Applicative.Types as OA
import Path
import Stack.Prelude
import Stack.Setup
import Stack.Types.Compiler
import Stack.Types.Config
import Stack.Types.Version
data SetupCmdOpts = SetupCmdOpts
{ scoCompilerVersion :: !(Maybe (CompilerVersion 'CVWanted))
, scoForceReinstall :: !Bool
, scoUpgradeCabal :: !(Maybe UpgradeTo)
, scoSetupInfoYaml :: !String
, scoGHCBindistURL :: !(Maybe String)
, scoGHCJSBootOpts :: ![String]
, scoGHCJSBootClean :: !Bool
}
setupYamlCompatParser :: OA.Parser String
setupYamlCompatParser = stackSetupYaml <|> setupInfoYaml
where stackSetupYaml = OA.strOption (
OA.long "stack-setup-yaml"
<> OA.help "DEPRECATED: Use 'setup-info-yaml' instead"
<> OA.metavar "URL"
<> OA.hidden )
setupInfoYaml = OA.strOption (
OA.long "setup-info-yaml"
<> OA.help "Alternate URL or absolute path for stack dependencies"
<> OA.metavar "URL"
<> OA.value defaultSetupInfoYaml )
cabalUpgradeParser :: OA.Parser UpgradeTo
cabalUpgradeParser = Specific <$> version' <|> latestParser
where
versionReader = do
s <- OA.readerAsk
case parseVersion (T.pack s) of
Nothing -> OA.readerError $ "Invalid version: " ++ s
Just v -> return v
version' = OA.option versionReader (
OA.long "install-cabal"
<> OA.metavar "VERSION"
<> OA.help "Install a specific version of Cabal" )
latestParser = OA.flag' Latest (
OA.long "upgrade-cabal"
<> OA.help "Install latest version of Cabal globally" )
setupParser :: OA.Parser SetupCmdOpts
setupParser = SetupCmdOpts
<$> OA.optional (OA.argument readVersion
(OA.metavar "GHC_VERSION" <>
OA.help ("Version of GHC to install, e.g. 7.10.2. " ++
"The default is to install the version implied by the resolver.")))
<*> OA.boolFlags False
"reinstall"
"reinstalling GHC, even if available (incompatible with --system-ghc)"
OA.idm
<*> OA.optional cabalUpgradeParser
<*> setupYamlCompatParser
<*> OA.optional (OA.strOption
(OA.long "ghc-bindist"
<> OA.metavar "URL"
<> OA.help "Alternate GHC binary distribution (requires custom --ghc-variant)"))
<*> OA.many (OA.strOption
(OA.long "ghcjs-boot-options"
<> OA.metavar "GHCJS_BOOT"
<> OA.help "Additional ghcjs-boot options"))
<*> OA.boolFlags True
"ghcjs-boot-clean"
"Control if ghcjs-boot should have --clean option present"
OA.idm
where
readVersion = do
s <- OA.readerAsk
case parseCompilerVersion ("ghc-" <> T.pack s) of
Nothing ->
case parseCompilerVersion (T.pack s) of
Nothing -> OA.readerError $ "Invalid version: " ++ s
Just x -> return x
Just x -> return x
setup
:: (HasConfig env, HasGHCVariant env)
=> SetupCmdOpts
-> CompilerVersion 'CVWanted
-> VersionCheck
-> Maybe (Path Abs File)
-> RIO env ()
setup SetupCmdOpts{..} wantedCompiler compilerCheck mstack = do
Config{..} <- view configL
(_, _, sandboxedGhc) <- ensureCompiler SetupOpts
{ soptsInstallIfMissing = True
, soptsUseSystem = configSystemGHC && not scoForceReinstall
, soptsWantedCompiler = wantedCompiler
, soptsCompilerCheck = compilerCheck
, soptsStackYaml = mstack
, soptsForceReinstall = scoForceReinstall
, soptsSanityCheck = True
, soptsSkipGhcCheck = False
, soptsSkipMsys = configSkipMsys
, soptsUpgradeCabal = scoUpgradeCabal
, soptsResolveMissingGHC = Nothing
, soptsSetupInfoYaml = scoSetupInfoYaml
, soptsGHCBindistURL = scoGHCBindistURL
, soptsGHCJSBootOpts = scoGHCJSBootOpts ++ ["--clean" | scoGHCJSBootClean]
}
let compiler = case wantedCompiler of
GhcVersion _ -> "GHC"
GhcjsVersion {} -> "GHCJS"
if sandboxedGhc
then logInfo $ "stack will use a sandboxed " <> compiler <> " it installed"
else logInfo $ "stack will use the " <> compiler <> " on your PATH"
logInfo "For more information on paths, see 'stack path' and 'stack exec env'"
logInfo $ "To use this " <> compiler <> " and packages outside of a project, consider using:"
logInfo "stack ghc, stack ghci, stack runghc, or stack exec"