简介

cobra是一个命令行程序库,可以用来编写命令行程序。同时,它也提供了一个脚手架,

用于生成基于 cobra 的应用程序框架。非常多知名的开源项目使用了 cobra 库构建命令行,如KubernetesHugoetcd等等等等。

本文介绍 cobra 库的基本使用和一些有趣的特性。

关于作者spf13,这里多说两句。spf13 开源不少项目,而且他的开源项目质量都比较高。

相信使用过 vim 的都知道spf13-vim,号称 vim 终极配置。

可以一键配置,对于我这样的懒人来说绝对是福音。他的viper是一个完整的配置解决方案。

完美支持 JSON/TOML/YAML/HCL/envfile/Java properties 配置文件等格式,还有一些比较实用的特性,如配置热更新、多查找目录、配置保存等。

还有非常火的静态网站生成器hugo也是他的作品。

快速使用

第三方库都需要先安装,后使用。下面命令安装了cobra生成器程序和 cobra 库:

$ go get github.com/spf13/cobra/cobra

如果出现了golang.org/x/text库找不到之类的错误,需要手动从 GitHub 上下载该库,再执行上面的安装命令。我以前写过一篇博客搭建 Go 开发环境提到了这个方法。

我们实现一个简单的命令行程序 git,当然这不是真的 git,只是模拟其命令行。最终还是通过os/exec库调用外部程序执行真实的 git 命令,返回结果。

所以我们的系统上要安装 git,且 git 在可执行路径中。目前我们只添加一个子命令version。目录结构如下:

▾ get-started/
▾ cmd/
helper.go
root.go
version.go
main.go

root.go

package cmd

import (
"errors" "github.com/spf13/cobra"
) var rootCmd = &cobra.Command {
Use: "git",
Short: "Git is a distributed version control system.",
Long: `Git is a free and open source distributed version control system
designed to handle everything from small to very large projects
with speed and efficiency.`,
Run: func(cmd *cobra.Command, args []string) {
Error(cmd, args, errors.New("unrecognized command"))
},
} func Execute() {
rootCmd.Execute()
}

version.go

package cmd

import (
"fmt"
"os" "github.com/spf13/cobra"
) var versionCmd = &cobra.Command {
Use: "version",
Short: "version subcommand show git version info.", Run: func(cmd *cobra.Command, args []string) {
output, err := ExecuteCommand("git", "version", args...)
if err != nil {
Error(cmd, args, err)
} fmt.Fprint(os.Stdout, output)
},
} func init() {
rootCmd.AddCommand(versionCmd)
}

main.go文件中只是调用命令入口:

package main

import (
"github.com/darjun/go-daily-lib/cobra/get-started/cmd"
) func main() {
cmd.Execute()
}

为了编码方便,在helpers.go中封装了调用外部程序和错误处理函数:

package cmd

import (
"fmt"
"os"
"os/exec" "github.com/spf13/cobra"
) func ExecuteCommand(name string, subname string, args ...string) (string, error) {
args = append([]string{subname}, args...) cmd := exec.Command(name, args...)
bytes, err := cmd.CombinedOutput() return string(bytes), err
} func Error(cmd *cobra.Command, args []string, err error) {
fmt.Fprintf(os.Stderr, "execute %s args:%v error:%v\n", cmd.Name(), args, err)
os.Exit(1)
}

每个 cobra 程序都有一个根命令,可以给它添加任意多个子命令。我们在version.goinit函数中将子命令添加到根命令中。

编译程序。注意,不能直接go run main.go,这已经不是单文件程序了。如果强行要用,请使用go run .

$ go build -o main.exe

cobra 自动生成的帮助信息,very cool:

$ ./main.exe -h
Git is a free and open source distributed version control system
designed to handle everything from small to very large projects
with speed and efficiency. Usage:
git [flags]
git [command] Available Commands:
help Help about any command
version version subcommand show git version info. Flags:
-h, --help help for git Use "git [command] --help" for more information about a command.

单个子命令的帮助信息:

$ ./main.exe version -h
version subcommand show git version info. Usage:
git version [flags] Flags:
-h, --help help for version

调用子命令:

$ ./main.exe version
git version 2.19.1.windows.1

未识别的子命令:

$ ./main.exe clone
Error: unknown command "clone" for "git"
Run 'git --help' for usage.

编译时可以将main.exe改成git,用起来会更有感觉

