介绍
GCli 是一个 Golang 下的简单易用的命令行应用工具库。可以很简单的实现运行命令、设定颜色风格、数据展示、进度显示、交互方法等功能。
功能特色
- 使用简单方便,轻量级,无额外依赖;
- 支持添加多个命令,并且支持给命令添加别名;
- 输入的命令错误时,将会提示相似命令(包含别名提示);
- 快速方便的添加选项绑定
--long
,支持添加短选项-s
; - 支持绑定参数到指定名称, 支持必须
required
,可选,数组isArray
三种设定:- 运行命令时将会自动检测,并按对应关系收集参数;
- 支持丰富的颜色渲染输出, 由 gookit/color 提供:
- 同时支持 html 标签式的颜色渲染,兼容 Windows;
- 内置
info,error,success,danger
等多种风格,可直接使用;
- 内置提供用户交互方法:
ReadLine
,Confirm
,Select
,MultiSelect
等; - 内置提供进度显示方法:
Txt
,Bar
,Loading
,RoundTrip
,DynamicText
等; - 自动根据命令生成帮助信息,并且支持颜色显示;
- 支持为当前 CLI 应用生成
zsh
,bash
下的命令补全脚本文件; - 支持将单个命令当做独立应用运行;
GoDoc
快速开始
如下,引入当前包就可以快速的编写 cli 应用了:
import "gopkg.in/gookit/gcli" // 推荐
// or
import "github.com/gookit/gcli"
package main
import (
"github.com/gookit/gcli"
"github.com/gookit/gcli/_examples/cmd"
"runtime"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
app := gcli.NewApp()
// 标识应用的版本
app.Version = "1.0.1"
// 应用描述
app.Description = "this is my cli application"
// 开启 debug 模式
// app.SetVerbose(gcli.VerbDebug)
// 添加一个内置的示例子 Command
app.Add(cmd.ExampleCommand())
// 添加一个自定义的子 Command
app.Add(&gcli.Command{
Name: "demo",
// {$cmd} 将会被替换为 demo
UseFor: "this is a description <info>message</> for {$cmd} command",
// 别名
Aliases: []string{"dm"},
Func: func(cmd *gcli.Command, args []string) int {
gcli.Println("hello, in the demo command")
return 0
},
})
// 运行程序
app.Run()
}
直接运行不传入任何参数会输出帮助信息:
$ go run main.go
This is my cli application (Version: 1.0.1)
Usage:
C:\...\main.exe [Global Options...] {command} [--option ...] [argument ...]
Global Options:
--verbose Set error reporting level(quiet 0 - 4 debug)
--no-color Disable color when outputting message
-h, --help Display the help information
-V, --version Display app version information
Available Commands:
demo This is a description message for demo command (alias: dm)
example This is a description message (alias: exp,ex)
help Display help information
Use "C:\...\main.exe {command} -h" for more information about a command
执行 demo
子命令:
# or: go run main.go dm
$ go run main.go demo
hello, in the demo command
上面除了添加了我们自己定义的 demo
子命令外还添加了一个 GCli 内置的 example
子程序,先查看一下它的帮助信息:
$ go run main.go ex -h
This is a description message
Name: example (alias: exp,ex)
Usage: C:\...\main.exe [Global Options...] example [--option ...] [argument ...]
Global Options:
--verbose Set error reporting level(quiet 0 - 4 debug)
--no-color Disable color when outputting message
-h, --help Display this help information
Options:
-c, --config string
The config option (default value)
-d, --dir DIRECTORY
The DIRECTORY option
--id int
The id option (default 2)
-n, --names value
The option message
-o, --opt string
The option message
Arguments:
arg0 The first argument, is required*
arg1 The second argument, is required*
arg2 The optional argument, is optional
arrArg The array argument, is array
Examples:
C:\...\main.exe example --id 12 -c val ag0 ag1
C:\...\main.exe example --names tom --names john -n c test use special option
测试执行 example
子命令:
$ go run main.go example --id 12 -c val -n zze1 -n zze2 ag0 ag1 ag2 1 2 3
hello, in example command
All options:
{id:12 c:val dir: opt: names:[zze1 zze2]}
Raw args:
[ag0 ag1 ag2 1 2 3]
Get arg by name:
named array arg 'arrArg', value: [1 2 3]
All named args:
named arg 'arg0': {Name:arg0 ShowName:arg0 Description:the first argument, is required IsArray:false Required:true Value:ag0 index:0}
named arg 'arg1': {Name:arg1 ShowName:arg1 Description:the second argument, is required IsArray:false Required:true Value:ag1 index:1}
named arg 'arg2': {Name:arg2 ShowName:arg2 Description:the optional argument, is optional IsArray:false Required:false Value:ag2 index:2}
named arg 'arrArg': {Name:arrArg ShowName:arrArg Description:the array argument, is array IsArray:true Required:false Value:[1 2 3] index:3}
可以看到我们通过各种方式传入参数给 example
子命令,然后由 example
子命令的执行程序逻辑归档输出了各参数。所以如果你希望实现如上的传参方式,你就可以直接跟踪 cmd.ExampleCommand()
进入查看源码来参考实现了。
生成命令补全脚本
当一个命令行程序的子命令很多时,我们往往希望能有命令补全的功能,GCli 默认就内置了生成补全脚本的子 Command,只需要在你的程序中加上即可使用:
import "github.com/gookit/gcli/builtin"
// ...
// 添加内置提供的生成命令
app.Add(builtin.GenAutoCompleteScript())
我这里直接在上面的示例程序中加上上述代码,在 Windows 下编译 Linux 可执行程序:
$ SET CGO_ENABLED=0
$ SET GOOS=linux
$ SET GOARCH=amd64
$ go build
查看命令帮助会发现多了一个 gen:ac
的子命令:
$ demo -h | grep gen
gen:ac Generate auto complete scripts for current application (alias: genac,gen-ac)
执行该子命令来生成补全脚本:
$ demo gen:ac
INFO:
&{shell:bash binName:demo output:auto-completion.bash}
Now, will write content to file auto-completion.bash
$ ls auto-completion.bash
auto-completion.bash
如上运行后就会在当前目录下生成一个 auto-completion.{zsh|bash}
文件, shell 环境名是自动获取的。当然你可以在运行时手动指定,可通过帮助查看相关选项:
$ demo gen:ac -h
Generate auto complete scripts for current application
Name: gen:ac (alias: genac,gen-ac)
Usage: demo [Global Options...] gen:ac [--option ...] [argument ...]
Global Options:
--verbose Set error reporting level(quiet 0 - 4 debug)
--no-color Disable color when outputting message
-h, --help Display this help information
Options:
-b, --bin-name string
Your packaged application bin file name.
-o, --output string
Output shell auto completion script file name. (default auto-completion.{shell})
-s, --shell string
The shell env name for want generated, allow: zsh,bash (default bash)
我这里是在 CentOS 下执行该程序,要使该补全脚本功能永久生效可以将补全脚本移动到指定目录:
$ mv auto-completion.bash /usr/share/bash-completion/completions/demo
如果没有该目录可以通过 yum 安装命令补全的包:
yum install bash-completion
。
将可执行程序放到 PATH
环境变量下,补全效果如下:
# 输入 demo 后按 2 次 tab
$ demo
ex example exp genac gen-ac gen:ac help
如果你不希望保留生成命令补全脚本的子命令则可以在代码中将添加该子命令的代码行注释重新编译。
编写命令
关于参数定义
- 必须的参数不能定义在可选参数之后;
- 只允许有一个数组参数(多个值的);
- 数组参数只能定义在最后;
内置命令示例
内置示例命令的代码涉及功能比较全面,这里就直接拿 cmd.ExampleCommand()
做说明了:
package cmd
import (
"fmt"
"github.com/gookit/color"
"github.com/gookit/gcli"
)
// options for the command
var exampleOpts = struct {
id int
c string
dir string
opt string
names gcli.Strings
}{}
// ExampleCommand command definition
func ExampleCommand() *gcli.Command {
cmd := &gcli.Command{
Name: "example",
UseFor: "this is a description message",
Aliases: []string{"exp", "ex"}, // 命令别名
Func: exampleExecute,
// {$binName} {$cmd} 是内置变量. {$binName} 将会被替换为执行时的二进制程序名称,{$cmd} 将会被替换为 demo
Examples: `{$binName} {$cmd} --id 12 -c val ag0 ag1
<cyan>{$fullCmd} --names tom --names john -n c</> test use special option`,
}
// 绑定命令选项信息
cmd.IntOpt(&exampleOpts.id, "id", "", 2, "the id option")
cmd.StrOpt(&exampleOpts.c, "config", "c", "value", "the config option")
// notice `DIRECTORY` will replace to option value type
cmd.StrOpt(&exampleOpts.dir, "dir", "d", "", "the `DIRECTORY` option")
// 支持设置选项短名称
cmd.StrOpt(&exampleOpts.opt, "opt", "o", "", "the option message")
// 支持绑定自定义变量, 但必须实现 flag.Value 接口
cmd.VarOpt(&exampleOpts.names, "names", "n", "the option message")
// 绑定命令参数信息,按参数位置绑定
cmd.AddArg("arg0", "the first argument, is required", true)
cmd.AddArg("arg1", "the second argument, is required", true)
cmd.AddArg("arg2", "the optional argument, is optional")
cmd.AddArg("arrArg", "the array argument, is array", false, true)
return cmd
}
// 命令执行主逻辑代码
// example run:
// go run ./_examples/cliapp.go ex -c some.txt -d ./dir --id 34 -n tom -n john val0 val1 val2 arrVal0 arrVal1 arrVal2
func exampleExecute(c *gcli.Command, args []string) int {
fmt.Print("hello, in example command\n")
magentaln := color.Magenta.Println
magentaln("All options:")
fmt.Printf("%+v\n", exampleOpts)
magentaln("Raw args:")
fmt.Printf("%v\n", args)
magentaln("Get arg by name:")
arr := c.Arg("arrArg")
fmt.Printf("named array arg '%s', value: %v\n", arr.Name, arr.Value)
magentaln("All named args:")
for _, arg := range c.Args() {
fmt.Printf("named arg '%s': %+v\n", arg.Name, *arg)
}
return 0
}
进度显示
GCli 还提供了一个 progress
模块用来支持进度显示的功能,示例如下:
package main
import (
"time"
)
import "github.com/gookit/gcli/progress"
func ProgressBar(barType string) {
speed := 100
maxSteps := 100
var p *progress.Progress
switch barType {
case "bar":
p = progress.Bar(maxSteps)
case "txt":
p = progress.Txt(maxSteps)
case "load":
p = progress.LoadBar([]rune{'加', '载', '中'}, maxSteps)
case "loading":
p = progress.LoadingBar([]rune{'加', '载', '中'}, maxSteps)
case "counter":
p = progress.Counter(maxSteps)
case "round":
p = progress.RoundTrip('-', 1)
p.MaxSteps = uint(maxSteps)
case "dynamic":
p = progress.DynamicText(map[int]string{18: "未成年", 55: "成年", 75: "老年", 100: "快入土"}, maxSteps)
default:
p = progress.Bar(maxSteps)
}
p.Start()
for i := 0; i < maxSteps; i++ {
time.Sleep(time.Duration(speed) * time.Millisecond)
p.Advance()
}
p.Finish()
}
func main() {
ProgressBar("bar") // ============================================================ 100.0%(100/100)
ProgressBar("txt") // 100.0%(100/100)
ProgressBar("load") // 加 (3/100) -> 载 (4/100) -> 中 (5/100)
ProgressBar("loading") // 加 (3/100) -> 载 (4/100) -> 中 (5/100)
ProgressBar("counter") // 100
ProgressBar("round") // [ - ] 100.0% (100/100)
ProgressBar("dynamic") // 11.0%(11/100)未成年 -> 29.0%(29/100)成年 -> 67.0%(67/100)老年 -> 94.0%(94/100)快入土
}
交互方法
console interactive methods
interact.ReadInput
interact.ReadLine
interact.ReadFirst
interact.Confirm
interact.Select/Choice
interact.MultiSelect/Checkbox
interact.Question/Ask
interact.ReadPassword
示例:
package main
import "fmt"
import "github.com/gookit/gcli/interact"
func main() {
username, _ := interact.ReadLine("Your name?")
password := interact.ReadPassword("Your password?")
ok := interact.Confirm("ensure continue?")
if !ok {
// do something...
}
fmt.Printf("username: %s, password: %s\n", username, password)
}
更多示例和使用请看 interact_demo.go
带颜色输出
GCli 是直接使用 gookit/color 库来实现带颜色输出的效果的。
示例
package main
import (
"github.com/gookit/color"
)
func main() {
// simple usage
color.Cyan.Printf("Simple to use %s\n", "color")
// internal theme/style:
color.Info.Tips("message")
color.Info.Prompt("message")
color.Info.Println("message")
color.Warn.Println("message")
color.Error.Println("message")
// custom color
color.New(color.FgWhite, color.BgBlack).Println("custom color style")
// can also:
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
// use defined color tag
color.Print("use color tag: <suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n")
// use custom color tag
color.Print("custom color tag: <fg=yellow;bg=black;op=underscore;>hello, welcome</>\n")
// set a style tag
color.Tag("info").Println("info style text")
// prompt message
color.Info.Prompt("prompt style message")
color.Warn.Prompt("prompt style message")
// tips message
color.Info.Tips("tips style message")
color.Warn.Tips("tips style message")
// 仅设置前景色
color.FgCyan.Printf("Simple to use %s\n", "color")
// 仅设置背景色
color.BgRed.Printf("Simple to use %s\n", "color")
// 完全自定义 前景色 背景色 选项
style := color.New(color.FgWhite, color.BgBlack, color.OpBold)
style.Println("custom color style")
// can also:
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
}
上述代码对应输出效果如下:
基础颜色
支持在 windows
cmd.exe
使用。
color.Bold
color.Black
color.White
color.Gray
color.Red
color.Green
color.Yellow
color.Blue
color.Magenta
color.Cyan
color.Bold.Println("bold message")
color.Yellow.Println("yellow message")
扩展风格主题
支持在 windows
cmd.exe
使用。
color.Info
color.Note
color.Light
color.Error
color.Danger
color.Notice
color.Success
color.Comment
color.Primary
color.Warning
color.Question
color.Secondary
color.Info.Println("Info message")
color.Success.Println("Success message")
使用颜色html标签
不支持在 windows
cmd.exe
使用,但不影响使用,会自动去除颜色标签。
使用颜色标签可以非常方便简单的构建自己需要的任何格式:
// 使用内置的 color tag
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>")
color.Println("<suc>hello</>")
color.Println("<error>hello</>")
color.Println("<warning>hello</>")
// 自定义颜色属性
color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n")
评论区