结合使用optparse-applicative和多个子命令和全局选项 [英] Using optparse-applicative with multiple subcommands and global options
问题描述
我正在编写一个包含多个子命令的命令行程序,这些子命令带有标志/参数。
I am writing a commandline program that takes multiple subcommands, which take flags/arguments.
该程序还应采用一些适用于以下情况的全局标志所有子命令。例如:
The program should also take some 'global-flags' that are applicable to all subcommands. For examples:
myProgram --configfile=~/.customrc UPLOADFILE --binary myfile.x
myProgram --configfile=~/.customrc SEARCH --regex "[a-z]+"
在此示例中,子命令是 UPLOADFILE
和 SEARCH
,而 configfile
与这两个子命令,以及适用于特定子命令的 binary
和 regex
。
in this example, the subcommands are UPLOADFILE
and SEARCH
, and configfile
is relevant to both subcommands, and binary
and regex
applicable to the specific subcommands.
我认为使用此库必须做到这一点,但是我正在努力找出放置在何处的内容!我是Haskell的新手,试图让我了解应用程序,这使我的大脑受伤:)
I feel this must be possible with this library, but I am struggling to work out what to put where! I am relatively new to Haskell, trying to get my head around applicatives, and it making my brain hurt :)
在
模块的文档,但我似乎无法弄清楚如何获得可以使用全局标志。
There is an example of subcommands here in the documentation for the module, but I can't seem to work out how to get the global-flags to work.
如果有人可以将我引向一个小的工作示例,或者对我应该如何构建代码来做这件事的见解,我将不胜感激,我发现这些高阶函数有些神奇!
If someone could point me towards a small working example, or insight into how I shoud structure code to do this, I would be very grateful, I am finding these higher order functions slightly magical!
非常感谢您的宝贵时间。最好的祝福,
Many thanks for your time. Best wishes,
迈克
推荐答案
您链接的文档包含此内容这样说:
The documentation you linked has this to say:
命令对于实现具有多个
函数的命令行程序很有用,每个函数都有其自己的一组选项,并且可能是一些全局的
选项,适用于所有选项。
虽然没有确切说明应如何应用这些选项。但是,如果您查看类型,则可以获得一些见解。该示例指示使用子解析器
,其类型为 Mod CommandFields a->。解析器a
。这可能不会说太多(尤其是左侧),但至关重要的是,此函数只会生成 Parser
-因此您可以像平常一样将其与其他解析器组合:
Although it does not say precisely how those options should be applied. If you look at the types, however, you can gain some insight. The example indicates to use subparser
, whose type is Mod CommandFields a -> Parser a
. This probably doesn't say much (especially the left hand side) but crucially this function just produces a Parser
- so you can combine it with other parsers as you normally would:
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 ...
定义子命令本身非常简单-我只是从文档中复制了示例,并根据您的特定示例重命名了一些内容:
Defining subcommands themselves is fairly straightforward - I just copied the example from the docs and renamed some things in accordance with your specific example:
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" )
运行此程序将提供以下信息:
Running this program gives the following:
>: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
这篇关于结合使用optparse-applicative和多个子命令和全局选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!