hinit-0.1.0: src/Hinit/Cli/Options.hs
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE StrictData #-}
module Hinit.Cli.Options where
import Control.Effect.Lift
import Data.String.Interpolate
import Data.Text (Text)
import Data.Version
import GHC.Generics
import Hinit.Types
import Options.Applicative
import Paths_hinit
data Op
= Set Text Val
deriving (Show, Eq, Generic)
toPair :: Op -> (Text, Val)
toPair (Set t v) = (t, v)
data Command
= Init
{ template :: Text,
project :: Text,
ops :: [Op],
force :: Bool
}
| List
{ verbose :: Bool
}
deriving (Show, Generic)
verString :: String
verString = [i|hi version #{showVersion version}|]
readBool :: ReadM Bool
readBool = do
s <- str
if
| s == "True" || s == "true" -> pure True
| s == "False" || s == "false" -> pure False
| otherwise -> fail ("the option " <> s <> " is not a bool")
text :: Parser (Text, Val)
text = (,) <$> arg <*> val
where
arg =
strOption
( long "text"
<> short 't'
<> metavar "Key"
<> help "Set a key-value pair where the value is text"
)
val = Text <$> argument str (metavar "Value")
bool :: Parser (Text, Val)
bool = (,) <$> arg <*> val
where
arg =
strOption
( long "bool"
<> short 'b'
<> metavar "Key"
<> help "Set a key-value pair where the value is boolean"
)
val =
Bool
<$> argument
readBool
( metavar "Value"
<> completeWith ["True", "False"]
)
operation :: Parser Op
operation = setT <|> setB
where
setT =
uncurry Set <$> text
setB =
uncurry Set <$> bool
initOptions :: Parser Command
initOptions =
Init
<$> argument str (metavar "TEMPLATE")
<*> argument str (metavar "TARGET")
<*> many operation
<*> switch (long "force" <> short 'f')
listOptions :: Parser Command
listOptions =
List
<$> switch (long "verbose" <> short 'v')
commandParser :: Parser Command
commandParser =
hsubparser
( foldMap
(\(cmd, parser, desc) -> command cmd (info (parser <**> versionHelper) (progDesc desc)))
[ ("init", initOptions, "Initialze a project"),
("list", listOptions, "List all available templates")
]
)
versionHelper :: Parser (a -> a)
versionHelper = infoOption verString (long "version" <> help "print program version")
cmds :: ParserInfo Command
cmds =
info
(commandParser <**> helper <**> versionHelper)
( fullDesc
<> progDesc
"hi is a generic project scaffolding tool that uses mustache for templating.\n\
\For more documentation, see https://github.com/poscat0x04/hinit"
<> header "hi - Project scaffolding tool writting in Haskell"
)
parseCliOptions :: Has (Lift IO) sig m => m Command
parseCliOptions = sendIO $ execParser cmds