子命令帮助使用 optparse applicative

subcommand help using optparse applicative

我有两个关于 optparse-applicative 的问题:(我把这些问题放在一起,因为很可能存在一个潜在的误解)。

  1. 据说用法是:(COMMAND | COMMAND)

    crime cli - process CRIME template and deploy commands

    Usage: (COMMAND | COMMAND) The CLI for CRIME

我希望它实际列出程序名称(非交互式)并列出命令,但我不知道如何为特定子命令添加元数据。

  1. 当我尝试获取特定子命令的帮助时,我收到有关缺少必需参数的消息。 (

stack exec commandline-exe -- DeployStack --help

> Invalid option `--help'
> 
> Usage: <interactive> DeployStack (-d|--deployment DEPLOYMENT)
>                                  (-t|--template TEMPLATE) 
>                                  [-p|--provider PROVIDER]   Deploy a Stack

以下是我构建帮助的方式:

-- For information about how this was done see: 
-- and https://hackage.haskell.org/package/optparse-applicative
module CLIParser
  ( Actions(..)
  , actions
  ) where

import           Data.Semigroup      ((<>))
import           Options.Applicative
import           Text.Show.Functions

data Actions
  = CreateTemplate
      { name :: String
      , path :: String
      }
  | DeployStack
      { deployment :: String
      , template   :: String
      , provider   :: String
      }
  deriving (Show)

actions :: Parser Actions
actions =
  subparser
    (command
       "CreateTemplate"
       (info templateCreator (progDesc "Create Template")) <>
     commandGroup "Template commands:") <|>
  subparser
    (command "DeployStack" (info deployStack (progDesc "Deploy a Stack")) <>
     commandGroup "Deploy commands:")

templateCreator :: Parser Actions
templateCreator = CreateTemplate <$> nameArg <*> pathArg

deployStack :: Parser Actions
deployStack = DeployStack <$> deployArg <*> templateArg <*> providerArg

nameArg :: Parser String
nameArg =
  strOption
    (long "name" <> metavar "NAME" <> short 'n' <> help "Name to give template")

pathArg :: Parser String
pathArg =
  strOption
    (long "path" <> metavar "PATH" <> short 'p' <> help "Path to template file")

deployArg :: Parser String
deployArg =
  strOption
    (long "deployment" <>
     metavar "DEPLOYMENT" <> short 'd' <> help "Name of deployment")

templateArg :: Parser String
templateArg =
  strOption
    (long "template" <>
     metavar "TEMPLATE" <> short 't' <> help "Template for deployement")

providerArg :: Parser String
providerArg =
  strOption
    (long "provider" <>
     metavar "PROVIDER" <>
     short 'p' <> showDefault <> value "AWS" <> help "Cloud Provider (e.g. AWS)")

** Main.hs **

module Main where

import CLIParser
import Options.Applicative
import System.IO

options :: ParserInfo Actions
options = info (actions <**> helper)
  ( fullDesc
    <> progDesc "The CLI for CRIME"
    <> header "crime cli - process CRIME template and deploy commands" )

main :: IO ()
main = execParser options >>= display


display :: Show a => a -> IO ()
display x = print x

获取 USAGE (COMMAND | COMMAND) 的解决方案是在命令子组中使用元变量。

要获取每个命令的帮助,请使用 hsubcommand 而不是命令。

解决方案如下所示:

D:\CRIME\commandLine>stack exec crimeCLI -- --help
crime cli - process CRIME template and deploy commands

Usage: crimeCLI.EXE (Template COMMAND | Deployment COMMAND)
  (e.g. stack exec crimeCLI -- TemplateCreate -name NAME -path PATHS)

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

Template commands:
  TemplateCreate           Create Template
  TemplateDetails          Show Details about a Template
  TemplateList             List all Templates for this user

Deploy commands:
  DeployStack              Deploy a Stack to a Provider
  DeployRemove             Remove a deployed stack from a Provider

这是代码:

-- For information about how this was done see: 
-- and https://hackage.haskell.org/package/optparse-applicative
module CLIParser
  ( Actions(..)
  , actions
  ) where

import           Data.Semigroup      ((<>))
import           Options.Applicative
import           Text.Show.Functions

data Actions
  = TemplateCreate
      { name :: String
      , path :: String
      }
  | TemplateDelete
      { name :: String
      , path :: String
      }
  | TemplateDetails
      { name :: String
      }
  | TemplateList
  | DeployStack
      { deployment :: String
      , template   :: String
      , provider   :: String
      }
  | DeployRemove
      { deployment :: String
      , template   :: String
      , provider   :: String
      }
  deriving (Show)

actions :: Parser Actions
actions =
  hsubparser
    (command
       "TemplateCreate"
       (info templateCreator (progDesc "Create Template")) <>
     command
       "TemplateDetails"
       (info templateDetails (progDesc "Show Details about a Template")) <>
     command
       "TemplateList"
       (info templateList (progDesc "List all Templates for this user")) <>
     commandGroup "Template commands:" <> (metavar "Template COMMAND")) <|>
  hsubparser
    (command
       "DeployStack"
       (info deployStack (progDesc "Deploy a Stack to a Provider")) <>
     command
       "DeployRemove"
       (info deployRemove (progDesc "Remove a deployed stack from a Provider")) <>
     commandGroup "Deploy commands:"  <> (metavar "Deployment COMMAND"))

templateCreator :: Parser Actions
templateCreator = TemplateCreate <$> nameArg <*> pathArg

templateDetails :: Parser Actions
templateDetails = TemplateDetails <$> nameArg

templateList :: Parser Actions
templateList = pure TemplateList

deployStack :: Parser Actions
deployStack = DeployStack <$> deployArg <*> templateArg <*> providerArg

deployRemove :: Parser Actions
deployRemove = DeployRemove <$> deployArg <*> templateArg <*> providerArg

nameArg :: Parser String
nameArg =
  strOption
    (long "name" <> metavar "NAME" <> short 'n' <> help "Name to give template")

pathArg :: Parser String
pathArg =
  strOption
    (long "path" <> metavar "PATH" <> short 'p' <> help "Path to template file")

deployArg :: Parser String
deployArg =
  strOption
    (long "deployment" <>
     metavar "DEPLOYMENT" <> short 'd' <> help "Name of deployment")

templateArg :: Parser String
templateArg =
  strOption
    (long "template" <>
     metavar "TEMPLATE" <> short 't' <> help "Template for deployement")

providerArg :: Parser String
providerArg =
  strOption
    (long "provider" <>
     metavar "PROVIDER" <>
     short 'p' <> showDefault <> value "AWS" <> help "Cloud Provider (e.g. AWS)")