我正在尝试构建一个git风格的CLI应用程序,例如racket-app command command-params ...
。这类似于使用thor的sub-command
功能可以执行的操作。
我有这段代码:
(define commands
(hash
"noop" (list "Does nothing"
(lambda () (log-info "noop was called :)")))
"render" (list "Prepares and renders the static HTML (hugo)"
render-proc)))
(define s1 (build-possible-commands-from-the-keys-of-commands))
(define command
(command-line
#:usage-help s1
#:args (op) op))
(cond
[(dict-has-key? commands command) ((second (dict-ref commands command)))]
[else (log-error "Unknown command")])
它以command-line: #:usage-help clause contains non-string
失败。
如果我将s1
的引用替换为实际字符串(例如"aoeu"
),那么它的工作正常。我想动态地构建该字符串(在此示例中为s1
),但我无法弄清楚如何做到这一点。
答案 0 :(得分:3)
command-line
的语法说:
flag-clause = ...
#:usage-help string ...
这意味着command-line
之后不会接受一般表达式
#:usage-help
。
我想不出这个限制的理由。我也希望接受一个表达。
我建议在Racket邮件列表中询问 - 也许某人有解释 - 或者如果没有,可能有人会改变command-line
的行为。
答案 1 :(得分:3)
我认为这里的问题是usage-help必须是文字字符串,而不是程序运行时计算的字符串,因为这个字符串应该可以从命令行获得,而不用运行程序。也就是说,raco help
应该能够在不运行程序的情况下提供帮助字符串。
你可以解决这个问题;你需要在扩展时提供字符串。这是最直截了当的方式:
#lang racket
(define-syntax my-cmd
(syntax-rules ()
[(_ str)
(define command
(command-line
#:usage-help str
#:args (op) op))]))
(my-cmd "aoeu")
在这个例子中,很清楚我已经分离了"命令"从文字字符串调用,但它可能对你没用。
所以,这里有一个问题:用例是什么?你是如何在字符串上抽象的呢?
在阅读了您的用例之后,我完全看起来像是想要使用parse-command-line
,就像Jon Zeppieri在球拍邮件列表中所建议的那样。这允许您指定在参数解析失败时要调用的过程,并且您可以发出任何您喜欢的字符串。