hzDocs
hzDocs
Articles / Postshedzr.comIntroduction

Guide

Your First CLI AppConcise Version
Step by step
Concepts
CommandCommand: Invoke programCommand: Presetting ArgsCommand: RedirectToCommand: DynCommandCommand: Aliases from ConfigCommand: Event HandlersFlagFlag: RequiredFlag: Toggle GroupFlag: Valid ArgsFlag: `Head -1` styleFlag: External EditorFlag: NegatableFlag: Leading Plus Sign `+`Flag: Event Handlers解析结果Builtin Commands & Flags帮助子系统Shared App辨析Package level functionsWithOptsBackstage
Howto ...
Auto-close the ClosersRead config into structUsing is DetectorsUsing Store

References

What's New
Packages

Others

Examples
Blueprint
产品发布
产品发布之前
Examples

Blueprint

good practise for an app written with cmdr

Blueprint

blueprint app 展示了我们推荐的一种项目组织方法。源代码可以在 hedzr/cmdr-tests 的 这里 找到。

“重复的代码”?

除了在 hedzr/cmdr-tests 中有一个 blueprint 示例程序之外,在 hedzr/cmdr 的 examples 中同样有一个 blueprint 示例程序,该示例缺乏 hedzr/cmdr-loaders repo 所提供的外部文件、源的加载能力。

在 hedzr/cmdr-go-starter 中的代码模版同样是 blueprint,这里更为正式,更适合工程实作,因为它为项目代码提供了周边相关的文件,具有完整的代码规范。

在未来,blueprint 将会被放入 hedzr/cmdr-templates repo 中,作为一个默认模版向你提供。

真实世界

cmdr-cli (暂未释出) 工具是完全标准化的独立 app,其中也包含大量到 cmdr 库的代码,这里也是一个参考。

样本代码

hedzr/cmdr-tests 中,以及 hedzr/cmdr 的 examples/ 中都包含各种示例代码供你参考。

all.go
soundex.go
main.go
main.go
package main

import (
	"context"
	"os"

	loaders "github.com/hedzr/cmdr-loaders"
	"github.com/hedzr/cmdr-tests/examples/blueprint/cmd"
	"github.com/hedzr/cmdr/v2"
	"github.com/hedzr/cmdr/v2/cli"
	"github.com/hedzr/cmdr/v2/examples/devmode"
	"github.com/hedzr/cmdr/v2/pkg/logz"
)

const (
	appName = "blueprint"
	desc    = `a good blueprint for you.`
	version = cmdr.Version
	author  = `The Examples Authors`
)

func main() {
	ctx := context.Background()	app := prepareApp(cmd.Commands...) // define your own commands implementations with cmd/*.go
	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)
	}
}

func prepareApp(commands ...cli.CmdAdder) cli.App {
	return loaders.Create(
		appName, version, author, desc,

		cmdr.WithAutoEnvBindings(true),  // default it's false
		cmdr.WithSortInHelpScreen(true), // default it's false
		// cmdr.WithDontGroupInHelpScreen(false), // default it's false
		// cmdr.WithForceDefaultAction(false),
	).
		// importing devmode package and run its init():
		With(func(app cli.App) { logz.Debug("in dev mode?", "mode", devmode.InDevelopmentMode()) }).
		WithBuilders(
			// common.AddHeadLikeFlagWithoutCmd, // add a `--line` option, feel free to remove it.
			// common.AddToggleGroupFlags,       //
			// common.AddTypedFlags,             //
			// common.AddKilobytesFlag,          //
			// common.AddValidArgsFlag,          //
		).
		WithAdders(commands...).
		Build()
}
cmd/all.go
package cmd

import (
	"github.com/hedzr/cmdr/v2/cli"
)

var Commands = append(
	[]cli.CmdAdder{
		sndx{},
	},
	// cmd.Commands...,
)
cmd/soundex.go
package cmd

import (
	"context"
	"fmt"

	"github.com/hedzr/cmdr/v2/cli"
	"github.com/hedzr/cmdr/v2/pkg/text"
)

type sndx struct{}

func (sndx) Add(app cli.App) {
	app.Cmd("soundex", "snd", "sndx", "sound").
		Description("soundex test").
		Group("Test").
		TailPlaceHolders("[text1, text2, ...]").
		OnAction(soundex).
		Build()
}

