关于urfave/cli的使用

1,125 阅读5分钟

urfave/cli简介

urfave/cli是一个简单、快速、有趣的包,用于在Go中构建命令行应用程序

urfave/cli安装

目前普遍使用的是V2版本,在go中直接安装即可使用

$ go get github.com/urfave/cli/v2

实例讲解

  • 在命令行工具中可以参考linux中命令行帮助理解,命令行格式:command [flags] [argument1] [argument2],命令,选项,参数直接用空格隔开,flags直接以"-"连起来。
  • cli 差不多是基于 flag 来开发的哈,我们需要了解一下flag包的的使用,这里简要说明一下flag接受语法
  1. -isbool (一个 - 符号,布尔类型该写法等同于 -isbool=true)
  2. -age=x (一个 - 符号,使用等号)
  3. -age x (一个 - 符号,使用空格)
  4. --age=x (两个 - 符号,使用等号)
  5. --age x (两个 - 符号,使用空格)

1. Args的使用

1、创建一个go项目,在main.go文件中写入如下代码

package main

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

func main() {
    app := &cli.App{    //实例化app对象
        Action: func(cCtx *cli.Context) error {
            fmt.Printf("Hello %q", cCtx.Args().Get(0))   
            //cCtx.Args(),可以获取运行命令后的参数列表,是一个切片,cCtx.Args().Get(0)是获取
            //第一个位置的参数,第二个第三个以此类推
            return nil
        },
    }

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

运行命令: go run main.go zhangpl
打印:  Hello zhangpl

2、标志位(Flags)

可以使用flags进行传参,案例如下

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/urfave/cli/v2"
)

func main() {
    var language string

    app := &cli.App{
        Flags: []cli.Flag{
            &cli.StringFlag{
                Name:        "lang",
                Value:       "english",
                Usage:       "language for the greeting",
                Destination: &language,  //此处的变量只能在函数内被取到值
            },
        },
        Action: func(cCtx *cli.Context) error {
            name := "someone"
            if cCtx.NArg() > 0 {  //统计参数的个数
                name = cCtx.Args().Get(0)
            }
            if language == "spanish" {  //判定选项值,如果为spanish则走Hola分支
                fmt.Println("Hola", name)
            } else {
                fmt.Println("Hello", name)
            }
            return nil
        },
    }

    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }
}
解读代码:
通过flags设立选项,name表示选项名称,valus表示默认值,usage表示用法,
destination表示将扫描的结果绑定到language上,通过命令行可以观察。
PS E:\hsops\go_study\greet> go run greet.go -h
NAME:                                                                 
   greet.exe - A new cli application                                  
                                                                      
USAGE:                                                                
   greet.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

PS E:\hsops\go_study\greet> go run .\greet.go --lang=english zhangpl //次数--lang表示选项,zhangpl为参数,注意参数跟选项不能混淆
运行结果:Hello zhangpl

3、Aliases的使用

package main

import (
   "fmt"
   "log"
   "os"

   "github.com/urfave/cli/v2"
)

