7

Cobra 快速入门 - 专为命令行程序而生

 3 years ago
source link: https://my.oschina.net/xcbeyond/blog/5166885
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

blog-thumb

最近一直在看 Istio(一个 Service Mesh 框架)相关的东西,当看到其源码时发现了一个新东西 Cobra,一查却发现这是个好东西,用的地方可不少,比如:DockerKubernetes 等都有它的身影存在。为了更好的了解这些开源框架(如,IstioKubernetes 等),势必需要对 Cobra 做一个详细的了解,后续可能用到它的地方会很多。今天就 Cobra 做一个整体的介绍,让我们对它能有所认识,或许今后你的项目中也会用到它。

1、Cobra 介绍

1.1 Cobra 概述

Cobra 是一个 Golang 包,它提供了简单的接口来创建命令行程序。同时,Cobra 也是一个应用程序,用来生成应用框架,从而开发以 Cobra 为基础的应用。

Cobra

1.2 主要功能

Cobra 的主要功能如下:

  • 简易的子命令行模式,如 app server, app fetch 等等。
  • 完全兼容 posix 命令行模式。
  • 嵌套子命令 subcommand
  • 支持全局,局部,串联 flags
  • 使用 cobra 很容易生成应用程序和命令(cobra init appname 和 cobra add cmdname)。
  • 提供智能化的提示(如,输出 app srver 命令,将提示 你是要输入 app server 吗?)。
  • 自动生成 commands 和 flags 的帮助信息。
  • 自动生成详细的 help 信息,如 app -help
  • 自动识别帮助 flag、 -h--help
  • 自动生成应用程序在 bash 下命令自动完成功能。
  • 自动生成应用程序的 man 手册。
  • 命令行别名。
  • 自定义 help 和 usage 信息。
  • 可选的与 viper 的紧密集成。

对于命令行程序而言,上面这些功能简直就是量身打造。

1.3 应用举例

Cobra 被用于许多 Go 项目中,例如:KubernetesHugoGithub CLI等,更多广泛使用的项目有:

