Golang urfave/cli库简单应用示例详解
作者:EricLee
引言
通过应用cli库可以在程序中像执行cmd命令一样运行可执行文件,同时也可以通过--help
执行的帮助说明。
最简单的应用
package main import ( "fmt" "log" "os" "github.com/urfave/cli/v2" ) func main() { app := &cli.App{ Name: "greet", Usage: "fight the loneliness!", Action: func(*cli.Context) error { fmt.Println("Hello friend!") return nil }, } if err := app.Run(os.Args); err != nil { log.Fatal(err) } }
上面代码编译后,会生成对应的可执行文件(Name与App的参数Name并没有强制关联,但最好保持一致)。在无参数执行可执行文件时,会执行对应app的Action。上述代码就会打印出Hello friend
cli最主要的几个参数是:Arguments、Flag、Command。这三个就像linux命令(或cmd命令)一样,给同一个应用程序通过传入不同的参数来执行不同的逻辑。
Args
app := &cli.App{ Action: func(cCtx *cli.Context) error { fmt.Printf("Hello %q", cCtx.Args().Get(0)) return nil }, }
通过cCTX.Args().Get(参数索引)
获取具体的参数。
Flag
package main import ( "fmt" "log" "os" "github.com/urfave/cli/v2" ) func main() { app := &cli.App{ Flags: []cli.Flag{ &cli.StringFlag{ Name: "lang", Value: "english", Usage: "language for the greeting", }, }, Action: func(cCtx *cli.Context) error { name := "Nefertiti" if cCtx.NArg() > 0 { name = cCtx.Args().Get(0) } if cCtx.String("lang") == "spanish" { fmt.Println("Hola", name) } else { fmt.Println("Hello", name) } return nil }, } if err := app.Run(os.Args); err != nil { log.Fatal(err) } }
对于上述代码执行编译和安装(之后的代码修改后都需要重新执行,后面省略此步骤,"cliTest/greet"为项目目录,细节自查go install命令的使用)
go install cliTest/greet
上述文件执行完成之后会生成可执行文件(windows注意文件所在目录加入到环境变量path中)
执行 greet --help
显示如下:
NAME:
greet - A new cli application
USAGE:
greet [global options] command [command options] [arguments...]
COMMANDS:
help, h Shows a list of commands or help for one commandGLOBAL OPTIONS:
--lang value language for the greeting (default: "english")
--help, -h show help
可以看到内容主要包含:
NAME
:应用名字及说明
USAGE
:应用的用法及格式
COMMANDS
:当前应用支持的命令(目前只有help)
GLOBAL OPTIONS
: 当前应用支持的可选参数
执行greet --lang spanish eric
,输出Hola eric
,因为通过--lang
选项我们设置了语言为spanish,在后面的执行中同样根据lang
选项执行了不同的逻辑。
执行greet --lang english eric
和greet eric
,都输出了Hello eric
,这是因为在lang定义的时候设置了默认值Value:"english"
。
Flag中各个参数的含义
Name
(string): 选项的名称,通常由一个或多个字符组成,可以在命令行中使用来指定该选项。Aliases
([]string): 选项的别名或替代名称列表。这些是可选的,用于提供更多的方法来指定相同的选项。Usage
(string): 选项的简短描述,用于帮助消息和命令行帮助文档中解释选项的用途。Value
(Value): 表示选项的值的接口类型。这通常是一个指向变量的指针,用于存储选项的值。DefValue
(string): 选项的默认值,以字符串形式表示。如果用户没有提供选项的值,将使用此默认值。EnvVar
(string): 选项的环境变量名。如果设置,可以通过环境变量来提供选项的值。FilePath
(string): 选项值表示文件路径时,用于将相对路径解释为绝对路径的基本路径。Required
(bool): 如果为 true,表示选项是必需的,用户必须提供一个值。否则,它是可选的。Hidden
(bool): 如果为 true,表示选项在帮助消息中不可见,通常用于隐藏高级或不常用的选项。NoOptDefVal
(bool): 如果为 true,表示选项的默认值不会在帮助消息中显示,用于隐藏默认值。HasBeenSet
(bool): 用于表示用户是否为该选项提供了值。通常在命令执行时检查此字段。PlaceHolder
(string): 用于在帮助消息中指定选项值的占位符,以帮助用户理解如何提供值。Category
(string): 用于将选项分组到特定的类别,以便更好地组织和显示帮助消息。HasBeenSetExplicitly
(bool): 用于表示用户是否显式设置了选项的值,以便区分用户提供的值和默认值。CustomStringVar
(cli.CustomStringVar): 用于提供自定义的字符串值处理函数,用于处理选项的字符串值。
常用的Flag类型
cli.StringFlag:用于接收字符串值的选项。例如:
goCopy code cli.StringFlag{ Name: "config, c", Usage: "Load configuration from `FILE`", }
cli.IntFlag:用于接收整数值的选项。例如:
goCopy code cli.IntFlag{ Name: "port, p", Usage: "Listen on `PORT`", }
cli.BoolFlag:用于接收布尔值(true 或 false)的选项。通常用于标识性选项。例如:
goCopy code cli.BoolFlag{ Name: "verbose, v", Usage: "Enable verbose mode", }
cli.Float64Flag:用于接收浮点数值的选项。例如:
goCopy code cli.Float64Flag{ Name: "threshold, t", Usage: "Set the threshold value", }
cli.StringSliceFlag:用于接收多个字符串值的选项,返回一个字符串切片。例如:
goCopy code cli.StringSliceFlag{ Name: "tags", Usage: "Add one or more tags", }
cli.GenericFlag:用于自定义类型的选项,需要实现 cli.Generic
接口。可以用于处理非标准选项类型。例如:
goCopy code cli.GenericFlag{ Name: "myflag", Value: &MyCustomType{}, // MyCustomType 需要实现 cli.Generic 接口 Usage: "Custom flag", }
这些是一些常见的 cli.Flag
类型,您可以根据需要选择适当的类型来定义您的命令行选项。不同的类型允许您接受不同类型的值,并提供了相应的方法来解析和处理这些值。您还可以创建自定义的 cli.Flag
类型来处理特定需求。Flag的类型有很多,具体的参考cli官方文档
Command
像上面的代码,我们本身只存在一个App,同时执行此app会执行器Action方法,如果希望一个App中可以定义多个Action方法,可以引入Command。同时Command还支持定义SubCommand,可以对功能进行更细化的区分。
app := &cli.App{ Commands: []*cli.Command{ { Name: "add", Aliases: []string{"a"}, Usage: "add a task to the list", Action: func(cCtx *cli.Context) error { fmt.Println("added task: ", cCtx.Args().First()) return nil }, }, { Name: "complete", Aliases: []string{"c"}, Usage: "complete a task on the list", Action: func(cCtx *cli.Context) error { fmt.Println("completed task: ", cCtx.Args().First()) return nil }, }, { Name: "template", Aliases: []string{"t"}, Usage: "options for task templates", Subcommands: []*cli.Command{ { Name: "add", Usage: "add a new template", Action: func(cCtx *cli.Context) error { fmt.Println("new task template: ", cCtx.Args().First()) return nil }, }, { Name: "remove", Usage: "remove an existing template", Action: func(cCtx *cli.Context) error { fmt.Println("removed task template: ", cCtx.Args().First()) return nil }, }, }, }, }, } if err := app.Run(os.Args); err != nil { log.Fatal(err) }
greet --help
显示:
COMMANDS:
add, a add a task to the list
complete, c complete a task on the list
template, t options for task templates
help, h Shows a list of commands or help for one command
可以看到当前包含的所有命令。但并没有显示template
命令的子命令,我们可以通过greet template --help
查看template命令的帮助文档
NAME:
greet template - options for task templatesUSAGE:
greet 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
命令的排序
通过在代码中app.Run之前调用sort.Sort(cli.CommandsByName(app.Commands))
可以对命令按名字排序。
命令的分类
同级的命令中可以通过增加Category
对命令进行分类(同类命令在展示时会再一个类下显示)。
例如:
Commands: []*cli.Command{ { Name: "add", Aliases: []string{"a"}, Category: "C1", Usage: "add a task to the list", Action: func(cCtx *cli.Context) error { fmt.Println("added task: ", cCtx.Args().First()) return nil }, }, { Name: "complete", Aliases: []string{"c"}, Category: "C1", Usage: "complete a task on the list", Action: func(cCtx *cli.Context) error { fmt.Println("completed task: ", cCtx.Args().First()) return nil }, },
--help
显示
COMMANDS:
template, t options for task templates
help, h Shows a list of commands or help for one command
C1:
add, a add a task to the list
complete, c complete a task on the list
Comand中各个参数的作用
Name
(字符串):命令的名称。用于从命令行中调用该命令。Aliases
([]字符串):命令的别名或替代名称列表。可以用作调用相同命令的替代方式。Usage
(字符串):命令的简短描述,用于说明命令的用途或功能。通常在命令行帮助消息中显示。UsageText
(字符串):在帮助消息的 USAGE 部分显示的自定义文本。可在此处提供额外的使用说明。Description
(字符串):命令如何工作的详细解释。提供了有关命令功能的更详细信息。ArgsUsage
(字符串):对该命令预期的参数的简要描述。帮助用户了解应该提供哪些参数。Category
(字符串):命令所属的类别。可用于组织和分组相关命令。BashComplete
(BashCompleteFunc):用于检查 bash 命令完成时调用的函数。用于命令行自动完成。Before
(BeforeFunc):在运行任何子命令之前但在上下文准备好后执行的操作。如果返回非 nil 错误,则不运行任何子命令。After
(AfterFunc):在运行任何子命令之后但子命令完成后执行的操作。即使Action()
恐慌,也会运行它。Action
(ActionFunc):在调用该命令时要调用的主要函数。在这里定义命令的行为。OnUsageError
(OnUsageErrorFunc):如果发生使用错误(如不正确的命令行参数或标志),则执行此函数。Subcommands
([]*Command):子命令的列表。您可以在父命令下创建子命令的层次结构。Flags
([]Flag):要解析的标志列表。标志用于传递选项和参数给命令。SkipFlagParsing
(布尔):如果为 true,则将所有标志视为普通参数。可用于禁用特定命令的自动标志解析。HideHelp
(布尔):如果为 true,则隐藏内置的帮助命令和帮助标志。HideHelpCommand
(布尔):如果为 true,则隐藏内置的帮助命令,但保留帮助标志。如果HideHelp
为 true,则忽略此选项。Hidden
(布尔):如果为 true,则从帮助或完成中隐藏该命令。这使得该命令在帮助消息中不可见。UseShortOptionHandling
(布尔):如果为 true,则启用短选项处理,使用户能够将多个单字符布尔参数组合成一个参数(例如,-ov
)。HelpName
(字符串):用于帮助的命令的全名。默认为完整命令名称,包括父命令。CustomHelpTemplate
(字符串):命令的帮助主题的文本模板。您可以通过设置此变量来提供自定义帮助文本。categories
(CommandCategories):包含已分类命令的结构,在应用程序启动时填充。isRoot
(布尔):指示是否为根 "特殊" 命令。separator
(separatorSpec):用于分隔参数的分隔符配置。
以上就是Golang urfave/cli库简单应用示例详解的详细内容,更多关于Golang urfave/cli库使用的资料请关注脚本之家其它相关文章!