Golang命令行库Cobra的使用

Stella981
• 阅读 738

前言

Cobra既是用于创建强大的现代CLI应用程序的库,也是用于生成应用程序和命令文件的程序。许多使用最广泛的Go项目都是使用Cobra构建的,其中包括:
kubernetes
docker
openshift
...

一、安装Cobra
在我们安装Cobra之前,我们先解决大陆网络无法访问的问题(你懂得),否则是无法完成所有工具的安装。这里我们使用Gopm来实现,gopm是Go Package Manager 的缩写。是Golang上的包管理工具,十分好用。

1.1 gopm 安装

go get -u github.com/gpmgo/gopm

这样就将gopm完成了,在对应的$GOPATH/bin目录下即可看到;

1.2 安装Cobra

go get -g github.com/spf13/cobra/cobra
go build github.com/spf13/cobra/cobra

提示:在执行go install的时候,需要依赖golang.org/x/相关软件包,请到该处下载即可。下载之后,将该包解压到自己的$GOPATH/src目录即可;

二、Cobra相关使用

2.1 使用Cobra生产应用程序

假设现在我们要开发一个基于CLI的命令程序,名字为demo。首先打开CMD,切换到GOPATH的bin目录下,执行如下指令:

cobra init demo

在src目录下会生成一个demo的文件夹,如下:

tree src/demo
src/demo
├── LICENSE
├── cmd
│   └── root.go
└── main.go

测试cobra效果:

demo go run main.go demo
A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.

当初次创建完项目之后,即可使用项目(这里是"demo")来查看效果;

2.2 添加子命令(这里以51reboot培训内容为例)

demo cobra add unbuf
unbuf created at /Users/yangsheng/go/src/demo/cmd/unbuf.go
demo tree
.
├── LICENSE
├── cmd
│   ├── root.go
│   └── unbuf.go
└── main.go

此时目录结构变更为如上所示。现在我们来执行一下这个子命令:

go run main.go unbuf
unbuf called

2.3 完善子命令功能

创建unbuf代码程序

mkdir unbuf

在该目录下面新建文件unbuf.go文件,具体内容如下:

package unbuf

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func init() {
    rand.Seed(time.Now().UnixNano())
}

//Player xxx
type Player struct {
    User1 string
    User2 string
}

// NewPlayer  create a instance, Player is object
func NewPlayer(user1, user2 string) *Player {
    return &Player{
        User1: user1,
        User2: user2,
    }
}

func (p *Player) GoPlayer() {
    var wg sync.WaitGroup
    ch := make(chan int)
    wg.Add(2)
    go player(p.User1, ch, &wg)
    go player(p.User2, ch, &wg)
    ch <- 1
    wg.Wait()
}

//player  two players
func player(name string, ch chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for {
        ball, ok := <-ch
        if !ok {
            fmt.Printf("%s won!!!\n", name)
            break
        }
        n := rand.Intn(100)
        if n%15 == 0 {
            fmt.Printf("%s miss,the rand number is %d\n", name, n)
            close(ch)
            break
        }
        fmt.Printf("Player %s hit the ball %d,the rand number is %d\n", name, ball, n)
        ball++
        ch <- ball
    }
}

func Runner() {
    var wg sync.WaitGroup
    ch := make(chan int)
    wg.Add(1)
    go run(ch, &wg)
    ch <- 1
    wg.Wait()
}

func run(ch chan int, wg *sync.WaitGroup) {
    var newRunner int
    runner := <-ch
    fmt.Printf("runner %d running with Baton\n", runner)
    if runner != 4 {
        newRunner = runner + 1
        fmt.Printf("runner %d to the line\n", runner)
        go run(ch, wg)
    }
    // rand sleep time
    n := rand.Intn(100)
    time.Sleep(time.Duration(n) * time.Millisecond)
    if runner == 4 {
        fmt.Printf("runner %d finish,Race over\n", runner)
        wg.Done()
        return
    }
    fmt.Printf("runner %d exchange with runner %d\n", runner, newRunner)
    ch <- newRunner
}

对子命令进行完善,具体代码如下:

// Copyright © 2018 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
    "fmt"

    "github.com/51reboot/golang-03-homework/lesson8/jkak/unbuf"
    "github.com/spf13/cobra"
)

// unbufCmd represents the unbuf command
var unbufCmd = &cobra.Command{
    Use:   "unbuf",
    Short: "A brief description of your command",
    Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("unbuf called")
        // TODO: work your own magic here
        obj := unbuf.NewPlayer("chen", "song")
        obj.GoPlayer()

        fmt.Println("\n-- start running --\n")
        unbuf.Runner()
    },
}

func init() {
    rootCmd.AddCommand(unbufCmd)

    // Here you will define your flags and configuration settings.

    // Cobra supports Persistent Flags which will work for this command
    // and all subcommands, e.g.:
    // unbufCmd.PersistentFlags().String("foo", "", "A help for foo")

    // Cobra supports local flags which will only run when this command
    // is called directly, e.g.:
    // unbufCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

到此一个简单demo功能就已经实现,我们运行一下看看实际效果:

go run main.go unbuf
unbuf called
Player song hit the ball 1,the rand number is 12
Player chen hit the ball 2,the rand number is 69
Player song hit the ball 3,the rand number is 58
Player chen hit the ball 4,the rand number is 77
Player song hit the ball 5,the rand number is 83
Player chen hit the ball 6,the rand number is 31
Player song hit the ball 7,the rand number is 16
Player chen hit the ball 8,the rand number is 67
Player song hit the ball 9,the rand number is 78
chen miss,the rand number is 15
song won!!!

-- start running --

runner 1 running with Baton
runner 1 to the line
runner 1 exchange with runner 2
runner 2 running with Baton
runner 2 to the line
runner 2 exchange with runner 3
runner 3 running with Baton
runner 3 to the line
runner 3 exchange with runner 4
runner 4 running with Baton
runner 4 finish,Race over

Cobra的使用就介绍到这里,更新细节可去github详细研究一下。这里只是一个简单的使用入门介绍,如果有错误之处,敬请指出,谢谢~

最后文中用到的代码,如有侵权,请与我联系;

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
happlyfox happlyfox
3年前
[cobra]-强大的CLI应用程序库
关于我cobra介绍<imgsrc"https://gitee.com/happlyfox/img/raw/master/image20210218091620719.png"alt"title.img"style"zoom:80%;"/Cobra是一个用于创建强大的现代CLI应用程序的库,也是一个用于生成应用程序和命令文件的程序
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这