命令:重定向
Redirect To...
重定向某命令到另一目的地
。.SetRedirectTo(subcmd)
为根命令提供一个重定向目的地
从 v2.1.19 开始,.SetRedirectTo(subcmd)
不仅仅为根命令提供一个重定向目的地,也支持任何子命令的重定向。
重定向到另一命令
作用于根命令时,可以让命令行输入 app
等价于输入了 app a b c
,这对于有的情形可能是有用的。
想象一下 pnpm
这样的包管理器命令,pnpm dev
实际上等价于 pnpm run dev
子命令,都是去运行 package.json
的 scripts
节里的 dev
条目所定义的命令行。
TODO
cmdr.v2 有设想为 RedirectTo 加上 fallback: bool 的子特性。
但这一设想尚未定型,也没有纳入计划表。
定义
对于根命令
你需要调用到 RootCommand 的 *CmdS.SetRedirectTo(dottedCmdPath)
接口。达到这一目的的途径可能有多种,下面是一个示例,
完整的源代码可以参考 examples/redirect-to-subcmd。
在范例中,WithAdders()
将会为 app 添加两套子命令:jump to
以及 wrong
。这是标准的 examples/cmd/
子包用于演示目的的基础设施。
而 With(func(app cli.App){...})
闭包则提供一个流式调用中操作 app 对象的机会。
在这里,app.WithRootCommand(...)
可以用于操作 SetRedirectTo
接口函数。
现在,运行 app
的效果就和 app wrong
相同。
可以有多种途径达到目的
为了达到完成到 RootCommand.SetRedirectTo
的调用,可以有多种途径。例如下面这一种:
对于子命令(Since V2.1.19)
对于子命令的重定向,你可以使用 CommandBuilder.RedirectTo(dottedCmdPath)
接口。下面是一个示例:
这个示例来自 cmdr-cli
工具的 init
子命令源代码。
同样地,使用 dottedCmdPath
可以重定向到多级子命令,例如 jump.to
。
不恰当的定义
无效的 dottedCmdPath
并不会报错,但请勿依赖这一现状,cmdr 未来可能根据整体规划而调整这一策略,例如可能返回一个 well-known error 对象等等。
cmdr 在尝试解决重定向目的地时,简单地抛弃无效的 dottedCmdPath
。
如果你定义了过于复杂的重定向路径,甚至导致了循环路径,cmdr 仍然应该工作良好并忽略问题并及时熔断。但这些情况对于终端用户仍然是不友好的,所以不宜滥用 cmdr 的容错能力。
一个例子是,当 rootCmd -> new
和 init
-> new
同时存在时,就会隐式地形成了循环路径。这是因为 cmdr 在尝试为 init
命令匹配标志时,它首先会试图匹配 new
命令的标志,而当new
命令未能完成标志的匹配时,cmdr 将会向上匹配,即沿着 new
的所有父命令的拥有者链条反向地依次尝试完成标志的匹配,直到尝试在 rootCmd 上进行标志匹配,注意到 rootCmd -> new
RedirectTo 的原因,又会重定向到 new
命令继续匹配。
这就导致了循环链条。
cmdr 将会追踪所有重定向规则,因此将会在最后一步从 rootCmd
推进到 new
的时候发生熔断,从而解决循环问题。
另一个简单的例子是,你尝试定义 new
-> new
重定向规则。它将会完成,但显然是错误的。cmdr 通过追踪规则也同样解决该循环问题。
当前 cmdr 并不试图警告你编码构造了不恰当的规则和命令层次结构,这需要你自行规划和确认。
惯用法
由于 cmdr 在标志匹配时自动解决到重定向目标以及父级命令链条,所以全局内建标志 --help
可以在 app init --help
命令行的解析中正确地被找到。类似地,app init --out /tmp/src.test
能够正确地将 --out
解决为 属于 new
命令。
因此对于重定向命令本身(例如 init
)来说,无需定义任何标志,它将自动引用重定向目标命令的标志集合来完成匹配。
多级命令
如果想要重定向到多级子命令,可以使用 dottedPath
/dottedCmdPath
。例如跳转到 jump to
子命令,可以使用 SetRedirectTo("jump.to")
来达成。
运行时
本文开始的示例程序的运行时效果如同这样:
返回的 Application Error 显示出根命令已经正确转向到了 “wrong” 子命令。
此时根命令默认功能就不再是显示帮助屏了,为了显示帮助屏,你需要显式地 -h
/--help
。
帮助屏中的效果
以下截图取自 cmdr-cli
工具(即将发布)。
Rootcmd
Subcmd
额外的话题
How is this guide?
Last updated on