Go 每日一库之 cobra的更多相关文章

  1. Go 每日一库之 viper

    简介 上一篇文章介绍 cobra 的时候提到了 viper,今天我们就来介绍一下这个库. viper 是一个配置解决方案,拥有丰富的特性: 支持 JSON/TOML/YAML/HCL/envfile/ ...

  2. Go 每日一库之 flag

    缘起 我一直在想,有什么方式可以让人比较轻易地保持每日学习,持续输出的状态.写博客是一种方式,但不是每天都有想写的,值得写的东西. 有时候一个技术比较复杂,写博客的时候经常会写着写着发现自己的理解有偏 ...

  3. Go 每日一库之 fsnotify

    简介 上一篇文章Go 每日一库之 viper中,我们介绍了 viper 可以监听文件修改进而自动重新加载. 其内部使用的就是fsnotify这个库,它是跨平台的.今天我们就来介绍一下它. 快速使用 先 ...

  4. Go 每日一库之 go-flags

    简介 在上一篇文章中,我们介绍了flag库.flag库是用于解析命令行选项的.但是flag有几个缺点: 不显示支持短选项.当然上一篇文章中也提到过可以通过将两个选项共享同一个变量迂回实现,但写起来比较 ...

  5. Go 每日一库之 go-homedir

    简介 今天我们来看一个很小,很实用的库go-homedir.顾名思义,go-homedir用来获取用户的主目录. 实际上,使用标准库os/user我们也可以得到这个信息: package main i ...

  6. Go 每日一库之 go-ini

    简介 ini 是 Windows 上常用的配置文件格式.MySQL 的 Windows 版就是使用 ini 格式存储配置的. go-ini是 Go 语言中用于操作 ini 文件的第三方库. 本文介绍g ...

  7. go每日一库 [home-dir] 获取用户主目录

    关于我 我的博客|文章首发 顾名思义,go-homedir用来获取用户的主目录.实际上,通过使用标准库os/user我们也可以得到内容,使用以下方式 标准库使用 package main import ...

  8. [python每日一库]——hotshot

    High performance logging profiler 官方文档:http://docs.python.org/2/library/hotshot.html#module-hotshot ...

  9. go每日新闻--2020-02-27

    go 语言中文网(每日资讯)_2020-02-27 一.Go 语言中文网 如何正确看待 Google 宣布 Fuchsia 操作系统没有选 Go 作为终端开发语言 Actor 还是 CSP?Go 中的 ...

随机推荐

  1. JPA 一对多双向映射 结果对象相互迭代 造成堆栈溢出问题方法

    问题: JPA 在双向映射时,会相互包含对方的实例,相互引用,造成递归迭代,堆栈溢出(java.lang.StackOverflowError). 分析: 在后端向前端传递的时候会将数据序列化,转为j ...

  2. [转]Win10下安装Linux子系统

    工作以来一直DotNet系偏C/S, 接触Web开发的时间也不长, 现在主要偏向Web全栈方向, 一直对Linux系统心生向往, 夜深了娃睡了, 打开老旧的笔记本来折腾一下. 准备工作 控制面板 &g ...

  3. Python--day32--struct模块

    struct模块:该模块可以把一个类型,如数字,转成固定长度的bytes

  4. 扶桑号战列舰 (单调栈+线段树区间更新懒惰标记 or 栈)

    传送门 •题目描述 题目描述 众所周知,一战过后,在世界列强建造超无畏级战列舰的竞争之中,旧日本海军根据“个舰优越主义”,建造了扶桑级战列舰,完工时为当时世界上武装最为强大的舰只. 同时,扶桑号战列舰 ...

  5. vue 路由跳转前确认框,刷新浏览器页面前提示确认框

    先看效果图: 1.刷新页面效果: 2.跳转路由(进入别的页面前)效果: 代码: // 路由跳转确认 beforeRouteLeave(to, from, next) { const answer = ...

  6. yum安装gcc和gcc-c++

    本次总结参考 博客:http://blog.csdn.net/robertkun/article/details/8466700  ,非常 感谢他的博客,帮我解决了问题. 今天安装gcc-c++时出现 ...

  7. linux下mysql5.7忘记root密码修改

    朋友最近开始学服务器,mysql密码忘了又不会弄,让我帮忙解决一下.重置或修改mysql的root密码这种事平时很少做,还是得google辅助一下,于是弄完了写篇博客记录一下,方便若干月后又有人遇到这 ...

  8. Linux 内核同步 urb

    不幸的是, 同步 urb 没有一个象中断, 控制, 和块 urb 的初始化函数. 因此它们必须在 驱动中"手动"初始化, 在它们可被提交给 USB 核心之前. 下面是一个如何正确初 ...

  9. 红米K20 Pro 传感器失效解决方案

    最近把Redmi K20 Pro升级到了安卓Q,用了几天,不好用,总是提示屏幕前方有遮挡,于是刷回了安卓9,但是发现重力感应传感器失效了,屏幕不会随这方向转,导航的时候看起来很难受. 网上查了一下,要 ...

  10. Team Foundation Server 2015使用教程【4】:默认团队权限说明