大家好过牙,我是謝偉甥厦,是一名程序員。
過去一陣子寇钉,我在開發(fā)一款客戶端命令行工具刀疙,業(yè)余時間,開始寫了下面這個工具扫倡。僅做學習參考使用∏恚現(xiàn)在它看上去不夠優(yōu)雅,命令的命名也沒有好好推敲撵溃。但功能都已實現(xiàn)油够。
即如何構(gòu)建一個命令行工具,希望通過這個項目的示例征懈,你能開發(fā)出各種各樣符合你需求的命令行工具。
比如 github 上非常熱門的命令行項目:
- annie 下載視頻和圖片工具
- hub 一個包裝git 操作github 的工具
- jfrog-cli-go 一個倉庫管理平臺的客戶端
...
開始之前揩悄,還是看幾個命令行工具一般是啥樣的:
beego: 命令行工具bee
λ bee
Bee is a Fast and Flexible tool for managing your Beego Web Application.
USAGE
bee command [arguments]
AVAILABLE COMMANDS
version Prints the current Bee version
migrate Runs database migrations
api Creates a Beego API application
bale Transforms non-Go files to Go source files
fix Fixes your application by making it compatible with newer versions of Beego
dlv Start a debugging session using Delve
dockerize Generates a Dockerfile for your Beego application
generate Source code generator
hprose Creates an RPC application based on Hprose and Beego frameworks
new Creates a Beego application
pack Compresses a Beego application into a single file
rs Run customized scripts
run Run the application by starting a local development server
server serving static content over HTTP on port
Use bee help [command] for more information about a command.
ADDITIONAL HELP TOPICS
Use bee help [topic] for more information about that topic.
思考一個問題:一個好的命令行應該具備什么卖哎?
- 完善的幫助命令
- 優(yōu)雅的輸出格式
- 支持長、短參數(shù)
- 命令補全
- 支持表格輸出
等等
實質(zhì):客戶端命令行工具的實質(zhì)是 接口或者API 的封裝删性。
1亏娜、如何解析命令行參數(shù)
- os.Args
- Flag
- cli
1. os.Args:
第一個參數(shù)是: 文件名稱,之外的參數(shù)是命令行接收的參數(shù)
對參數(shù)進行處理即可實現(xiàn)解析命令行參數(shù)蹬挺。
args = os.Args
oneArg = args[1]
TwoArg = args[2]
func add() int {
number_one, _ := strconv.Atoi(args[2])
number_two, _ := strconv.Atoi(args[3])
return number_one + number_two
}
2. Flag
Flag golang 系統(tǒng)自帶的庫能更好的處理命令行參數(shù):
var operation string
var numberone float64
var numbertwo float64
flag.StringVar(&operation, "o", "add", "operation for this tool")
flag.Float64Var(&numberone, "n1", 0, "The first number")
flag.Float64Var(&numbertwo, "n2", 0, "The second number")
定義三個參數(shù)维贺,分別為string、float巴帮、float 類型
3. cli
這是一個第三方庫溯泣,是一個命令參數(shù)解析的框架,能夠很好的快速形成命令行榕茧。
主要包括:
- app 主要實現(xiàn)的是整體的命令行工具動作
- command 對命令的處理
- flag 對短參數(shù)的處理
- help 使用 template 模板實現(xiàn)命令的幫助提示
2垃沦、如何組織項目
- commands : 命令集合
- domain: http 請求處理
- main: 程序入口
- objects: 定義結(jié)構(gòu)體
- reader : 命令清單入口
- utils: 程序幫助程序入口
3、如何組織命令
第一級命令集合
func Commands() []cli.Command {
return []cli.Command{
{
Name: "book",
Usage: douban.BookUsage,
Subcommands: douban.SubBookCommand(),
},
{
Name: "story",
Usage: one.StoryUsage,
Subcommands: one.SubStoryCommand(),
},
{
Name: "movie",
Usage: douban.MovieUsage,
Subcommands: douban.SubMovieCommand(),
},
}
}
第二級命令集合:
func SubBookCommand() []cli.Command {
return []cli.Command{
{
Name: "random",
Action: actionBookNumber,
},
{
Name: "detail",
Action: actionBookDetail,
},
{
Name: "search",
Flags: getFlagSearch(),
Subcommands: subCommandBookSearch(),
},
}
}
第三級命令集合:
func subCommandBookSearch() []cli.Command {
return []cli.Command{
{
Name: "query",
Action: actionQuery,
},
{
Name: "tag",
Action: actionTag,
},
}
}
組合起來即是: YiYi.exe book random | detail | search query | search tag ...
可以看出該框架對命令的組織方式很優(yōu)雅用押≈荆可以讓使用者聚焦在實現(xiàn)業(yè)務上。
4、操作步驟
- 組織命令
- 實現(xiàn)具體函數(shù)處理
這里以:YiYi.exe book search query arg
這個命令講述如何實現(xiàn)池充。
實例化APP
func main(){
app := cli.NewApp()
app.CommandNotFound = func(context *cli.Context, command string) {
fmt.Printf("[[WARNING] Not Found Command: %s\n", command)
fmt.Printf("[MESSAGE] Please Type: Reader --help")
}
app.Commands = reader.Commands()
app.Run(os.Args)
}
定義Commands
func Commands() []cli.Command {
return []cli.Command{
{
Name: "book",
Usage: douban.BookUsage,
Subcommands: douban.SubBookCommand(),
},
}
}
定義 SubCommand
func SubBookCommand() []cli.Command {
return []cli.Command{
{
Name: "search",
Flags: getFlagSearch(),
Subcommands: subCommandBookSearch(),
},
}
}
func subCommandBookSearch() []cli.Command {
return []cli.Command{
{
Name: "query",
Action: actionQuery,
},
{
Name: "tag",
Action: actionTag,
},
}
}
實現(xiàn) search query arg 命令
func actionQuery(c *cli.Context) {
if c.NArg() == 1 {
//fmt.Println(c.String("count"))
url := fmt.Sprintf(bookSearchByQuery, c.Args().Get(0), strconv.Itoa(c.Int("count")))
getBookSearch(url)
}
}
具體實現(xiàn):
結(jié)構(gòu)體 和 模板輸出
type BookAll struct {
BookCollection []BookInfo
}
type BookInfo struct {
Title string
Subtitle string
URL string
Isbn10 string
Isbn13 string
Price string
}
func (b BookAll) Template() {
t := template.New("New Template for book")
t, _ = t.Parse(`
Show Book from DouBan Api:
AllCollections:
{{range .BookCollection}}
Title: {{.Title}}
Subtitle: {{.Subtitle}}
URL: {{.URL}}
Isbn10: {{.Isbn10}}
Isbn13: {{.Isbn13}}
Price: {{.Price}}
{{end}}
`)
t.Execute(os.Stdout, b)
}
具體http 請求處理:
func getBookSearch(url string) {
var allBook []objects.BookInfo
data := utils.Response(url, "books")
for _, one := range data.Array() {
var oneBook objects.BookInfo
oneBook.Title = one.Get("title").String()
oneBook.Subtitle = one.Get("subtitle").String()
oneBook.Isbn10 = one.Get("isbn10").String()
oneBook.Isbn13 = one.Get("isbn13").String()
oneBook.URL = one.Get("url").String()
oneBook.Price = one.Get("price").String()
allBook = append(allBook, oneBook)
}
AllData := objects.BookAll{
BookCollection: allBook,
}
AllData.Template()
}
func Response(url string, key string) gjson.Result {
var newClient httpclient.HttpClient
newClient = httpclient.Implement{}
resp, err := newClient.Get(url)
//fmt.Println(url)
if err != nil {
fmt.Println("Get HTTP Response Failed")
return gjson.Result{}
}
if key == "" {
return gjson.Parse(string(resp))
} else {
return gjson.Parse(string(resp)).Get(key)
}
}
gjson 處理 是用來處理 json 的第三方庫桩引,非常好用。
上面我們使用框架收夸,一級一級實現(xiàn)下來坑匠,發(fā)現(xiàn)實際上我們只要聚焦實現(xiàn)業(yè)務:即http 請求 和 響應信息的處理即可。
5. 效果
YiYi.exe --help
YiYi is a tool for reading with DouBan and One APP api.
NAME:
YiYi - An application for book, movie, and story from DouBan and One App.
USAGE:
YiYi [global options] command [command options] [arguments...]
VERSION:
___ ___ ___ ___
/\__\ /\ \ /\__\ /\ \
|::L__L _\:\ \ |::L__L _\:\ \
|:::\__\ /\/::\__\ |:::\__\ /\/::\__\
/:;;/__/ \::/\/__/ /:;;/__/ \::/\/__/
\/__/ \:\__\ \/__/ \:\__\
\/__/ \/__/ v0.0.1
DESCRIPTION:
An application for book, movie, and story from DouBan and One App.
AUTHOR:
xieWei <wuxiaoshen@shu.edu.cn>
COMMANDS:
book get book info from DouBan API
story get story info from One API
movie get movie info from DouBan API
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
YiYi.exe book search query Golang
返回信息
Show Book from DouBan Api:
AllCollections:
Title: Cloud Native programming with Golang: Develop microservice-based high performance web apps for the cloud with Go
Subtitle: Discover practical techniques to build cloud-native apps that are scalable, reliable, and always available.
URL: https://api.douban.com/v2/book/30154908
Isbn10: 178712598X
Isbn13: 9781787125988
Price: USD 44.99
Title: Building RESTful Web services with Go: Learn how to build powerful RESTful APIs with Golang that scale gracefully
Subtitle: Explore the necessary concepts of REST API development by building few real world services from scratch.
URL: https://api.douban.com/v2/book/30154905
Isbn10: 1788294289
Isbn13: 9781788294287
Price: USD 44.99
Title: Go Standard Library Cookbook: Over 120 specific ways to make full use of the standard library components in Golang
Subtitle: Implement solutions by leveraging the power of the GO standard library and reducing dependency on external crates
URL: https://api.douban.com/v2/book/30179004
Isbn10: 1788475275
Isbn13: 9781788475273
Price: USD 49.99
Title: Go語言編程
Subtitle:
URL: https://api.douban.com/v2/book/11577300
Isbn10: 7115290369
Isbn13: 9787115290366
Price: 49.00元
Title: The Go Programming Language
Subtitle:
URL: https://api.douban.com/v2/book/26337545
Isbn10: 0134190440
Isbn13: 9780134190440
Price: USD 39.99
Title: Go Web編程
Subtitle:
URL: https://api.douban.com/v2/book/24316255
Isbn10: 7121200910
Isbn13: 9787121200915
Price: 65.00元
Title: Go語言學習筆記
Subtitle:
URL: https://api.douban.com/v2/book/26832468
Isbn10: 7121291606
Isbn13: 9787121291609
Price: 89
Title: Go 語言程序設計
Subtitle:
URL: https://api.douban.com/v2/book/24869910
Isbn10: 7115317909
Isbn13: 9787115317902
Price: CNY 69.00
Title: Go程序設計語言
Subtitle:
URL: https://api.douban.com/v2/book/27044219
Isbn10: 7111558421
Isbn13: 9787111558422
Price: 79
Title: Go并發(fā)編程實戰(zhàn)
Subtitle: Go并發(fā)編程實戰(zhàn)
URL: https://api.douban.com/v2/book/26244729
Isbn10: 7115373981
Isbn13: 9787115373984
Price: 89元
Title: Go in Action
Subtitle:
URL: https://api.douban.com/v2/book/25858023
Isbn10: 1617291781
Isbn13: 9781617291784
Price: USD 39.99
具體用法: