天天看点

cli构建应用命令——urfave

作者:寒笛过霜天

cli是一个简单,快速且有趣的软件包,用于在Go中构建命令行应用程序。目的是使开发人员能够以表达方式编写快速且可分发的命令行应用程序。

github地址:

https://github.com/urfave/cli           

Star 16.9k

使用v2发行版

> # go get github.com/urfave/cli/v2           

文档:

https://github.com/urfave/cli/blob/master/docs/v2/manual.md

...
import(
"github.com/urfave/cli/v2" //导入为包"cli"
)
...           

实例1:

package main
import (
"os"
"github.com/urfave/cli/v2"
)
func main() {
(&cli.App{}).Run(os.Args)
}           

执行方式1:

> # go run main.go
NAME:
cli - A new cli application
USAGE:
cli [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 (default: false)           

执行方式2:

> # go mod init cli
> # go build
> # cli
NAME:
cli - A new cli application
USAGE:
cli [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 (default: false)           

执行方式3:

> # go install
> # cli
NAME:
cli - A new cli application
USAGE:
cli [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 (default: false)           

实例2:

package main
import (
    "fmt"
    "log"
    "os"
    "github.com/urfave/cli/v2"
)
func main() {
    app := &cli.App{
        Name: "boom",
        Usage: "make an explosive entrance",
        Action: func(c *cli.Context) error {
            fmt.Println("boom! I say!")
            return nil
        },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
}           

执行方式1:

> # go run main.go
boom! I say!           
> # go run main.go --help
NAME:
cli - A new cli application
USAGE:
cli [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 (default: false)           

执行方式2:

> # go mod init cli
> # go build
> # cli
boom! I say!           
> # cli --help
NAME:
cli - A new cli application
USAGE:
cli [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 (default: false)           

执行方式3:

安装命令到 $GOPATH/bin 目录下:

> # go install
> # cli
boom! I say!           

实例3:

首先创建一个名为的目录greet, 然后在其中添加文件, 并在其中添加 greet.go以下代码:

greet.go

package main
import (
    "fmt"
    "log"
    "os"
    "github.com/urfave/cli/v2"
)
func main() {
    app := &cli.App{
    Name: "greet",
    Usage: "fight the loneliness!",
    Action: func(c *cli.Context) error {
        fmt.Println("Hello friend!")
        return nil
    },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
}           
> # go mod init greet //这里不需要 main.go 入口文件
> # go install //安装命令到 $GOPATH/bin 目录下
> # go env GOPATH
/root/go
> # /root/go/bin/greet
Hello friend!           

下面演示编译形成的二进制文件的名称和路径的展示:

> # cd /home/greet/
> # mv greet.go main.go
> # go build
> # ls
go.mod go.sum greet main.go           
> # go build -o main
> # ls
go.mod go.sum greet main main.go
> # ./main
Hello friend!           

查看帮助信息

> # ./greet --help
NAME:
greet - fight the loneliness!
USAGE:
greet [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 (default: false)
> # go install
> # ls
go.mod go.sum main main.go           

注意:

1 go install 安装的命令文件名称由 go mod init [module] 初始化模块的名称 [module] 决定, 安装命令存放到到 $GOPATH/bin 目录下;

2 go build 默认由 go mod init [module] 初始化模块的名称 [module] 决定, 默认存放到当前目录下, 但可以通过 -o 改写命令文件的路径和名称;

3 Name 和 Usage 用于展示帮助的信息, 不能用于指定编译后的命令文件的名称;

4 go install 会自动清除go build 编译的目录文件, 除 go build -o 方式之外;

5 编译时一个目录下只能有一个 package main 定义的包名; 否则会报: main redeclared in this block previous declaration 错误信息;

实例4: 获取参数

package main
import (
"fmt"
"log"
"os"
"github.com/urfave/cli/v2"
)
func main() {
    app := &cli.App{
    Action: func(c *cli.Context) error {
            fmt.Printf("Hello %q", c.Args().Get(0)) // 获取第一个参数
            return nil
        },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
}           
> # go build
> # ./greet xukaikai
Hello "xukaikai"           

实例4: Flags

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(c *cli.Context) error {
    name := "Nefertiti"
    if c.NArg() > 0 {
        name = c.Args().Get(0)
    }
    if c.String("lang") == "spanish" {
        fmt.Println("Hola", name)
    } else {
        fmt.Println("Hello", name)
    }
    return nil
    },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
}           
> # go build
> # greet
Hello Nefertiti
> # greet --lang spanish
Hola Nefertiti           

实例5:

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(c *cli.Context) error {
    name := "someone"
    if c.NArg() > 0 {
        name = c.Args().Get(0)
    }
    if language == "spanish" {
        fmt.Println("Hola", name)
    } else {
        fmt.Println("Hello", name)
    }
    return nil
    },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
}           

实例6: 使用别名

package main
import (
    "log"
    "os"
    "github.com/urfave/cli/v2"
)
func main() {
    app := &cli.App{
          Flags: []cli.Flag{
                &cli.StringFlag{
                Name: "config",
                Aliases: []string{"c"}, // 设置别名
                Usage: "Load configuration from `FILE`",
            },
        },
    }
    err := app.Run(os.Args)
    if err != nil {
    log.Fatal(err)
    }
}           
> # greet --help
NAME:
cli - A new cli application
USAGE:
cli [global options] command [command options] [arguments...]
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--config FILE, -c FILE Load configuration from FILE
--help, -h show help (default: false)           

实例7: 多重命令

package main
import (
    "fmt"
    "log"
    "os"
    "github.com/urfave/cli/v2"
)
func main() {
    app := cli.NewApp()
    app.EnableBashCompletion = true
    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: "options 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("removed task template: ", c.Args().First())
        return nil
    },
    },
    },
    },
    }
    err := app.Run(os.Args)
    if err != nil {
    log.Fatal(err)
    }
}           

> # go build

> # ./greet add 3 5

added task: 3

实例8: 显示版本号

package main
import (
    "fmt"
    "os"
    "github.com/urfave/cli/v2"
)
var (
    Revision = "fafafaf"
)
func main() {
    cli.VersionPrinter = func(c *cli.Context) {
        fmt.Printf("version=%s revision=%s\n", c.App.Version, Revision)
    }
    app := &cli.App{
        Name: "partay",
        Version: "v19.99.0",
    }
    app.Run(os.Args)
}           
> # go build
> # ./greet --verion
version=v19.99.0 revision=fafafaf           

实例:使用模板

package main
import (
    "fmt"
    "log"
    "os"
    "github.com/urfave/cli/v2"
)
func main() {
    app := &cli.App{
    Flags: []cli.Flag{
    &cli.TimestampFlag{Name: "meeting", Layout: "2006-01-02T15:04:05"},
    },
    Action: func(c *cli.Context) error {
        fmt.Printf("%s", c.Timestamp("meeting").String())
        return nil
    },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
}           
> # go build
> # ./greet --meeting 2019-08-12T15:04:05
2019-08-12 15:04:05 +0000 UTC           

实例:

main.go

package main
import (
    "fmt"
    "log"
    "os"
    "github.com/urfave/cli/v2"
)
var (
    Revision = "mainnet"
)
func main() {
    // 添加版本号
    cli.VersionPrinter = func(c *cli.Context) {
    fmt.Printf("version=%s revision=%s\n", c.App.Version, Revision)
    }
    app := &cli.App{
    Name: "version",
    Version: "v1.0.0",
    }
    // 此设置将允许应用程序的子命令自动完成
    app.EnableBashCompletion = true
    // 多重命令和子命令
    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: "options 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("removed task template: ", c.Args().First())
            return nil
        },
    },
    },
    },
    }
    err := app.Run(os.Args)
    if err != nil {
        log.Fatal(err)
    }
    }           
> # go build -o cli main.go
> # ./cli
NAME:
version - A new cli application
USAGE:
cli [global options] command [command options] [arguments...]
VERSION:
v1.0.0
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 (default: false)
--version, -v print the version (default: false)