I am attempting to use Hackage's optparse-applicative package and have a question regarding how to specify a certain aspect of the help message displayed when the program is run with insufficient commands specified.
The following example program illustrates my issue. When run from the command line it takes one of two commands as input. That is, it is intended to be run either as $ program com1
or $ program com2
.
module Main where
import Options.Applicative
import Data.Semigroup ((<>))
data Command = Com1
| Com2
com1 :: Parser Command
com1 = subparser $ command "com1" $ info (pure Com1) fullDesc
com2 :: Parser Command
com2 = subparser $ command "com2" $ info (pure Com2) fullDesc
commandParser :: Parser Command
commandParser = com1
<|> com2
runCommand :: Command -> IO ()
runCommand Com1 = putStrLn ">>> Com1 <<<"
runCommand Com2 = putStrLn ">>> Com2 <<<"
opts :: ParserInfo Command
opts = info (commandParser <**> helper)
$ fullDesc
<> progDesc "=== progDesc ==="
<> header "=== header ==="
<> footer "=== footer ==="
main :: IO ()
main = runCommand =<< execParser opts
When this program is run with neither command com1
nor com2
specified, a help message is displayed.
$ program
Missing: (COMMAND | COMMAND)
Usage: options-applicative-example-exe (COMMAND | COMMAND)
=== progDesc ===
This help message displays (COMMAND | COMMAND)
instead of (com1 | com2)
, and I think that specifying the names in this help message would be clearer and more useful.
Specifying the --help
option as in $ program --help
gives a different output.
$ program --help
=== header ===
Usage: options-applicative-example-exe (COMMAND | COMMAND)
=== progDesc ===
Available options:
-h,--help Show this help text
Available commands:
com1
com2
=== footer ===
The command names com1
and com2
are listed in the "Available commands" section. Here too, however, I think the usage section would be clearer as (com1 | com2)
instead of (COMMAND | COMMAND)
.
How can I specify the usage section of the help message to be (com1 | com2)
instead of (COMMAND | COMMAND)
?
It seems you can use metavar
on the command.
com1 = subparser $ mconcat
[ metavar c
, command c $ info (pure Com1) fullDesc)
] where c = "com1"
Whereas here each command is its own subparser, the docs of optparse-applicative
prefer to combine command
modifiers first before applying subparser
to the whole, so we would only see a single COMMAND
and metavar
wouldn't work well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With