{-# LANGUAGE NoImplicitPrelude #-}

module Stack.Options.NewParser
  ( newOptsParser
  ) where

import qualified Data.Map.Strict as M
import           Options.Applicative
                   ( Parser, help, idm, long, metavar, short, switch )
import           Options.Applicative.Builder.Extra ( boolFlags )
import           Stack.Init ( InitOpts )
import           Stack.New ( NewOpts (..) )
import           Stack.Options.InitParser ( initOptsParser )
import           Stack.Prelude
import           Stack.Types.PackageName ( packageNameArgument )
import           Stack.Types.TemplateName
                   ( templateNameArgument, templateParamArgument )

-- | Parser for @stack new@.

newOptsParser :: Parser (NewOpts, InitOpts)
newOptsParser :: Parser (NewOpts, InitOpts)
newOptsParser = (,) (NewOpts -> InitOpts -> (NewOpts, InitOpts))
-> Parser NewOpts -> Parser (InitOpts -> (NewOpts, InitOpts))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser NewOpts
newOpts Parser (InitOpts -> (NewOpts, InitOpts))
-> Parser InitOpts -> Parser (NewOpts, InitOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser InitOpts
initOptsParser
 where
  newOpts :: Parser NewOpts
newOpts = PackageName
-> Bool -> Bool -> Maybe TemplateName -> Map Text Text -> NewOpts
NewOpts
    (PackageName
 -> Bool -> Bool -> Maybe TemplateName -> Map Text Text -> NewOpts)
-> Parser PackageName
-> Parser
     (Bool -> Bool -> Maybe TemplateName -> Map Text Text -> NewOpts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod ArgumentFields PackageName -> Parser PackageName
packageNameArgument
          (  String -> Mod ArgumentFields PackageName
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PACKAGE_NAME"
          Mod ArgumentFields PackageName
-> Mod ArgumentFields PackageName -> Mod ArgumentFields PackageName
forall a. Semigroup a => a -> a -> a
<> String -> Mod ArgumentFields PackageName
forall (f :: * -> *) a. String -> Mod f a
help String
"A valid package name."
          )
    Parser
  (Bool -> Bool -> Maybe TemplateName -> Map Text Text -> NewOpts)
-> Parser Bool
-> Parser (Bool -> Maybe TemplateName -> Map Text Text -> NewOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod FlagFields Bool -> Parser Bool
switch
          (  String -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"bare"
          Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields Bool
forall (f :: * -> *) a. String -> Mod f a
help String
"Do not create a subdirectory for the project."
          )
    Parser (Bool -> Maybe TemplateName -> Map Text Text -> NewOpts)
-> Parser Bool
-> Parser (Maybe TemplateName -> Map Text Text -> NewOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
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
"init"
          String
"the initialisation of the project for use with Stack."
          Mod FlagFields Bool
forall m. Monoid m => m
idm
    Parser (Maybe TemplateName -> Map Text Text -> NewOpts)
-> Parser (Maybe TemplateName) -> Parser (Map Text Text -> NewOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TemplateName -> Parser (Maybe TemplateName)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Mod ArgumentFields TemplateName -> Parser TemplateName
templateNameArgument
          (  String -> Mod ArgumentFields TemplateName
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"TEMPLATE_NAME"
          Mod ArgumentFields TemplateName
-> Mod ArgumentFields TemplateName
-> Mod ArgumentFields TemplateName
forall a. Semigroup a => a -> a -> a
<> String -> Mod ArgumentFields TemplateName
forall (f :: * -> *) a. String -> Mod f a
help String
"Name of a template - can take the form\
                  \ [[service:]username/]template with optional service name\
                  \ (github, gitlab, or bitbucket) and username for the \
                  \service; or, a local filename such as foo.hsfiles or ~/foo; \
                  \or, a full URL such as https://example.com/foo.hsfiles."
          ))
    Parser (Map Text Text -> NewOpts)
-> Parser (Map Text Text) -> Parser NewOpts
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([(Text, Text)] -> Map Text Text)
-> Parser [(Text, Text)] -> Parser (Map Text Text)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Text, Text)] -> Map Text Text
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList (Parser (Text, Text) -> Parser [(Text, Text)]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Mod OptionFields (Text, Text) -> Parser (Text, Text)
templateParamArgument
          (  Char -> Mod OptionFields (Text, Text)
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'p'
          Mod OptionFields (Text, Text)
-> Mod OptionFields (Text, Text) -> Mod OptionFields (Text, Text)
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields (Text, Text)
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"param"
          Mod OptionFields (Text, Text)
-> Mod OptionFields (Text, Text) -> Mod OptionFields (Text, Text)
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields (Text, Text)
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"KEY:VALUE"
          Mod OptionFields (Text, Text)
-> Mod OptionFields (Text, Text) -> Mod OptionFields (Text, Text)
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields (Text, Text)
forall (f :: * -> *) a. String -> Mod f a
help String
"Parameter for the template in the format key:value."
          )))