func main() {
   var language string
   app := &cli.App{
      Flags: []cli.Flag{
         &cli.StringFlag{
            Name:        "lang",
            Aliases:     []string{"l", "m"},
            Value:       "english",
            Usage:       "language for the greeting",
            Destination: &language,
         },
      },
      Action: func(c *cli.Context) error {
         name := "anyone"
         if c.NArg() > 0 {
            name = c.Args().Get(0)
         } else {
            fmt.Println("No Args")
         }
         if language == "chinese" {
            fmt.Println("Curry", name)
         } else {
            fmt.Println("James", name)
         }
         return nil
      },
   }

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

PS E:\hsops\go_study\greet> go run .\greet.go -h
NAME:
   greet.exe - A new cli application                                               
                                                                                   
USAGE:                                                                             
   greet.exe [global options] command [command options] [arguments...]             
                                                                                   
COMMANDS:                                                                          
   help, h  Shows a list of commands or help for one command                       
                                                                                   
GLOBAL OPTIONS:                                                                    
   --lang value, -l value, -m value  language for the greeting (default: "english")
   --help, -h                        show help  
   
从上面可以看出options中多了-l和-m,分别使用两个不同的选项进行定义
PS E:\hsops\go_study\greet> go run .\greet.go --m chinese
No Args
Curry anyone
PS E:\hsops\go_study\greet> go run .\greet.go --lang english
No Args
James anyone
可以发现结果一致

4、如果是使用多个命令,则可以使用Commands,

package main

import (
   "fmt"
   "log"
   "os"
   "sort"

   "github.com/urfave/cli/v2"
)

func main() {
   app := &cli.App{
      Commands: []*cli.Command{
         {
            Name:    "sex",
            Aliases: []string{"s"},
            Usage:   "你可以通过我来获取性别",
            Action: func(c *cli.Context) error {
               fmt.Println("难人")
               return nil
            },
         },
         {
            Name:    "age",
            Aliases: []string{"a"},
            Usage:   "你可以通过我来获取年龄",
            Action: func(c *cli.Context) error {
               fmt.Println("100岁了")
               return nil
            },
         },
      },
   }

   sort.Sort(cli.CommandsByName(app.Commands)) // 通过命令函数来排序,在help中进行展示

   err := app.Run(os.Args)
   if err != nil {
      log.Fatal(err)
   }
}
代码解析:
PS E:\hsops\go_study\greet> go run .\greet.go -h
NAME:
   greet.exe - A new cli application

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

COMMANDS:
   age, a   你可以通过我来获取年龄
   sex, s   你可以通过我来获取性别
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help

通过执行不同的命令获取不同的结果
PS E:\hsops\go_study\greet> go run .\greet.go age
100岁了

5、Subcommands 子命令

package main

import (
   "fmt"
   "log"
   "os"

   "github.com/urfave/cli/v2"
)

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

代码解析:
任何命令行首先通过--help或者-h进行查看

PS E:\hsops\go_study\greet> go run .\greet.go -h
NAME:
   greet.exe - A new cli application                                  
                                                                      
USAGE:                                                                
   greet.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  options for task templates
   help, h      Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help
从COMMANDS中可以看出来共有add,complete,template三个command,且template有add,remove两个子命令,templete跟add可以理解为包含关系,可以通过下述命令进行查看
PS E:\hsops\go_study\greet> go run .\greet.go template -h
NAME:
   greet.exe template - options for task templates            
                                                              
USAGE:                                                        
   greet.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
从COMMANDS中可以看到template两个子命令,add和remove

命令行可以用:
PS E:\hsops\go_study\greet> go run .\greet.go add
added task:
PS E:\hsops\go_study\greet> go run .\greet.go template add
new task template: 

6、Subcommands categories使用,子命令类别主要是将子命令进行归类,在使用中可以参考如下代码

package main

import (
   "fmt"
   "log"
   "os"

   "github.com/urfave/cli/v2"
)

func main() {
   app := &cli.App{
      Commands: []*cli.Command{
         {
            Name:  "noop",
            Usage: "complete a task on the list",
            Action: func(cCtx *cli.Context) error {
               fmt.Println("noop task: ", cCtx.Args().First())
               return nil
            },
         },
         {
            Name:     "add",
            Category: "template",
            Usage:    "complete a task on the list",
            Action: func(cCtx *cli.Context) error {
               fmt.Println("completed add task: ", cCtx.Args().First())
               return nil
            },
         },
         {
            Name:     "remove",
            Category: "template",
            Usage:    "complete a task on the list",
            Action: func(cCtx *cli.Context) error {
               fmt.Println("completed remove task: ", cCtx.Args().First())
               return nil
            },
         },
      },
   }

   if err := app.Run(os.Args); err != nil {
      log.Fatal(err)
   }
}
代码解析:
PS E:\hsops\go_study\greet> go run .\greet.go -h
   greet.exe - A new cli application

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

COMMANDS:
   noop     complete a task on the list
   help, h  Shows a list of commands or help for one command
   template:
     add     complete a task on the list
     remove  complete a task on the list

GLOBAL OPTIONS:
   --help, -h  show help
PS E:\hsops\go_study\greet> go run .\greet.go add
completed add task:
PS E:\hsops\go_study\greet> go run .\greet.go remove
completed remove task:
PS E:\hsops\go_study\greet> go run .\greet.go noop  
noop task:  

通过go run greet.go可以知道不同的命令在不同的分类中,但是具体使用情况没有区别