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é)構。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é)構,在應用程序啟動時填充。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-04Golang中常見的三種并發(fā)控制方式使用小結(jié)
這篇文章主要為大家詳細介紹了如何對goroutine并發(fā)行為的控制,在Go中最常見的有三種方式:sync.WaitGroup、channel和Context,下面我們就來看看他們的具體使用吧2024-01-01Go語言中三種容器類型的數(shù)據(jù)結(jié)構詳解
在?Go?語言中,有三種主要的容器類型用于存儲和操作集合數(shù)據(jù)這篇文章主要為大家介紹了三者的使用與區(qū)別,感興趣的小伙伴可以跟隨小編一起學習一下2025-02-02