func soundex(ctx context.Context, cmd cli.Cmd, args []string) (err error) {
	_, _ = cmd, args
	for ix, s := range args {
		fmt.Printf("%5d. %s => %s\n", ix, s, text.Soundex(s))
	}
	return
}

cmdr-tests 中的 blueprint 具有完整的应用程序基础能力。 除了集成了 Store 提供的完整的配置数据管理功能之外,也包含了自动装载配置源的功能。

此外,blueprint 在所有的方面都具备基本的支持。

所以从这里开始,你可以立即投入功能性开发。

如何开始

在有了 blueprint 的基础架构之后,你可以添加子命令。

例如我们想要增加一个 hello 子命令,那么首先可以在 cmd/ 文件夹中增加一个 hello.go 源文件,内容如下:

cmd/hello.go
package cmd

import (
	"context"
	"fmt"

	"github.com/hedzr/cmdr/v2/cli"
	"github.com/hedzr/cmdr/v2/pkg/text"
)

type helloCmd struct{}

func (helloCmd) Add(app cli.App) {
	app.Cmd("hello", "hi").
		Description("hello test").
		Group("Test").
		OnAction(helloCmdRun).
		Build()
}

func helloCmdRun(ctx context.Context, cmd cli.Cmd, args []string) (err error) {
	_, _ = cmd, args
	for ix, s := range args {
		fmt.Printf("%5d. %s => %s\n", ix, s, text.Soundex(s))
	}
	return
}

然后将 helloCmd{} 实例加入 cmd/all.go 的 Commands 中:

cmd/all.go
package cmd

import (
	"github.com/hedzr/cmdr/v2/cli"
)

var Commands = append(
	[]cli.CmdAdder{
		sndx{},
    helloCmd{},
	},
	// cmd.Commands...,
)

现在 hello 子命令就添加就绪了,运行显示帮助屏将会得到下面的结果:

$ go run ./examples/blueprint/ -h
blueprint v2.1.1 ~ Copyright © 2025 by The Examples Authors ~ All Rights Reserved.

Usage:

  $ blueprint  [Options...][files...]

Description:

  a good blueprint for you.

Commands:
  [Test]
    snd, soundex, sndx, sound                 soundex test
    hello                                     hello test

Global Flags:
  [Misc]
    -h, --help,--info,--usage                 Show this help screen (-?) [Env: HELP] (Default: true)

Type '-h'/'-?' or '--help' to get command help screen.
More: '-D'/'--debug', '-V'/'--version', '-#'/'--build-info', '--no-color'...

$

和 devmode 一起工作

blueprint 集成了 devmode.go 来打包初始化用于开发模式的一系列状态环境:

  • debugMode, traceMode and levels of them
  • 状态同步的 logging 设置:是否允许 logz.Debug() 输出(以及 logz.Trace())
  • 自动检测 .devmode 文件是否存在并切入 DevMode

这是通过

With(func(app cli.App) {
  logz.Debug("in dev mode?", "mode", devmode.InDevelopmentMode())
}).

来达成的。

该调用在初始化时刻引用 devmode 包中的 init func 来完成环境检测和状态初始化。

配置文件

cmdr-loader 已经装配好了所有有关的基本工作,所以这样开始:

  1. 在工作目录下新建 blueprint.toml 填写如下内容
    [zoo.camel]
    grouped = false
  2. 运行 ./bin/blueprint ~~debug 查看和找到 app.zoo.camel.grouped 表项以证实配置文件正确装载。
  3. 证实 ./ci/etc/blueprint/ 的配置项已经被加载。

最后,在部署 app 时,将 ./ci/etc/blueprint/ 部署到 /etc/blueprint/,而将 ./blueprint.toml 和 bin/blueprint 可执行文件放在一起。

Tip

windows

将 ./ci/etc/blueprint/ 部署到 /etc/blueprint/ ?

macOS

将 ./ci/etc/blueprint/ 部署到 /usr/local/etc/blueprint/ 或者 /opt/homebrew/etc/blueprint 或者 $HOME/.config/blueprint 都是可以的。

:end:

What is Next?

How is this guide?

Last updated on

Examples

Previous Page

产品发布

基于 cmdr 的 app 有哪些额外检查表

On this page

Blueprint
如何开始
和 devmode 一起工作
配置文件