hzDocs

命令:动态命令清单

loading dynamic commands at runtime

DynCommand

cmdr 支持动态地扫描和识别动态的子命令列表,它们在运行时刻被计算和列举。

实例:concise

示例程序 concise 在子命令 jump 上实现了动态加载外部脚本为子命令的功能。

这并不影响你按照常规方案为 jump 增加固定的子命令 to

./examples/tiny1/main.go
package main
 
import (
	"context"
	"os"
 
	"github.com/hedzr/cmdr/v2"
	"github.com/hedzr/cmdr/v2/examples/cmd"
	"github.com/hedzr/cmdr/v2/pkg/logz"
)
 
const (
	appName = "concise"
	desc    = `concise version of tiny app.`
	version = cmdr.Version
	author  = `The Example Authors`
)
 
func main() {
	app := cmdr.Create(appName, version, author, desc).
		WithAdders(cmd.Commands...).
		Build()
 
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
 
	if err := app.Run(ctx); err != nil {
		logz.ErrorContext(ctx, "Application Error:", "err", err) // stacktrace if in debug mode/build
		os.Exit(app.SuggestRetCode())
	} else if rc := app.SuggestRetCode(); rc != 0 {
		os.Exit(rc)
	}
}

外部脚本文件

cmdr 在 ci/ 中附加了一些短小的 Shell 脚本文件以便对 concise app 进行演示支持。

cpu
disk
memory

它们将会被在运行时动态载入为 jump 的子命令。

运行时

上面的示例程序的运行时效果如同这样:

$ go run ./examples/tiny/concise jump
concise v2.1.1 ~ Copyright © 2025 by The Example Authors ~ All Rights Reserved.
 
Usage:
 
  $ concise jump [Options...][files...]
 
Description:
 
  jump command
 
Examples:
 
  jump example
 
Commands:
  to                                          to command [Since: v0.1.1]
  cpu                                         ci/pkg/usr.local.lib/concise/ext/cpu
  disk                                        ci/pkg/usr.local.lib/concise/ext/disk
  memory                                      ci/pkg/usr.local.lib/concise/ext/memory
 
Global Flags:
  [Misc]
    -h, --help,--info,--usage                 Show this help screen (-?) [Env: HELP] (Default: false)
 
Type '-h'/'-?' or '--help' to get command help screen.
More: '-D'/'--debug', '-V'/'--version', '-#'/'--build-info', '--no-color'...
$ go run ./examples/tiny/concise jump cpu
100.5%
$

实现方法

从基本面上讲,实现动态命令加载主要是利用到 cmdr Cmd 构造器提供的

OnEvaluateSubCommands(dyncmd.OnEvalJumpSubCommands).

接口。

你可以在 cmdr 需要列举、解析、运行动态命令的各种时刻,通过提供回调函数来返回你的命令清单。

如果你只想被回调一次而不是始终回调,那么可以使用 OnEvaluateSubCommandsOnce() 接口。

cmdr concise 以及 dyncmd 提供的是一个较为全面的实现方法,它构造了一个 liteCmd 对象用于包装诸如 cpu shell 脚本。

你可以仿照这种方法,也可以采用你自己的思路。

动态计算的标志?

确实也支持标志清单的动态计算。

请查阅 app.Flg().OnEvaluateFlags() / OnEvaluateFlagsOnce()

额外的话题

How is this guide?

Edit on GitHub

Last updated on

On this page