# Others
# Addons
在 cmdr-addons
项目中我们收集了一些为 cmdr 做增强的子包。
https://github.com/hedz/cmdr-addons
# Using isdelve
isdelve 几乎被内置于 cmdr
中。
几乎,是指如果你会使用到几个特别的 API 调用的话,则 isdelve 会被自动地引用到你的项目中,否则即使你使用了 cmdr 也不会自动包含 isdelve 的相关内容。这几个特别调用是:
cmdr.InDebugging() bool
cmdr.IsDebuggerAttached() bool
isdelve 提供的检测函数,目的在于检测 dlv 调试器有否在线。如果你的 app 被启用于一个 dlv 兼容的调试容器中,那么上述检测会返回 true 值。
如同这里所讲的那样使得 isdelve 能够生效:
https://stackoverflow.com/questions/47879070/how-can-i-see-if-the-goland-debugger-is-running-in-the-program
In Goland, you can enable this under 'Run/Debug Configurations', by adding the following into 'Go tool arguments:'
-tags=delve
1
If you are outside of Goland, running
go run a.go
will reportdelve false
, if you want to run dlv on its own, usedlv debug --build-flags='-tags=delve' a.go
; this will reportdelve true
.
# 和 IsDebugMode() 的区别
IsDebugMode() bool
的功能是测试 cmdr.GetBoolR("debug")
是否被置位。要设置这个标志,你可以在命令行中输入 --debug/-D
,这是在 cmdr 中内建的隶属于 RootCommand 的标志,目的就在于预置一个全局的 调试模式
。
一般来说,所谓的 调试模式
就是为了能够输出更多的 app 运行过程中预埋的调试日志,如果你使用了 logx 集成(这是我们提供的一个用于整合 cmdr 和 hedzr/log 的附加库),那么 cmdr.Logger.Debugf(...)
将会在 --debug
为 true 时自动被输出。
See also:
WithLogx()
# --debug
vs ~~debug
要注意的是,--debug
是隶属于 RootCommand 的命令行标志,它和 ~~debug
也有所不同。
~~debug
采用 cmdr 特有的标志前缀 ~~
,这会设置一个在 Option Store 中的 debug
配置项,而 --debug
会设置的是 Option Store 中的 app.debug
配置项。
所以通过 cmdr.GetBoolR("debug")
(或者使用 cmdr.GetDebugMode()
)能够获取到 --debug
的配置值,但你无法通过 cmdr.GetBoolR() 的方式取得 ~~debug
的值。取而代之的是,你应该用 cmdr.GetBool("debug")
来获取 ~~debug
的配置值。
GetBool(keyPath) 直接取得 keyPath 对应的配置项的值。
GetBoolR(keyPath) 首先为 keyPath 添加所谓的 OptionsPrefix 前缀,然后再取得新的 keyPath 所对应的配置项的值。
默认的 OptionsPrefix 为 "app"。
# Using dex
(TODO)
# 从 go flag 迁移
请参考:
从 flag 迁移到 cmdr | hzSomthing (opens new window)
# 使用 flag 等价的命令行界面
我们已经熟知 golang 提倡的是短选项类似的命令行界面,每个选项均以短横线引导,选项被建议采用完整的单词而不是缩略语。所以当你使用 flag 时,一个 app 的选项列表往往是这样的风格:
Usage of flagdemo:
-age int
Input Your Age (default 28)
-flagname int
Just for demo (default 1234)
-gender string
Input Your Gender (default "male")
-name string
Input Your Name (default "nick")
2
3
4
5
6
7
8
9
其源码可以参考这里:
https://play.golang.org/p/9I0ZcqJ_oRs (opens new window)
# 用 cmdr 来模拟
由于 cmdr 允许短选项不必被限制为单个字母,故而当你不愿采用标准的 POXIS CLI 界面,而是想沿循 Golang 惯例时,也是能够做到的。
package main
import (
"fmt"
"github.com/hedzr/cmdr"
)
func main() {
if err := cmdr.Exec(buildRootCmd(),
); err != nil {
fmt.Printf("error: %+v\n", err)
}
}
func buildRootCmd() (rootCmd *cmdr.RootCommand) {
root := cmdr.Root(appName, version).
Copyright(copyright, "hedzr").
Description(desc, longDesc).
Examples(examples)
rootCmd = root.RootCommand()
cmdr.NewInt(28).
Titles("age", "age").
Description("Input Your Age").
AttachTo(root)
cmdr.NewInt(1234).
Titles("flagname", "flagname").
Description("Just for demo").
AttachTo(root)
cmdr.NewString("male").
Titles("gender", "gender").
Description("Input Your Gender").
AttachTo(root)
cmdr.NewString("nick").
Titles("name", "name").
Description("Input Your Name").
AttachTo(root)
return
}
const (
appName = "flag-demo"
version = "1.0.0"
copyright = "flag-demo is an effective devops tool"
desc = "flag-demo is an effective devops tool. It make an demo application for `cmdr`."
longDesc = "flag-demo is an effective devops tool. It make an demo application for `cmdr`."
examples = ``
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
其界面形如下面的输出:
可以见到,借助 cmdr 的增强的短选项,我们可以实现和 flag 完全等价的 CLI 界面。
# MetaData at Go Building
在使用 cmdr 时,你可以通过 Golang 的构建过程插入一些元信息,这样将会有利于 cmdr 的基础信息完备。
我们建议你采用如下的过程来进行发布版本的构建:
APP_NAME=your-app-name
APP_VERSION=your-app-version
CMDR_PKG=github.com/hedzr/cmdr/conf
TIMESTAMP=$(date -u '+%Y-%m-%d_%I:%M:%S%p')
GITHASH=$(git rev-parse HEAD)
GOVERSION=$(go version)
LDFLAGS="-s -w -X '$CMDR_PKG.Buildstamp=$TIMESTAMP' -X '$CMDR_PKG.Githash=$GITHASH' -X '$CMDR_PKG.GoVersion=$GOVERSION' -X '$CMDR_PKG.Version=$APP_VERSION' -X '$CMDR_PKG.AppName=$APP_NAME"
go build -ldflags "$LDFLAGS" -o bin/app-name ./cli
2
3
4
5
6
7
8
9
10
11
12
你不必无脑拷贝,只需要知道在 $CMDR_PKG
中,cmdr 约定了一组元信息变量,向它们提供正确的值将会有利于 cmdr 的运作。例如 cmdr 在输出应用名称标题行时,或者通过 --version
打印版本号时,通过 --build-info
打印构建信息屏时,都会用到上述的元信息。
所以在构建你的 app 时,你应该通过 CI 工具来完成这些信息的组织,尽管这些变量也可以通过编程方式去设置。但又何必呢?白白损失启动速度,即使只是几十 ns 也没必要。
🔚