简介

clicobracobraclicli.App

快速使用

cliv1v2v2
1
go get -u github.com/urfave/cli/v2

使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import (
	"fmt"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){
	app := &cli.App{
		Name: "hello",
		Usage: "hello world example",
		Action: func(c *cli.Context)error {
			fmt.Println("hello world")
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}
}

cli.AppRun()cli
1
2
3
func main(){
	(&cli.App{}).Run(os.Args)
}
hello worldName/Usage/ActionNameUsageActioncli.Context
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
C:\Users\xx\Desktop\git\mydocker1>go run main.go
hello world

除了这个,cli为我们额外生成了帮助信息
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
NAME:
   hello - hello world example

USAGE:
    [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help

参数

cli.Context
NArg()Args()cli.ArgsGet(i)i

示例:

 1
 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
package main

import (
	"fmt"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){
	app := &cli.App{
		Name: "arguments",
		Usage: "arguments example",
		Action: func(c *cli.Context)error {
			for i:=0;i<c.NArg();i++{
				fmt.Printf("%d: %s\n",i+1,c.Args().Get(i))
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

输出

1
2
3
4
C:\Users\xx\Desktop\git\mydocker1>go run main.go /bin/bash --c sss
1: /bin/bash
2: --c
3: sss

选项

一个好用的命令行程序怎么会少了选项呢?cli设置和获取选项非常简单。在cli.App{}结构初始化时,设置字段Flags即可添加选项。Flags字段是[]cli.Flag类型,cli.Flag实际上是接口类型。cli为常见类型都实现了对应的XxxFlag,如BoolFlag/DurationFlag/StringFlag等。它们有一些共用的字段,Name/Value/Usage(名称/默认值/释义)。看示例:

 1
 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
func main(){
	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "lang",
				Value: "english",
				Usage: "language for the greeting",
			},
		},
		Action: func(c *cli.Context)error {
			for i:=0;i<c.NArg();i++{
				fmt.Printf("%d: %s\n",i+1,c.Args().Get(i))
			}
			name := "world"
			//获取flag lang的值
			if c.String("lang") == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

输出:

 1
 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
默认调用
C:\Users\xx\Desktop\git\mydocker1>go run main.go
hello world

设置非英语
C:\Users\xx\Desktop\git\mydocker1>go run main.go -lang chinese
你好 world

C:\Users\xx\Desktop\git\mydocker1>go run main.go --lang chinese
你好 world

传入参数作为人名
C:\Users\xx\Desktop\git\mydocker1>go run main.go --lang chinese xx
你好 xx

通过--help查看帮助
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
NAME:
   flags - flag example

USAGE:
    [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --lang value  language for the greeting (default: "english")
   --help, -h    show help

存入变量

c.Type(name)Destination
 1
 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
func main(){
	var language string
	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "lang",
				Value: "english",
				Usage: "language for the greeting",
				Destination: &language,
			},
		},
		Action: func(c *cli.Context)error {

			name := "world"
			if c.NArg() > 0{
				name = c.Args().Get(0)
			}
			//获取flag lang的值
			if language == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

占位值

cliUsage
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func main(){

	app := &cli.App{
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "config",
				Usage: "Load configuration from `FILE`",
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

设置占位值之后,帮助信息中,该占位值会显示在对应的选项后面,对短选项也是有效的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
NAME:


USAGE:
    [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config FILE  Load configuration from FILE
   --help, -h     show help

选项别名

Aliases,
 1
 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
func main(){
	var language string
	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "lang",
				Aliases: []string{"language","l"},
				Value: "english",
				Usage: "language for the greeting",
				Destination: &language,
			},
		},
		Action: func(c *cli.Context)error {

			name := "world"
			if c.NArg() > 0{
				name = c.Args().Get(0)
			}
			//获取flag lang的值
			if language == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

查看帮助信息

 1
 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
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
NAME:
   flags - flag example

USAGE:
    [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --lang value, --language value, -l value  language for the greeting (default: "english")
   --help, -h                                show help


使用--lang chinese、--language chinese和-l chinese效果是一样的。如果通过不同的名称指定同一个选项,会报错:
C:\Users\xx\Desktop\git\mydocker1>go run main.go --lang chinese xx
你好 xx

C:\Users\xx\Desktop\git\mydocker1>go run main.go --language chinese xx
你好 xx

C:\Users\xx\Desktop\git\mydocker1>go run main.go --l chinese xx
你好 xx

C:\Users\xx\Desktop\git\mydocker1>go run main.go --l chinese --lang xx
Cannot use two forms of the same flag: l lang

环境变量

EnvVarscli,
 1
 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
func main(){
	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "lang,language,l",
				Value: "english",
				Usage: "language for the greeting",
				EnvVars: []string{"APP_LANG","SYSTEM_LANG"},
			},
		},
		Action: func(c *cli.Context)error {

			name := "world"
			if c.NArg() > 0{
				name = c.Args().Get(0)
			}
			//获取flag lang的值
			if c.String("lang") == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
C:\Users\xx\Desktop\git\mydocker1>go run main.go
hello world

C:\Users\xx\Desktop\git\mydocker1>set APP_LANG=chinese

C:\Users\xx\Desktop\git\mydocker1>go run main.go
你好 world

C:\Users\xx\Desktop\git\mydocker1>go run main.go
hello world

C:\Users\xx\Desktop\git\mydocker1>set SYSTEM_LANG=chinese

C:\Users\xx\Desktop\git\mydocker1>go run main.go
你好 world

文件

cliFilePath
 1
 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
func main(){
	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "lang,language,l",
				Value: "english",
				Usage: "language for the greeting",
				FilePath: "./lang.txt",
			},
		},
		Action: func(c *cli.Context)error {

			name := "world"
			if c.NArg() > 0{
				name = c.Args().Get(0)
			}
			//获取flag lang的值
			if c.String("lang") == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}
main.golang.txtchinese
1
2
3
C:\Users\xx\Desktop\git\mydocker1>go run main.go
你好 world

cliYAML/JSON/TOML

有一个单独的包altsrc增加了对其他文件格式如(YAML/JSON/TOML)等配置文件获取标志值的支持

目前支持的输入源格式:

  • YAML
  • JSON
  • TOML

但开发人员可以通过实现altsrc来添加对其他输入源的支持。InputSourceContext用于指定源。

YAML示例

 1
 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
package main

import (
	"fmt"
	"github.com/urfave/cli/v2/altsrc"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){
	flags := []cli.Flag{
		//yaml多级使用.分割
		altsrc.NewStringFlag(&cli.StringFlag{Name: "test.lang",Aliases: []string{"lang"}}),
		//指定加载的yaml配置文件路径
		&cli.StringFlag{
			Name: "load",
			Usage: "load yaml `config` ",
		},
	}

	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: flags,
		//在执行命令前加载配置文件
		Before: altsrc.InitInputSourceWithContext(flags,altsrc.NewYamlSourceFromFlagFunc("load")),
		Action: func(c *cli.Context)error {

			name := "world"
			if c.NArg() > 0{
				name = c.Args().Get(0)
			}
			//获取flag lang的值
			if c.String("test.lang") == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

创建yaml load.yaml

1
2
3
test:
  lang: english

运行

1
2
3
4
5
6
C:\Users\xx\Desktop\git\mydocker1>go run main.go
你好 world

C:\Users\xx\Desktop\git\mydocker1>go run main.go   --load load.yaml
hello world

JSON示例

 1
 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
package main

import (
	"fmt"
	"github.com/urfave/cli/v2/altsrc"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){
	flags := []cli.Flag{
		//json多级使用.分割
		altsrc.NewStringFlag(&cli.StringFlag{Name: "test.lang",Aliases: []string{"lang"}}),
		//指定加载的json配置文件路径
		&cli.StringFlag{
			Name: "load",
			Usage: "load json `config` ",
		},
	}

	app := &cli.App{
		Name: "flags",
		Usage: "flag example",
		Flags: flags,
		//在执行命令前加载配置文件
		Before: altsrc.InitInputSourceWithContext(flags,altsrc.NewJSONSourceFromFlagFunc("load")),
		Action: func(c *cli.Context)error {

			name := "world"
			if c.NArg() > 0{
				name = c.Args().Get(0)
			}
			//获取flag lang的值
			if c.String("test.lang") == "english"{
				fmt.Println("hello",name)
			}else {
				fmt.Println("你好",name)
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

创建json文件 load1.json

1
2
3
4
5
{
  "test": {
    "lang": "english"
  }
}

运行

1
2
3
4
5
6
7
8
9
C:\Users\xx\Desktop\git\mydocker1>go run main.go
你好 world

C:\Users\xx\Desktop\git\mydocker1>go run main.go   --load load1.json
hello world

C:\Users\xx\Desktop\git\mydocker1>go run main.go --lang chinese   --load load1.json
你好 world

优先级

标志值源的优先级如下(从高到低):

  • 用户指定的命令行选项值
  • 环境变量(如果指定)
  • 配置文件(如果指定)
  • 默认定义在标志

组合短选项

ls -a -lls -alclicli.AppUseShortOptionHandlingtrue
 1
 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
package main

import (
	"fmt"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){

	app := &cli.App{
		UseShortOptionHandling: true,
		Commands: []*cli.Command{
			{
				Name: "short",
				Usage: "complete a task on the list",
				Flags: []cli.Flag{
					&cli.BoolFlag{Name: "server",Aliases: []string{"s"}},
					&cli.BoolFlag{Name: "option",Aliases: []string{"o"}},
					&cli.BoolFlag{Name: "message",Aliases: []string{"m"}},
				},
				Action: func(c *cli.Context) error {
					fmt.Println("server",c.Bool("server"))
					fmt.Println("option",c.Bool("option"))
					fmt.Println("message",c.Bool("message"))
					return nil
				},
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

运行

1
2
3
4
5
C:\Users\xx\Desktop\git\mydocker1>go run main.go short  -som ss
server true
option true
message true

UseShortOptionHandlingtrue--langclil/a/n/glang--

必要选项

Requiredtrue
 1
 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
package main

import (
	"fmt"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){

	app := &cli.App{
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "lang",
				Value: "english",
				Usage: "language for the greeting",
				Required: true,
			},
		},
		Action: func(c *cli.Context) error {
			if c.String("lang") == "english"{
				fmt.Println("hello")
			}else {
				fmt.Println("你好")
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
不指定lang时
C:\Users\xx\Desktop\git\mydocker1>go run main.go
NAME:
   main.exe - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --lang value  language for the greeting (default: "english")
   --help, -h    show help (default: false)
2021/09/19 13:49:28 Required flag "lang" not set

指定lang
C:\Users\xx\Desktop\git\mydocker1>go run main.go  --lang chinese
你好

帮助文档中的默认值

ValueValueDefaultText
 1
 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
package main

import (
	"fmt"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){

	app := &cli.App{
		Flags: []cli.Flag{
			&cli.IntFlag{
				Name: "port",
				Value: 0,
				Usage: "Use a randomized port",
				DefaultText: "random",
			},
		},
		Action: func(c *cli.Context) error {
			if c.String("lang") == "english"{
				fmt.Println("hello")
			}else {
				fmt.Println("你好")
			}
			return nil
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}
Valuedefault: 0DefaultText
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
C:\Users\xx\Desktop\git\mydocker1>go run main.go  --help
NAME:
   main.exe - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --port value  Use a randomized port (default: random)
   --help, -h    show help (default: false)

子命令

子命令使命令行程序有更好的组织性。git有大量的命令,很多以某个命令下的子命令存在。例如git remote命令下有add/rename/remove等子命令,git submodule下有add/status/init/update等子命令。

cli通过设置cli.App的Commands字段添加命令,设置各个命令的SubCommands字段,即可添加子命令。非常方便!

 1
 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
53
54
55
56
57
58
59
60
61
62
63
package main

import (
	"fmt"
	"github.com/urfave/cli/v2"
	"log"
	"os"
)

func main(){

	app := &cli.App{
		Commands: []*cli.Command{
			{
				Name: "add",
				Aliases: []string{"a"},
				Usage: "add a task to the list",
				Action: func(c *cli.Context) error {
					fmt.Println("added task:",c.Args().First())
					return nil
				},
			},
			{
				Name: "complete",
				Aliases: []string{"c"},
				Usage: "complete a task on the list",
				Action: func(c *cli.Context) error {
					fmt.Println("completed task:",c.Args().First())
					return nil
				},
			},
			{
				Name: "template",
				Aliases: []string{"t"},
				Usage: "option for task templates",
				Subcommands: []*cli.Command{
					{
						Name: "add",
						Usage: "add a new template",
						Action: func(c *cli.Context) error {
							fmt.Println("new task template",c.Args().First())
							return nil
						},
					},
					{
						Name: "remove",
						Usage: "remove an existing template",
						Action: func(c *cli.Context) error {
							fmt.Println("remove task:",c.Args().First())
							return nil
						},
					},
				},
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}
add/complete/templatetemplateadd/remove
 1
 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
C:\Users\xx\Desktop\git\mydocker1>go run main.go  --help
NAME:
   main.exe - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

COMMANDS:
   add, a       add a task to the list
   complete, c  complete a task on the list
   template, t  option for task templates
   help, h      Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help (default: false)

注意一点,子命令默认不显示在帮助信息中,需要显式调用子命令所属命令的帮助(./subcommand template --help):

C:\Users\xx\Desktop\git\mydocker1>go run main.go t --help
NAME:
   main.exe template - option for task templates

USAGE:
   main.exe template command [command options] [arguments...]

COMMANDS:
   add      add a new template
   remove   remove an existing template
   help, h  Shows a list of commands or help for one command

OPTIONS:
   --help, -h  show help (default: false)


C:\Users\xx\Desktop\git\mydocker1>go run main.go add dating
added task: dating

C:\Users\xx\Desktop\git\mydocker1>go run main.go complete dating
completed task: dating

C:\Users\xx\Desktop\git\mydocker1>go run main.go template add dating
new task template dating

C:\Users\xx\Desktop\git\mydocker1>go run main.go template remove dating
remove task: dating

分类

Category
 1
 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
func main(){

	app := &cli.App{
		Commands: []*cli.Command{
			{
				Name: "noop",
				Usage: "Usage for noop",
			},
			{
				Name: "add",
				Category: "template",
				Usage: "Usage for add",
			},
			{
				Name: "remove",
				Category: "template",
				Usage: "Usage for remove",
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil{
		log.Fatal(err)
	}

}

运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
C:\Users\xx\Desktop\git\mydocker1>go run main.go  --help
NAME:
   main.exe - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

COMMANDS:
   noop     Usage for noop
   help, h  Shows a list of commands or help for one command
   template:
     add     Usage for add
     remove  Usage for remove

GLOBAL OPTIONS:
   --help, -h  show help (default: false)

自定义帮助信息

在cli中所有的帮助信息文本都可以自定义,整个应用的帮助信息模板通过AppHelpTemplate指定。命令的帮助信息模板通过CommandHelpTemplate设置,子命令的帮助信息模板通过SubcommandHelpTemplate设置。甚至可以通过覆盖cli.HelpPrinter这个函数自己实现帮助信息输出。下面程序在默认的帮助信息后添加个人网站和微信信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
	"fmt"
	"github.com/urfave/cli"
	"os"
)

func main(){

	cli.AppHelpTemplate = fmt.Sprintf(`%s 
WEBSITE: https://www.xieys.club
WECHAT: 赶路人`,cli.AppHelpTemplate)

	(&cli.App{}).Run(os.Args)
}

运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
C:\Users\xx\Desktop\git\mydocker1>go run main.go  --help
NAME:


USAGE:
    [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help

WEBSITE: https://www.xieys.club
WECHAT: 赶路人

改写帮助模板

 1
 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
package main

import (
	"github.com/urfave/cli"
	"os"
)

func main(){

	cli.AppHelpTemplate = `NAME:
	{{.Name}} - {{.Usage}}
USAGE:
	{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{ if len .Authors}}
AUTHOR:	
	{{range .Authors}}{{.}}{{end}}{{end}}{{if .Commands}}
COMMANDS:
	{{range .Commands}}{{if not .HideHelp}}  {{join .Names ", "}}{{ "\t"}}{{.Usage}}{{ "\n" }}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
GLOBAL OPTIONS:
	{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{if .Copyright}}
COPYRIGHT:
	{{.Copyright}}{{end}}{{if .Version}}
VERSION:
	{{.Version}}{{end}}
`
	app := &cli.App{
		Name: "help",
		Usage: "a new cli application",
		Authors: []cli.Author{
			{
				Name: "xieys",
				Email: "xieys_1993l@163.com",
			},
		},
	}
	app.Run(os.Args)
}
{{.XXX}}XXXcli.App{}Authors

运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
NAME:
  help - a new cli application
USAGE:
          [global options] command [command options] [arguments...]
AUTHOR:
         xieys <xieys_1993l@163.com>
COMMANDS:
    help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
  --help, -h  show help

通过覆盖HelpPrinter,只输出自己定制的信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
	"fmt"
	"github.com/urfave/cli"
	"io"
	"os"
)

func main(){

	cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) {
		fmt.Println("Simple Help!")
	}
	(&cli.App{}).Run(os.Args)
}

运行

1
2
3
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
Simple Help!

内置选项

帮助选项

--help/-hcli.HelpFlag
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
	"github.com/urfave/cli/v2"
	"os"
)

func main(){

	cli.HelpFlag = &cli.BoolFlag{
		Name: "heeeelp",
		Aliases: []string{"haap"},
		Usage: "help",
	}
	(&cli.App{}).Run(os.Args)
}

查看帮助

 1
 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
C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
Incorrect Usage. flag: help requested

NAME:
   main.exe - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --heeeelp, --haap  help (default: false)

C:\Users\xx\Desktop\git\mydocker1>go run main.go --haap
NAME:
   main.exe - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --heeeelp, --haap  help (default: false)

版本选项

-v/--versioncli.VersionFlag
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import (
	"github.com/urfave/cli/v2"
	"os"
)

func main(){

	cli.VersionFlag = &cli.BoolFlag{
		Name: "print-version",
		Aliases: []string{"V"},
		Usage: "print only the version",
	}
	(&cli.App{
		Name: "version",
		Version: "V1.0.0",
	}).Run(os.Args)
}

运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
C:\Users\xx\Desktop\git\mydocker1>go run main.go --print-version
version version V1.0.0

C:\Users\xx\Desktop\git\mydocker1>go run main.go --help
NAME:
   version - A new cli application

USAGE:
   main.exe [global options] command [command options] [arguments...]

VERSION:
   V1.0.0

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h           show help (default: false)
   --print-version, -V  print only the version (default: false)
   
C:\Users\xx\Desktop\git\mydocker1>go run main.go -V
version version V1.0.0
   

还可以通过设置cli.VersionPrinter字段控制版本信息的输出内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
	"fmt"
	"github.com/urfave/cli/v2"
	"os"
)


func main(){
	cli.VersionPrinter = func(c *cli.Context) {
		fmt.Printf("version = %s reversion=1",c.App.Version)
	}
	cli.VersionFlag = &cli.BoolFlag{
		Name: "print-version",
		Aliases: []string{"V"},
		Usage: "print only the version",
	}
	(&cli.App{
		Name: "version",
		Version: "V1.0.0",
	}).Run(os.Args)
}

运行

1
2
3
C:\Users\xx\Desktop\git\mydocker1>go run main.go -V
version = V1.0.0 reversion=1

除此之外,cli还支持bash自动补全功能,参考