(来源于:https://github.com/spf13/cobra/blob/master/projects_using_cobra.md

看了这些,一个字“赞”,两个字“优秀”!

了解了 Cobra 后,再去看这些 KubernetesetcdRegistry 等开源项目的代码时,也就大概知道如何去看了,这也就是我学习 Cobra 的目的。

Cobra 是基于命令(commands)、参数(arguments )、选项(flags)而创建的。

在具体了解、使用Cobra前有一些概念需要提前知晓一下:命令(commands)、参数(arguments )、选项(flags)这几个概念。

  • commands:命令代表行为,一般表示 action,即运行的二进制命令服务。同时可以拥有子命令(children commands)
  • arguments:参数代表命令行参数。
  • flags:选项代表对命令行为的改变,即命令行选项。二进制命令的配置参数,可对应配置文件。参数可分为全局参数和子命令参数。

最好的命令行程序在实际使用时,就应该像在读一段优美的语句,能够更加直观的知道如何与用户进行交互。执行命令行程序应该遵循一般的格式: APPNAME VERB NOUN --ADJECTIVE 或 APPNAME COMMAND ARG --FLAG

比如下面的示例:

# server是 commands,port 是 flag
hugo server --port=1313

# clone 是 commands,URL 是 arguments,brae 是 flag
git clone URL --bare
xcbeyond@xcbeyonddeMacBook-Pro ~ % docker info --help 

Usage:  docker info [OPTIONS]

Display system-wide information

Options:
  -f, --format string   Format the output using the given Go template

你没有看错,像 Docker 这种这么复杂的命令都是用 Cobra 是实现的,其必有过人之处,下一节就让我们一起来看看如何实现一套属于自己的命令行工具吧!

3、Cobra 实战

实战是最好的学习方式! 本节将从一个实战带你快速入门 Cobra。

3.1 环境准备

3.1.1 前提条件&环境

  • 操作系统:MacOS
  • Go 环境:go 1.16
  • Go 开发 IDE:VSCode

(上述环境可以个人环境而定,不做限制)

3.1.2 Cobra 安装

使用 go get 命令获取最新版本的 Cobra 库。下面命令将会安装 Cobra 及其相关依赖包:

go get -u github.com/spf13/cobra/cobra

下载安装完 Cobra 后,打开 GOPATH 目录,在 bin 目录下会下载好 cobra 程序(Window: cobra.exe, MacOS: cobra)。

3.1.3 工程初始化(Cobra 代码生成器)

假设现需要开发一个基于 Cobra 的 CLI 的命令行程序,命名为 cobra-demo

由于 Cobra 提供了代码生成器的功能,我们可以直接使用 Cobra 提供的初始化命令 cobra init 进行快速初始化创建 Cobra 工程。

切换到 GOPATH 目录(如,/Users/xcbeyond/github),执行命令 cobra init <name> --pkg-name <pkgname>,如下:

xcbeyond@xcbeyonddeMacBook-Pro github % .\bin\cobra init cobra-demo --pkg-name github.com/xcbeyond/cobra-demo
Your Cobra application is ready at
/Users/xcbeyond/github/cobra-demo

初始化成功后,cobra-demo 程序目录结构如下:

.
├── cmd
│   ├── root.go
│   └── show.go
├── go.mod
├── go.sum
└── main.go

3.1.4 运行

执行命令 go run 运行:

xcbeyond@xcbeyonddeMacBook-Pro cobra-demo % go run main.go
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.

3.2 实战

这里以一个简单的 time 命令为例,实战讲解如何 Cobra 开发一个命令。

功能如下:

  • show:查看当前时间。
  • parse:指定时间格式 –format,parse 为 show 的子命令。

3.2.1 实现 show 命令(Command命令)

  1. 添加 show 命令

    通过命令 cobra add 添加 show 命令:

    xcbeyond@xcbeyonddeMacBook-Pro cobra-demo % ../bin/cobra add show
    show created at /Users/xcbeyond/github/cobra-demo
    

    此时,项目目录下会创建一个 show.go 文件,在该文件中可完成命令的具体操作逻辑。

    下面是 show.go 文件的初始代码:

    // showCmd represents the show command
    var showCmd = &cobra.Command{
        Use:   "show",
        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("show called")
        },
    }
    
    func init() {
        rootCmd.AddCommand(showCmd)
    
        // Here you will define your flags and configuration settings.
    
        // Cobra supports Persistent Flags which will work for this command
        // and all subcommands, e.g.:
        // showCmd.PersistentFlags().String("foo", "", "A help for foo")
    
        // Cobra supports local flags which will only run when this command
        // is called directly, e.g.:
        // showCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
    }
    

    &cobra.Command 作为命令的定义,其中有如下变量:

    • Use:用于指定具体的命令,如:show。
    • Short:命令的简短描述。
    • Long:命令的详细描述。
    • Run:命令执行入口,用于实现命令的具体处理逻辑。

    rootCmd.AddCommand(showCmd) 命令的添加,将命令添加到根命令。(Cobra 支持命令的子命令)

  2. 实现显示当前时间逻辑

    在 &cobra.Command.Run 中添加获取当前时间逻辑 time.Now()

    var showCmd = &cobra.Command{
        Use:   "show",
        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) {
            // show current time
            fmt.Println(time.Now())
        },
    }
    
  3. 修改 help 命令

    help 命令有两个,一个是 short,一个是 lang,很明显 short 命令用来定义简短的说明,lang 命令用来定义详细说明,下面我们修改 show 命令的 help:

    var showCmd = &cobra.Command{
        Use:   "show",
        Short: "Displays the current time",
        Long: `You can use the time show command to view the current time. For example:
    
    $ ./cobra-demo show
    2021-03-19 14:34:20.9320241 +0800 CST m=+0.378845301`,
        Run: func(cmd *cobra.Command, args []string) {
            // show current time
            fmt.Println(time.Now())
        },
    }
    
  4. 执行 show 命令:

    xcbeyond@xcbeyonddeMacBook-Pro cobra-demo % go run main.go show
    2021-07-31 14:49:27.3582836 +0800 CST m=+0.176660901
    

    执行 show –help 命令:

    xcbeyond@xcbeyonddeMacBook-Pro cobra-demo % go run main.go show --help
    You can use the time show command to view the current time. For example:
    
    $ ./cobra-demo show
    2021-07-31 14:34:20.9320241 +0800 CST m=+0.378845301
    
    Usage:
    cobra-demo show [flags]
    
    Flags:
    -h, --help   help for show
    
    Global Flags:
            --config string   config file (default is $HOME/.cobra-demo.yaml)
    

Cobra-demo 只是简单的阐述了由几部分组成,在实际项目中要比这复杂的很多,一般都是拥有多个子命令,但核心内容都是类似的。

大家好!我是 xcbeyond, xcbeyond 就是我,大家也可以叫我超哥!本文首发于我的博客:Cobra 快速入门


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK