{-# LANGUAGE NoImplicitPrelude #-}
module Stack.Options.ExecParser where

import           Options.Applicative
import           Options.Applicative.Builder.Extra
import           Options.Applicative.Args
import           Stack.Options.Completion
import           Stack.Prelude
import           Stack.Types.Config

-- | Parser for exec command
execOptsParser :: Maybe SpecialExecCmd -> Parser ExecOpts
execOptsParser :: Maybe SpecialExecCmd -> Parser ExecOpts
execOptsParser Maybe SpecialExecCmd
mcmd =
    SpecialExecCmd -> [String] -> ExecOptsExtra -> ExecOpts
ExecOpts
        (SpecialExecCmd -> [String] -> ExecOptsExtra -> ExecOpts)
-> Parser SpecialExecCmd
-> Parser ([String] -> ExecOptsExtra -> ExecOpts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser SpecialExecCmd
-> (SpecialExecCmd -> Parser SpecialExecCmd)
-> Maybe SpecialExecCmd
-> Parser SpecialExecCmd
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Parser SpecialExecCmd
eoCmdParser SpecialExecCmd -> Parser SpecialExecCmd
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe SpecialExecCmd
mcmd
        Parser ([String] -> ExecOptsExtra -> ExecOpts)
-> Parser [String] -> Parser (ExecOptsExtra -> ExecOpts)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [String]
eoArgsParser
        Parser (ExecOptsExtra -> ExecOpts)
-> Parser ExecOptsExtra -> Parser ExecOpts
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ExecOptsExtra
execOptsExtraParser
  where
    eoCmdParser :: Parser SpecialExecCmd
eoCmdParser = String -> SpecialExecCmd
ExecCmd (String -> SpecialExecCmd)
-> Parser String -> Parser SpecialExecCmd
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod ArgumentFields String -> Parser String
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument (String -> Mod ArgumentFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"COMMAND" Mod ArgumentFields String
-> Mod ArgumentFields String -> Mod ArgumentFields String
forall a. Semigroup a => a -> a -> a
<> Completer -> Mod ArgumentFields String
forall (f :: * -> *) a. HasCompleter f => Completer -> Mod f a
completer Completer
projectExeCompleter)
    eoArgsParser :: Parser [String]
eoArgsParser = Parser String -> Parser [String]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Mod ArgumentFields String -> Parser String
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument (String -> Mod ArgumentFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
txt))
      where
        txt :: String
txt = case Maybe SpecialExecCmd
mcmd of
            Maybe SpecialExecCmd
Nothing -> String
normalTxt
            Just ExecCmd{} -> String
normalTxt
            Just SpecialExecCmd
ExecRun -> String
"-- ARGUMENT(S) (e.g. stack run -- file.txt)"
            Just SpecialExecCmd
ExecGhc -> String
"-- ARGUMENT(S) (e.g. stack runghc -- X.hs -o x)"
            Just SpecialExecCmd
ExecRunGhc -> String
"-- ARGUMENT(S) (e.g. stack runghc -- X.hs)"
        normalTxt :: String
normalTxt = String
"-- ARGUMENT(S) (e.g. stack exec ghc-pkg -- describe base)"

evalOptsParser :: String -- ^ metavar
               -> Parser EvalOpts
evalOptsParser :: String -> Parser EvalOpts
evalOptsParser String
meta =
    String -> ExecOptsExtra -> EvalOpts
EvalOpts
        (String -> ExecOptsExtra -> EvalOpts)
-> Parser String -> Parser (ExecOptsExtra -> EvalOpts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
eoArgsParser
        Parser (ExecOptsExtra -> EvalOpts)
-> Parser ExecOptsExtra -> Parser EvalOpts
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ExecOptsExtra
execOptsExtraParser
  where
    eoArgsParser :: Parser String
    eoArgsParser :: Parser String
eoArgsParser = Mod ArgumentFields String -> Parser String
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument (String -> Mod ArgumentFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
meta)

-- | Parser for extra options to exec command
execOptsExtraParser :: Parser ExecOptsExtra
execOptsExtraParser :: Parser ExecOptsExtra
execOptsExtraParser = EnvSettings
-> [String] -> [String] -> Maybe String -> ExecOptsExtra
ExecOptsExtra
                         (EnvSettings
 -> [String] -> [String] -> Maybe String -> ExecOptsExtra)
-> Parser EnvSettings
-> Parser ([String] -> [String] -> Maybe String -> ExecOptsExtra)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser EnvSettings
eoEnvSettingsParser
                         Parser ([String] -> [String] -> Maybe String -> ExecOptsExtra)
-> Parser [String]
-> Parser ([String] -> Maybe String -> ExecOptsExtra)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [String]
eoPackagesParser
                         Parser ([String] -> Maybe String -> ExecOptsExtra)
-> Parser [String] -> Parser (Maybe String -> ExecOptsExtra)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [String]
eoRtsOptionsParser
                         Parser (Maybe String -> ExecOptsExtra)
-> Parser (Maybe String) -> Parser ExecOptsExtra
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe String)
eoCwdParser
  where
    eoEnvSettingsParser :: Parser EnvSettings
    eoEnvSettingsParser :: Parser EnvSettings
eoEnvSettingsParser = Bool -> Bool -> Bool -> Bool -> Bool -> EnvSettings
EnvSettings Bool
True
        (Bool -> Bool -> Bool -> Bool -> EnvSettings)
-> Parser Bool -> Parser (Bool -> Bool -> Bool -> EnvSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool
boolFlags Bool
True
                String
"ghc-package-path"
                String
"setting the GHC_PACKAGE_PATH variable for the subprocess"
                Mod FlagFields Bool
forall m. Monoid m => m
idm
        Parser (Bool -> Bool -> Bool -> EnvSettings)
-> Parser Bool -> Parser (Bool -> Bool -> EnvSettings)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool
boolFlags Bool
True
                String
"stack-exe"
                String
"setting the STACK_EXE environment variable to the path for the stack executable"
                Mod FlagFields Bool
forall m. Monoid m => m
idm
        Parser (Bool -> Bool -> EnvSettings)
-> Parser Bool -> Parser (Bool -> EnvSettings)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> Parser Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
        Parser (Bool -> EnvSettings) -> Parser Bool -> Parser EnvSettings
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> Parser Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True

    eoPackagesParser :: Parser [String]
    eoPackagesParser :: Parser [String]
eoPackagesParser = Parser String -> Parser [String]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many
                       (Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"package"
                                  Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help String
"Additional package(s) that must be installed"
                                  Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PACKAGE(S)"))

    eoRtsOptionsParser :: Parser [String]
    eoRtsOptionsParser :: Parser [String]
eoRtsOptionsParser = [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[String]] -> [String]) -> Parser [[String]] -> Parser [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [String] -> Parser [[String]]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Mod OptionFields [String] -> Parser [String]
argsOption
        ( String -> Mod OptionFields [String]
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"rts-options"
        Mod OptionFields [String]
-> Mod OptionFields [String] -> Mod OptionFields [String]
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields [String]
forall (f :: * -> *) a. String -> Mod f a
help String
"Explicit RTS options to pass to application"
        Mod OptionFields [String]
-> Mod OptionFields [String] -> Mod OptionFields [String]
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields [String]
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"RTSFLAG"))

    eoCwdParser :: Parser (Maybe FilePath)
    eoCwdParser :: Parser (Maybe String)
eoCwdParser = Parser String -> Parser (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
                  (Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"cwd"
                             Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help String
"Sets the working directory before executing"
                             Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DIR"
                             Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Completer -> Mod OptionFields String
forall (f :: * -> *) a. HasCompleter f => Completer -> Mod f a
completer Completer
dirCompleter)
                  )