Golang?urfave/cli庫簡單應用示例詳解
引言
通過應用cli庫可以在程序中像執(zhí)行cmd命令一樣運行可執(zhí)行文件,同時也可以通過--help執(zhí)行的幫助說明。
最簡單的應用
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)
}
}上面代碼編譯后,會生成對應的可執(zhí)行文件(Name與App的參數(shù)Name并沒有強制關聯(lián),但最好保持一致)。在無參數(shù)執(zhí)行可執(zhí)行文件時,會執(zhí)行對應app的Action。上述代碼就會打印出Hello friend
cli最主要的幾個參數(shù)是:Arguments、Flag、Command。這三個就像linux命令(或cmd命令)一樣,給同一個應用程序通過傳入不同的參數(shù)來執(zhí)行不同的邏輯。
Args
app := &cli.App{
Action: func(cCtx *cli.Context) error {
fmt.Printf("Hello %q", cCtx.Args().Get(0))
return nil
},
}通過cCTX.Args().Get(參數(shù)索引)獲取具體的參數(shù)。
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)
}
}對于上述代碼執(zhí)行編譯和安裝(之后的代碼修改后都需要重新執(zhí)行,后面省略此步驟,"cliTest/greet"為項目目錄,細節(jié)自查go install命令的使用)
go install cliTest/greet
上述文件執(zhí)行完成之后會生成可執(zhí)行文件(windows注意文件所在目錄加入到環(huán)境變量path中)
執(zhí)行 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
可以看到內(nèi)容主要包含:
NAME:應用名字及說明
USAGE:應用的用法及格式
COMMANDS:當前應用支持的命令(目前只有help)
GLOBAL OPTIONS: 當前應用支持的可選參數(shù)
執(zhí)行greet --lang spanish eric ,輸出Hola eric,因為通過--lang選項我們設置了語言為spanish,在后面的執(zhí)行中同樣根據(jù)lang選項執(zhí)行了不同的邏輯。
執(zhí)行greet --lang english eric 和greet eric,都輸出了Hello eric,這是因為在lang定義的時候設置了默認值Value:"english"。
Flag中各個參數(shù)的含義
Name(string): 選項的名稱,通常由一個或多個字符組成,可以在命令行中使用來指定該選項。Aliases([]string): 選項的別名或替代名稱列表。這些是可選的,用于提供更多的方法來指定相同的選項。Usage(string): 選項的簡短描述,用于幫助消息和命令行幫助文檔中解釋選項的用途。Value(Value): 表示選項的值的接口類型。這通常是一個指向變量的指針,用于存儲選項的值。DefValue(string): 選項的默認值,以字符串形式表示。如果用戶沒有提供選項的值,將使用此默認值。EnvVar(string): 選項的環(huán)境變量名。如果設置,可以通過環(huán)境變量來提供選項的值。FilePath(string): 選項值表示文件路徑時,用于將相對路徑解釋為絕對路徑的基本路徑。Required(bool): 如果為 true,表示選項是必需的,用戶必須提供一個值。否則,它是可選的。Hidden(bool): 如果為 true,表示選項在幫助消息中不可見,通常用于隱藏高級或不常用的選項。NoOptDefVal(bool): 如果為 true,表示選項的默認值不會在幫助消息中顯示,用于隱藏默認值。HasBeenSet(bool): 用于表示用戶是否為該選項提供了值。通常在命令執(zhí)行時檢查此字段。PlaceHolder(string): 用于在幫助消息中指定選項值的占位符,以幫助用戶理解如何提供值。Category(string): 用于將選項分組到特定的類別,以便更好地組織和顯示幫助消息。HasBeenSetExplicitly(bool): 用于表示用戶是否顯式設置了選項的值,以便區(qū)分用戶提供的值和默認值。CustomStringVar(cli.CustomStringVar): 用于提供自定義的字符串值處理函數(shù),用于處理選項的字符串值。
常用的Flag類型
cli.StringFlag:用于接收字符串值的選項。例如:
goCopy code
cli.StringFlag{
Name: "config, c",
Usage: "Load configuration from `FILE`",
}cli.IntFlag:用于接收整數(shù)值的選項。例如:
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:用于接收浮點數(shù)值的選項。例如:
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:用于自定義類型的選項,需要實現(xiàn) cli.Generic 接口??梢杂糜谔幚矸菢藴蔬x項類型。例如:
goCopy code
cli.GenericFlag{
Name: "myflag",
Value: &MyCustomType{}, // MyCustomType 需要實現(xiàn) cli.Generic 接口
Usage: "Custom flag",
}這些是一些常見的 cli.Flag 類型,您可以根據(jù)需要選擇適當?shù)念愋蛠矶x您的命令行選項。不同的類型允許您接受不同類型的值,并提供了相應的方法來解析和處理這些值。您還可以創(chuàng)建自定義的 cli.Flag 類型來處理特定需求。Flag的類型有很多,具體的參考cli官方文檔
Command
像上面的代碼,我們本身只存在一個App,同時執(zhí)行此app會執(zhí)行器Action方法,如果希望一個App中可以定義多個Action方法,可以引入Command。同時Command還支持定義SubCommand,可以對功能進行更細化的區(qū)分。
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之前調(diào)用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中各個參數(shù)的作用
Name(字符串):命令的名稱。用于從命令行中調(diào)用該命令。Aliases([]字符串):命令的別名或替代名稱列表??梢杂米髡{(diào)用相同命令的替代方式。Usage(字符串):命令的簡短描述,用于說明命令的用途或功能。通常在命令行幫助消息中顯示。UsageText(字符串):在幫助消息的 USAGE 部分顯示的自定義文本??稍诖颂幪峁╊~外的使用說明。Description(字符串):命令如何工作的詳細解釋。提供了有關命令功能的更詳細信息。ArgsUsage(字符串):對該命令預期的參數(shù)的簡要描述。幫助用戶了解應該提供哪些參數(shù)。Category(字符串):命令所屬的類別??捎糜诮M織和分組相關命令。BashComplete(BashCompleteFunc):用于檢查 bash 命令完成時調(diào)用的函數(shù)。用于命令行自動完成。Before(BeforeFunc):在運行任何子命令之前但在上下文準備好后執(zhí)行的操作。如果返回非 nil 錯誤,則不運行任何子命令。After(AfterFunc):在運行任何子命令之后但子命令完成后執(zhí)行的操作。即使Action()恐慌,也會運行它。Action(ActionFunc):在調(diào)用該命令時要調(diào)用的主要函數(shù)。在這里定義命令的行為。OnUsageError(OnUsageErrorFunc):如果發(fā)生使用錯誤(如不正確的命令行參數(shù)或標志),則執(zhí)行此函數(shù)。Subcommands([]*Command):子命令的列表。您可以在父命令下創(chuàng)建子命令的層次結(jié)構(gòu)。Flags([]Flag):要解析的標志列表。標志用于傳遞選項和參數(shù)給命令。SkipFlagParsing(布爾):如果為 true,則將所有標志視為普通參數(shù)。可用于禁用特定命令的自動標志解析。HideHelp(布爾):如果為 true,則隱藏內(nèi)置的幫助命令和幫助標志。HideHelpCommand(布爾):如果為 true,則隱藏內(nèi)置的幫助命令,但保留幫助標志。如果HideHelp為 true,則忽略此選項。Hidden(布爾):如果為 true,則從幫助或完成中隱藏該命令。這使得該命令在幫助消息中不可見。UseShortOptionHandling(布爾):如果為 true,則啟用短選項處理,使用戶能夠?qū)⒍鄠€單字符布爾參數(shù)組合成一個參數(shù)(例如,-ov)。HelpName(字符串):用于幫助的命令的全名。默認為完整命令名稱,包括父命令。CustomHelpTemplate(字符串):命令的幫助主題的文本模板。您可以通過設置此變量來提供自定義幫助文本。categories(CommandCategories):包含已分類命令的結(jié)構(gòu),在應用程序啟動時填充。isRoot(布爾):指示是否為根 "特殊" 命令。separator(separatorSpec):用于分隔參數(shù)的分隔符配置。
以上就是Golang urfave/cli庫簡單應用示例詳解的詳細內(nèi)容,更多關于Golang urfave/cli庫使用的資料請關注腳本之家其它相關文章!
相關文章
Golang?Gin解析JSON請求數(shù)據(jù)避免出現(xiàn)EOF錯誤
這篇文章主要為大家介紹了Golang?Gin?優(yōu)雅地解析JSON請求數(shù)據(jù),避免ShouldBindBodyWith出現(xiàn)EOF錯誤的源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
Golang中常見的三種并發(fā)控制方式使用小結(jié)
這篇文章主要為大家詳細介紹了如何對goroutine并發(fā)行為的控制,在Go中最常見的有三種方式:sync.WaitGroup、channel和Context,下面我們就來看看他們的具體使用吧2024-01-01
Go語言中三種容器類型的數(shù)據(jù)結(jié)構(gòu)詳解
在?Go?語言中,有三種主要的容器類型用于存儲和操作集合數(shù)據(jù)這篇文章主要為大家介紹了三者的使用與區(qū)別,感興趣的小伙伴可以跟隨小編一起學習一下2025-02-02

