前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >『如何构建命令行工具:YiYi』

『如何构建命令行工具:YiYi』

作者头像
谢伟
发布2018-06-06 13:36:08
7220
发布2018-06-06 13:36:08
举报
文章被收录于专栏:GopherCoder

封面.png

大家好,我是谢伟,是一名程序员。

过去一阵子,我在开发一款客户端命令行工具,业余时间,开始写了下面这个工具。仅做学习参考使用。现在它看上去不够优雅,命令的命名也没有好好推敲。但功能都已实现。

即如何构建一个命令行工具,希望通过这个项目的示例,你能开发出各种各样符合你需求的命令行工具。

比如 github 上非常热门的命令行项目:

  • annie 下载视频和图片工具
  • hub 一个包装git 操作github 的工具
  • jfrog-cli-go 一个仓库管理平台的客户端

...

开始之前,还是看几个命令行工具一般是啥样的:

beego: 命令行工具bee

代码语言:javascript
复制
λ 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.

思考一个问题:一个好的命令行应该具备什么?

  • 完善的帮助命令
  • 优雅的输出格式
  • 支持长、短参数
  • 命令补全
  • 支持表格输出

等等

实质:客户端命令行工具的实质是 接口或者API 的封装。

1、如何解析命令行参数

  • os.Args
  • Flag
  • cli

1. os.Args:

第一个参数是: 文件名称,之外的参数是命令行接收的参数

对参数进行处理即可实现解析命令行参数。

代码语言:javascript
复制
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 系统自带的库能更好的处理命令行参数:

代码语言:javascript
复制
    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")

定义三个参数,分别为string、float、float 类型

3. cli

这是一个第三方库,是一个命令参数解析的框架,能够很好的快速形成命令行。

cli项目地址

主要包括:

  • app 主要实现的是整体的命令行工具动作
  • command 对命令的处理
  • flag 对短参数的处理
  • help 使用 template 模板实现命令的帮助提示

2、如何组织项目

  • commands : 命令集合
  • domain: http 请求处理
  • main: 程序入口
  • objects: 定义结构体
  • reader : 命令清单入口
  • utils: 程序帮助程序入口

3、如何组织命令

第一级命令集合

代码语言:javascript
复制
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(),
        },
    }
}

第二级命令集合:

代码语言:javascript
复制
func SubBookCommand() []cli.Command {
    return []cli.Command{
        {
            Name:   "random",
            Action: actionBookNumber,
        },
        {
            Name:   "detail",
            Action: actionBookDetail,
        },
        {
            Name:        "search",
            Flags:       getFlagSearch(),
            Subcommands: subCommandBookSearch(),
        },
    }
}

第三级命令集合:

代码语言:javascript
复制
func subCommandBookSearch() []cli.Command {
    return []cli.Command{
        {
            Name:   "query",
            Action: actionQuery,
        },
        {
            Name:   "tag",
            Action: actionTag,
        },
    }
}

组合起来即是: YiYi.exe book random | detail | search query | search tag ...

可以看出该框架对命令的组织方式很优雅。可以让使用者聚焦在实现业务上。

4、操作步骤

YiYi.png

  • 组织命令
  • 实现具体函数处理

这里以:YiYi.exe book search query arg 这个命令讲述如何实现。

实例化APP

代码语言:javascript
复制
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

代码语言:javascript
复制
func Commands() []cli.Command {
    return []cli.Command{
        {
            Name:        "book",
            Usage:       douban.BookUsage,
            Subcommands: douban.SubBookCommand(),
        },

    }
}

定义 SubCommand

代码语言:javascript
复制
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,
        },
    }
}

实现 search query arg 命令

代码语言:javascript
复制
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)
    }
}

具体实现:

结构体 和 模板输出

代码语言:javascript
复制
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 请求处理:

代码语言:javascript
复制
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()
}
代码语言:javascript
复制
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 的第三方库,非常好用。

上面我们使用框架,一级一级实现下来,发现实际上我们只要聚焦实现业务:即http 请求 和 响应信息的处理即可。

5. 效果

代码语言:javascript
复制
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                                              
代码语言:javascript
复制
YiYi.exe book search query Golang

返回信息

代码语言:javascript
复制
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并发编程实战
            Subtitle: Go并发编程实战
            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

具体用法:

YiYi 帮助文档

项目地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.03.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、如何解析命令行参数
  • 2、如何组织项目
  • 3、如何组织命令
  • 4、操作步骤
  • 5. 效果
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档