A partial and therefore somewhat unsatisfying solution.
{-# LANGUAGE DeriveDataTypeable #-}
module Main where
import Control.Monad
import System.Console.CmdArgs
import System.Console.CmdArgs.Explicit
import System.IO
helpAndExit :: (Data a) => String -> a -> IO ()
helpAndExit msg args =
do
let cm = cmdArgsMode args
let ht = msg ++ "\n\n"
++ show cm
cmdArgsApply (CmdArgs{cmdArgsValue=args,
cmdArgsHelp = Just ht,
cmdArgsVersion = Nothing,
cmdArgsVerbosity = Nothing } )
return ()
data FooArgs = FooArgs{script :: String, thing :: String }
deriving (Show, Data, Typeable)
fooArgs = cmdArgsMode $ FooArgs{
script = def &= typ "SCRIPT" &= help "Script",
thing = def &= help "Thing"
}
main :: IO()
main = do
ca <- cmdArgsRun fooArgs
let scriptName = script ca
when (null $ scriptName)
(helpAndExit "scriptName is mandatory" ca)
putStrLn scriptName
This is only a partial solution because parameter specific help is lost. With --help
:
$ stack run -- --help
The fooargs program
fooargs [OPTIONS]
Common flags:
-s --script=SCRIPT Script
-t --thing=ITEM Thing
-? --help Display help message
-V --version Print version information
When not passing a mandatory parameter:
scriptName is mandatory
fooargs [OPTIONS]
Common flags:
-s --script=ITEM
-t --thing=ITEM
-? --help Display help message
-V --version Print version information
This loss of help info for --script
and --thing
is possibly because CmdArgs.cmdArgsPrivate
is not initialised, which also causes a compiler warning. Or it could be related to this caveat in the doco
Values created with annotations are not pure - the first time they are computed they will include the annotations, but subsequently they will not.
It is a shame to post a partial answer, and I solved my problem another way, but since the question has gone unanswered for a few years, perhaps other people can improve this one. It does seem like an obvious use case to me.