Groovy CliBuilder,如何识别错误的参数?

发布于 2025-01-04 10:18:03 字数 3114 浏览 1 评论 0原文

我正在学习 Groovy CliBuilder,我发现它很棒,除了我不知道如何识别错误的参数。考虑以下示例代码:

def cli = new CliBuilder()
cli.s args: 1, longOpt: 'sdkdir', 'sdkdir usage info'
cli.h args: 0, longOpt: 'help', 'print usage information'
def opt = cli.parse(args)
if (!opt) {
    //how to be in this case? seems I can never reach here
    println "something went wrong, but I don't know what"
} else if (opt.h) {
    cli.usage()
} else (!opt.s) {
    println "missing required option -s, try with --help for more information"
} else {
    //do something
}

如果我使用例如 -p 调用脚本,这是一个无效选项,则不会发生任何情况。同样,如果我在选项后面添加参数,它们也不会被检测到。

我如何检测并发出错误信号?

另外,一个小小的不便之处在于,在我的示例中 -s 是必需参数,因此理论上我可以添加 required: true,但实际上我不能或它-h 也需要,但我认为用 if 测试它是可以的,除非有更好的方法。

我真正的问题是找到不需要的选项和论点。任何帮助表示感谢,谢谢。

更新:感谢@rodion您的意见,我想为了简单起见,我会选择“足够好”而不是“完美”。这是我想到的:

#!/usr/bin/groovy
def cli = new CliBuilder(usage: 'cliTest -s sdkdir {projectName}', 
                         header: 'Command line parameter parsing test in Groovy')
cli.s longOpt: 'sdkdir', args: 1, 'sdkdir usage info, REQUIRED'
cli.h longOpt: 'help', 'print usage information'
def opt = cli.parse(args)
def errMsg = "Invalid arguments.\nusage: ${cli.usage}\n" + 
        "Try `cliTest --help' for more information."
if (!opt) {
    //should never happen, since I don't have required parameters in CliBuilder
    println "error processing arguments\n"
} else if (opt.h) {
    cli.usage()
} else if (!opt.s) {
    println errMsg
} else if (opt.arguments().size() != 1) {
    println errMsg
} else {
    println "Creating project ${opt.arguments()[0]}, sdkdir ${opt.s.value}" 
}

这个解决方案足够好,但并不完美,因为它不会告诉您哪个参数是错误的,而只是告诉您一条简洁的消息或打印使用信息。以下是一些测试:

$ ./cliTest 
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -a
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -a -s ../sdkdir
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s ../sdkdir
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s ../sdkdir projectName
Creating project projectName, sdkdir ../sdkdir

$ ./cliTest -s ../sdkdir projectName wrong
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s ../sdkdir -a  projectName 
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s
error: Missing argument for option: s
usage: cliTest -s sdkdir {projectName}
Command line parameter parsing test in Groovy
 -h,--help           print usage information
 -s,--sdkdir <arg>   sdkdir usage info, REQUIRED
error processing arguments

就我的目的而言,我非常满意,但如果有人知道更好的方法,请告诉我。

另外,我发现当存在 required: true 选项并且参数丢失时,可能会发生 !opt 情况,但根据我的理解,它永远不能使用,否则不可能单独提供帮助选项。

I am learning Groovy CliBuilder and I find it great, except, I don't know how to recognise wrong arguments. Consider the following example code:

def cli = new CliBuilder()
cli.s args: 1, longOpt: 'sdkdir', 'sdkdir usage info'
cli.h args: 0, longOpt: 'help', 'print usage information'
def opt = cli.parse(args)
if (!opt) {
    //how to be in this case? seems I can never reach here
    println "something went wrong, but I don't know what"
} else if (opt.h) {
    cli.usage()
} else (!opt.s) {
    println "missing required option -s, try with --help for more information"
} else {
    //do something
}

If I call my script with, for instance, -p, which is an invalid option nothing happens. Similarly, if I add arguments after the options they aren't detected too.

How can I detect and signal the error?

Also, a small inconvenience is that in my example -s is a required parameter, so in theory, I could add required: true, in practice I can't or it would be required also with -h, but I think testing it with an if is fine, unless there is a better way.

My real problem is about finding unwanted options and arguments. Any help appreciated, thank you.

UPDATE: Thanks @rodion for your input, I guess I will settle with good enough instead of perfect for the sake of simplicity. Here is what I came up with:

#!/usr/bin/groovy
def cli = new CliBuilder(usage: 'cliTest -s sdkdir {projectName}', 
                         header: 'Command line parameter parsing test in Groovy')
cli.s longOpt: 'sdkdir', args: 1, 'sdkdir usage info, REQUIRED'
cli.h longOpt: 'help', 'print usage information'
def opt = cli.parse(args)
def errMsg = "Invalid arguments.\nusage: ${cli.usage}\n" + 
        "Try `cliTest --help' for more information."
if (!opt) {
    //should never happen, since I don't have required parameters in CliBuilder
    println "error processing arguments\n"
} else if (opt.h) {
    cli.usage()
} else if (!opt.s) {
    println errMsg
} else if (opt.arguments().size() != 1) {
    println errMsg
} else {
    println "Creating project ${opt.arguments()[0]}, sdkdir ${opt.s.value}" 
}

This solution is good enough, but not perfect because it doesn't tell you which parameter is wrong, but just tells you with a concise message or prints usage information. Here are some tests:

$ ./cliTest 
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -a
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -a -s ../sdkdir
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s ../sdkdir
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s ../sdkdir projectName
Creating project projectName, sdkdir ../sdkdir

$ ./cliTest -s ../sdkdir projectName wrong
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s ../sdkdir -a  projectName 
Invalid arguments.
usage: cliTest -s sdkdir {projectName}
Try `cliTest --help' for more information.

$ ./cliTest -s
error: Missing argument for option: s
usage: cliTest -s sdkdir {projectName}
Command line parameter parsing test in Groovy
 -h,--help           print usage information
 -s,--sdkdir <arg>   sdkdir usage info, REQUIRED
error processing arguments

For my purposes, I'm more than satisfied, but if anyone knows a better way, let me know.

Also, I figured out that the !opt case can happen when there is a required: true option and the argument is missing, but from my understanding it can never be used, since otherwise is not possible to have an help option alone.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如果没有 2025-01-11 10:18:03

将 groovy CliBuilder 属性 stopAtNonOption 设置为 false。 (默认为 true)。我知道这看起来不直观。

CliBuilder cli = new CliBuilder(usage:'script-name',stopAtNonOption:false)

然后,当您运行命令行应用程序时,一旦遇到无法识别的选项,CliBuilder 将退出并显示错误消息,例如:

$ script-name -bad
error: Unrecognized option: -bad

Set the groovy CliBuilder property stopAtNonOption to false. (It defaults to true). I know this seems unintuitive.

CliBuilder cli = new CliBuilder(usage:'script-name',stopAtNonOption:false)

Then when you run your command line application, the CliBuilder will exit with an error message as soon as it encounters an unrecognized option, e.g.:

$ script-name -bad
error: Unrecognized option: -bad
我们的影子 2025-01-11 10:18:03

这似乎与此问题有关。显然你可以在解析后检查 opt (但如果它为空,那么我猜你什么也没有留下)。哦,这个问题显然不是错误,嗯...很奇怪。

This seems to be related to this issue. Apparently you can inspect opt after parsing (but if it's null, then I guess you are left with nothing). Oh, and the issue is apparenly Not A Bug, hmm... wierd.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文