Golang urfave/cli库简单应用示例详解

 更新时间:2023年09月07日 09:24:44   作者:EricLee  
这篇文章主要为大家介绍了Golang urfave/cli库简单应用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

通过应用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 command

GLOBAL 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 templates

USAGE:
   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库使用的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言并发编程 互斥锁详情

    Go语言并发编程 互斥锁详情

    在并发编程中,多个Goroutine访问同一块内存资源时可能会出现竞态条件,我们需要在临界区中使用适当的同步操作来以避免竞态条件。Go 语言中提供了很多同步工具,本文将介绍互斥锁Mutex和读写锁RWMutex的使用方法。
    2021-10-10
  • Go语言的type func()用法详解

    Go语言的type func()用法详解

    在Go语言中,函数的基本组成为:关键字func、函数名、参数列表、返回值、函数体和返回语句,这篇文章主要介绍了Go语言的type func()用法,需要的朋友可以参考下
    2022-03-03
  • 深入了解Golang中reflect反射的使用

    深入了解Golang中reflect反射的使用

    这篇文章主要介绍了深入了解Golang中reflect反射的使用,Go语言中的反射是一种机制,可以在运行时动态地获取类型信息和操作对象,以及调用对象的方法和属性等,需要详细了解可以参考下文
    2023-05-05
  • Golang中日志使用详解

    Golang中日志使用详解

    这篇文章记录了Golang项目中日志使用,以及结合Gin框架记录请求日志,文中通过代码示例介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-01-01
  • 深入浅出Go语言:手把手教你高效生成与解析JSON数据

    深入浅出Go语言:手把手教你高效生成与解析JSON数据

    本文将带你一步步走进Go语言的世界,教你如何高效生成与解析JSON数据,无论你是初学者还是经验丰富的开发者,都能在本文中找到实用的技巧和灵感,本文内容简洁明了,示例丰富,让你在阅读的过程中轻松掌握Go语言生成与解析JSON数据的技巧,需要的朋友可以参考下
    2024-02-02
  • Go 第三方库之类型转换问题

    Go 第三方库之类型转换问题

    今天给大家介绍一个第三方库,专门处理类型转换的问题。对Go 第三方库之类型转换问题感兴趣的朋友跟随小编一起看看吧
    2021-08-08
  • golang时间字符串和时间戳转换的案例

    golang时间字符串和时间戳转换的案例

    这篇文章主要介绍了golang时间字符串和时间戳转换的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go 文件读取和写入操作全面讲解

    Go 文件读取和写入操作全面讲解

    这篇文章主要为大家介绍了Go文件的读取和写入操作示例的全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • go语言的工作空间和GOPATH环境变量介绍

    go语言的工作空间和GOPATH环境变量介绍

    这篇文章主要介绍了go语言的工作空间和GOPATH环境变量介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • go中slice浅拷贝和深拷贝的实现

    go中slice浅拷贝和深拷贝的实现

    本文主要介绍了go中slice浅拷贝和深拷贝的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09

最新评论