如何在optparse-applicative生成的帮助消息中指定缺失命令的名称?

时间:2018-01-08 04:53:26

标签: haskell optparse-applicative

我正在尝试使用Hackage的optparse-applicative程序包,并且在程序运行时指定的命令不足时,如何指定显示的帮助消息的某个方面有疑问。

以下示例程序说明了我的问题。从命令行运行时,它将两个命令之一作为输入。也就是说,它可以作为$ program com1$ 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

如果在未指定命令com1com2的情况下运行此程序,则会显示帮助消息。

$ program
Missing: (COMMAND | COMMAND)

Usage: options-applicative-example-exe (COMMAND | COMMAND)
  === progDesc ===

此帮助消息显示(COMMAND | COMMAND)而不是(com1 | com2),我认为在此帮助消息中指定名称会更清晰,更有用。

--help中指定$ program --help选项会产生不同的输出。

$ program --help
=== header ===

Usage: options-applicative-example-exe (COMMAND | COMMAND)
  === progDesc ===

Available options:
  -h,--help                Show this help text

Available commands:
  com1
  com2

=== footer ===

命令名com1com2列在“可用命令”部分中。不过,我也认为使用部分会更加清晰,而不是(com1 | com2)而不是(COMMAND | COMMAND)

如何将帮助信息的使用情况部分指定为(com1 | com2)而不是(COMMAND | COMMAND)

1 个答案:

答案 0 :(得分:7)

您似乎可以在命令中使用metavar

com1 = subparser $ mconcat
  [ metavar c
  , command c $ info (pure Com1) fullDesc)
  ] where c = "com1"

虽然这里的每个命令都是自己的subparser,但optparse-applicative的文档更喜欢在将command应用到整体之前先组合subparser修饰符,所以我们只会看到一个COMMAND 1}}和metavar效果不佳。