天天看點

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)