1

我正在尝试使用 docopt 实现 HTTPie 的 CLI,但由于某种原因,我无法将 METHOD 作为第一个参数可选。我删除了大部分用于隔离此问题的选项。

此外,HTTPie 的作者获取 REQUEST ITEM 的方式似乎与 docopt 文档有误,因此想知道实现该部分的最佳替代方案是什么。

HTTPie 的完整文档:https ://github.com/jkbr/httpie

我的文档示例: https ://gist.github.com/dasickis/4711926

4

1 回答 1

3

当尝试匹配模式时,docopt是贪婪的。所以如果你的模式是:

usage: http [METHOD] URL [ITEM...]

然后你运行$ http google.com bladocopt 将匹配google.comas METHOD,因为,哟,这是第一个位置参数!在这种情况下, docopt没有任何信息来推断METHOD应该是什么样子。但是,如果您有以下用法:

usage: http [get|post|put|delete] URL [ITEM...]

然后它知道如果不是get/post/put/delete,那么它应该是URL。但是,我可以看到这不是最优的:1. httpie 使用大写名称(被解释为位置参数,而不是 docopt 的命令),2. 如果有很多命令,则用法可能会变得很长。

如果您不关心与 httpie 的兼容性,我会使用 (A) 小写命令,因为按照惯例,命令是小写的。另一个不兼容的设计决策是 (B) 要求METHOD

usage: http METHOD URL [ITEM...]

通过这种方式,您可以使使用模式明确。(C) 为了保持兼容性,我会做以下使用:

usage: http URL [ITEM...] 
       http METHOD URL [ITEM...]

在这种情况下,第二个子模式将永远不会匹配(docopt对 url 和方法一无所知,这使得第一个模式成为第二个模式的超集),然后我将参数分解为:

positional_arguments = [args['URL']] + args['ITEM']

然后positional_arguments手动解析,具体取决于第一个参数看起来像 url 还是像请求动词。

抱歉,docopt没有优雅地处理这个案例,我会更多地考虑这个用例。如果您有任何建议,请创建一个问题:https ://github.com/docopt/docopt/issues

PS您是对的,这REQUEST ITEM是错误的,非常非常规且令人困惑。它应该是REQUEST-ITEMorREQUEST_ITEM或 just ITEM

于 2013-02-05T09:46:47.127 回答