使用带有多个子命令和全局选项的optparse-applicative

时间:2016-03-31 16:40:05

标签: haskell command-line-arguments

我正在编写一个命令行程序,它接受多个子命令,它们带有标志/参数。

该程序还应该采用适用于所有子命令的一些“全局标志”。例如:

myProgram --configfile=~/.customrc UPLOADFILE --binary myfile.x
myProgram --configfile=~/.customrc SEARCH --regex "[a-z]+"

在此示例中,子命令为UPLOADFILESEARCHconfigfile与两个子命令相关,binaryregex适用于特定子命令子命令。

我觉得这个库必须有可能,但我正在努力找出放在哪里的东西!我对Haskell相对较新,试图让我的头脑能够应对,并且让我的大脑受伤:)

documentation for the module中有一个子命令的示例,但我似乎无法弄清楚如何使全局标志起作用。

如果有人能指出我的一个小工作示例,或者深入了解我如何构建代码来做到这一点,我将非常感激,我发现这些高阶函数有点神奇!

非常感谢你的时间。祝福,

麦克

1 个答案:

答案 0 :(得分:3)

您链接的文档可以这样说:

  

命令对于实现多个命令行程序很有用   函数,每个函数都有自己的一组选项,可能是一些全局   适用于所有这些选项的选项。

虽然它没有准确说明应该如何应用这些选项。但是,如果你看一下类型,你可以获得一些见解。该示例表明使用subparser,其类型为Mod CommandFields a -> Parser a。这可能并不多(特别是左手边),但关键是这个函数只产生一个Parser - 所以你可以像往常一样将它与其他解析器结合起来:

data Subcommand 
  = Upload { binary :: String } 
  | Search { regex  :: String } deriving Show 

data Options = Options 
  { configFile :: FilePath 
  , subcommand :: Subcommand 
  } deriving Show 

commandO = Options <$> configFileO <*> subcommandO 

configFileO = strOption
   ( long "configfile"
  <> help "Filepath of configuration file" 
   )

subcommandO :: Parser Subcommand
subcommandO = subparser ...

定义子命令本身非常简单 - 我只是从文档中复制了示例,并根据您的具体示例重命名了一些内容:

subcommandO = 
  subparser
    ( command "UPLOADFILE" (info uploadO
        ( progDesc "Upload a file" ))
   <> command "SEARCH" (info searchO
        ( progDesc "Search in a file" ))
   )

uploadO = Upload <$> 
  ( strOption
     ( long "binary"
    <> help "Binary file to upload" 
     )
  )

searchO = Upload <$> 
  ( strOption
     ( long "regex"
    <> help "Regular expression to search for" 
     )
  )

main = execParser opt >>= print where 
  opt = info (helper <*> commandO)
     ( fullDesc
    <> progDesc "Example for multiple subcommands"
    <> header "myProgram" )

运行此程序将提供以下内容:

>:main --configfile=~/.customrc UPLOADFILE --binary myfile.x
Options {configFile = "~/.customrc", subcommand = Upload {binary = "myfile.x"}}

>:main --configfile=~/.customrc SEARCH --regex "[a-z]+"
Options {configFile = "~/.customrc", subcommand = Upload {binary = "[a-z]+"}}

>:main --help
myProgram

Usage: <interactive> --configfile ARG COMMAND
  Example for multiple subcommands

Available options:
  -h,--help                Show this help text
  --configfile ARG         Filepath of configuration file

Available commands:
  UPLOADFILE               Upload a file
  SEARCH                   Search in a file
*** Exception: ExitSuccess