module Stack.SetupCmd
( setup
, setupParser
, SetupCmdOpts(..)
) where
import Control.Applicative
import Control.Monad.Logger
import Control.Monad.Reader
import Data.Monoid
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 Prelude
import Stack.Setup
import Stack.Types.Compiler
import Stack.Types.Config
import Stack.Types.StackT
import Stack.Types.Version
data SetupCmdOpts = SetupCmdOpts
{ scoCompilerVersion :: !(Maybe CompilerVersion)
, 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
:: (StackM env m, HasConfig env, HasGHCVariant env)
=> SetupCmdOpts
-> CompilerVersion
-> VersionCheck
-> Maybe (Path Abs File)
-> m ()
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"