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
产品发布
产品发布之前
Concepts

Command: Aliases from Config

loading alias commands from a config file

Define alias commands in config file

You can also define alias commands in config file, just like what git cli app to do.

Sample cmdr-tests/examples/dyncmd-cfg

The example app dyncmd-cfg in hedzr/cmdr-tests shows how to add alias commands.

./examples/dyncmd-cfg/main.go
package main

import (
	"context"
	"os"

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

const (
	appName = "dyncmd-cfg"
	desc    = `dyncmd defined in config file`
	version = cmdr.Version
	author  = `The Example Authors`
)

func main() {
	ctx := context.Background()

	app := loaders.Create(appName, version, author, desc).
		With(func(app cli.App) { logz.Debug("in dev mode?", "mode", devmode.InDevelopmentMode()) }).
		WithAdders(cmd.Commands...).
		Build()

	ctx := context.Background()
	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)
	}
}
./examples/cmd/all.go
package cmd

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

var Commands = []cli.CmdAdder{
	jumpCmd{},
	// wrongCmd{},
}
./examples/cmd/all.go
package cmd

import (
	"context"

	"github.com/hedzr/cmdr/v2"
	"github.com/hedzr/cmdr/v2/cli"
	"github.com/hedzr/cmdr/v2/examples/dyncmd"
	"github.com/hedzr/cmdr/v2/pkg/dir"
	logz "github.com/hedzr/logg/slog"
)

type jumpCmd struct{}

func (jumpCmd) Add(app cli.App) {
	app.Cmd("jump").
		Description("jump command").
		Examples(`jump example`). // {{.AppName}}, {{.AppVersion}}, {{.DadCommands}}, {{.Commands}}, ...
		Deprecated(`v1.1.0`).
		Group("Test").
		// Group(cli.UnsortedGroup).
		// Hidden(false).
		OnEvaluateSubCommands(dyncmd.OnEvalJumpSubCommands).
		OnEvaluateSubCommandsFromConfigPath().
		// Both With(cb) and Build() to end a building sequence
		With(func(b cli.CommandBuilder) {
			b.Cmd("to").
				Description("to command").
				Examples(``).
				Deprecated(`v0.1.1`).
				OnAction(func(ctx context.Context, cmd cli.Cmd, args []string) (err error) {
					// cmd.Set() == cmdr.Set(), cmd.Store() == cmdr.Store(cmd.GetDottedPath())
					_, _ = cmd.Set().Set("tiny3.working", dir.GetCurrentDir())
					println()
					println("dir:", cmd.Set().WithPrefix("tiny3").MustString("working"))

					cs := cmd.Set().WithPrefix(cli.CommandsStoreKey, "jump.to")
					if cs.MustBool("full") {
						println()
						println(cmd.Set().Dump())
					}
					cs2 := cmd.Store()
					if cs2.MustBool("full") != cs.MustBool("full") {
						logz.Panic("a bug found")
					}
					app.SetSuggestRetCode(1) // ret code must be in 0-255
					return                   // handling command action here
				}).
				With(func(b cli.CommandBuilder) {
					b.Flg("full", "f").
						Default(false).
						Description("full command").
						Build()
				})
		})
}
all.go
jump.go
main.go

The notable point is OnEvaluateSubCommandsFromConfigPath(), which will load alias command from a special section in the config files.

If nothing specified, dottedPath app.alias would be applied. This means section [alias] in a config file will be read.

The feature is inspired from git cli app and its [alias] section inside $HOME/.gitconfig.

Details

In alias section, each key and value is mapped into a subcmd. The value string is the action of the subcmd, which is a shell script. The prefix of the value string has special purpose:

  • >: redirect to another command, with dottedPath form.
  • !: invoke a gui app or a program. For example, "! say hello" will play voice with text hello (only worked for macOS); "! bash -c "ls /" can invoke ls in bash env.
  • (no prefix): invoke a shell script within standard shell env.

Alias list for dyncmd-cfg app

In the directory ./ci/etc/dyncmd-cfg, there is the config files for dyncmd-cfg, with standard layout. The [alias] section is defined inside dyncmd-cfg.toml.

01.logging.toml
11.main.toml
dyncmd-cfg.toml
[alias]
jc = "> jump to"
ls = "! bash -c \"ls -laG\""
l = "ls -laG"
say = "say hello"

# PREFIX MEANINGS:
# '>':     leading a RedirectTo cmd, using space-sep'd or dot-sep'd path.
#          for examples, "> jump.to" redirect ro 'juml/'to' command.
# '!':     leading a program, for example: "say hello" in macOS will play voice 'hello'.
#          mostly it's a gui program
# nothing: run a shell command. for example: "ls -la" will list file
[logging]
file = "/var/lib/dyncmd-cfg.stdout.log"
rotate = 7    # in days
[server]
port = 3000

The alias commands will be attached to jump command.

Run

The result is,

$ go run ./examples/dyncmd-cfg jump
dyncmd-cfg v2.1.1 ~ Copyright © 2025 by The Example Authors ~ All Rights Reserved.

Usage:

  $ dyncmd-cfg jump [Options...][files...]

Description:

  jump command

Examples:

  jump example

Commands:
  to                                          to command [Since: v0.1.1]
  [Alias]
    jc                                        jump: [alias]/jc
    ls                                        jump: [alias]/ls

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 jc

dir: /Volumes/VolHack/work/godev/cmdr.v2/cmdr.tests
exit status 1
$

It shows everything is okay.

Implements

The key method OnEvaluateSubCommandsFromConfig("alias") is used for enabling alias commands.

OnEvaluateSubCommandsFromConfig().

额外的话题

Howto run a subcmd directly from root

Command

Command: Invokes

Command: Preset Args

Command: Redirect To

Command: Dynamic Cmd

Command: Dynamic Cmd From Config

Command: Event Handlers

What is Next?

How is this guide?

Last updated on

Command: DynCommand

loading dynamic commands at runtime

Command: Event Handlers

OnXXX event handlers...

On this page

Define alias commands in config file
Sample cmdr-tests/examples/dyncmd-cfg
Details
Alias list for dyncmd-cfg app
Run
Implements
额外的话题