将 optparse-applicative 与多个子命令和全局选项一起使用

use*_*351 4 haskell command-line-arguments

我正在编写一个命令行程序,它采用多个子命令,这些子命令采用标志/参数。

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

myProgram --configfile=~/.customrc UPLOADFILE --binary myfile.x
myProgram --configfile=~/.customrc SEARCH --regex "[a-z]+"
Run Code Online (Sandbox Code Playgroud)

在此示例中,子命令是UPLOADFILEand SEARCH,并且configfile与这两个子命令相关,binary并且regex适用于特定的子命令。

我觉得这个库一定可以做到这一点,但我正在努力想办法把什么放在哪里!我对 Haskell 比较陌生,试图让我的头脑围绕应用程序,这让我的大脑受伤:)

在 module文档中有一个子命令示例,但我似乎无法弄清楚如何让 global-flags 工作。

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

非常感谢您的时间。最好的祝愿,

麦克风

use*_*038 8

您链接的文档是这样说的:

命令对于实现具有多个功能的命令行程序非常有用,每个功能都有自己的一组选项,可能还有一些 适用于所有这些功能的全局选项。

尽管它没有准确说明应如何应用这些选项。但是,如果您查看这些类型,您可以获得一些见解。该示例指示使用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 ...
Run Code Online (Sandbox Code Playgroud)

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

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" )
Run Code Online (Sandbox Code Playgroud)

运行这个程序会得到以下结果:

>: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
Run Code Online (Sandbox Code Playgroud)