Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I specify names for missing commands in the help message generated by optparse-applicative?

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)?

like image 569
mherzl Avatar asked Jan 08 '18 04:01

mherzl


1 Answers

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.

like image 87
Li-yao Xia Avatar answered Oct 09 '22 09:10

Li-yao Xia