使用 go cobra创建命令行项目

栏目: Go · 发布时间: 5年前

内容简介:Cobra是一个库,其提供简单的接口来创建强大现代的CLI接口,类似于git或者go工具。同时,它也是一个应用,用来生成应用框架,从而开发以Cobra为基础的应用。Docker和Kubernetes源码中使用了Cobra。概念Cobra有三个基本概念commands,arguments和flags。其中commands代表行为,arguments代表数值,flags代表对行为的改变。

Cobra是一个库,其提供简单的接口来创建强大现代的CLI接口,类似于git或者 go 工具。同时,它也是一个应用,用来生成应用框架,从而开发以Cobra为基础的应用。Docker和Kubernetes源码中使用了Cobra。

概念

Cobra有三个基本概念commands,arguments和flags。其中commands代表行为,arguments代表数值,flags代表对行为的改变。

基本模型如下:

APPNAME COMMAND ARG --FLAG

例如:

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

# clone是commands,URL是arguments,brae是flags
git clone URL --bare

安装cobra

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

安装cobra可执行命令

在文件夹github.com/spf13/cobra/cobra下使用go install在$GOPATH/bin路径下生成cobra.exe可执行命令。

go install

此时,可能会遇到go的一些包下载不下来的问题。由于众所周知的原因,有时会go get的时候会有一些包下载不下来,类似这样出现time out。

(https fetch: Get https://golang.org/x/sys/unix?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
(https fetch: Get https://golang.org/x/text/transform?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
(https fetch: Get https://golang.org/x/text/unicode/norm?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

这时候可以手动安装。进入gopath的src目录:

cd ~/go/src

创建目录:

mkdir -p  golang.org/x/

进入刚创建的目录:

cd golang.org/x

克隆git库:

git clone https://github.com/golang/sys.git
git clone https://github.com/golang/text.git

使用Cobra

创建一个名称为demo的cobra项目,其目录为$GOPATH/src。

cobra init demo

实现没有子命令的CLIs程序

接下来就是可以继续demo的功能设计了。例如在demo下面新建一个包,名称为imp。如下:

demo
    cmd/
       root.go
    imp/
       imp.go
   main.go       //程序执行的入口,调用cmd包所以我们只需要在cmd包内调用imp包就能实现demo程序的需求

imp.go文件的代码如下:

package imp
import(
    "fmt"
)

func Show(name string, age int) {
    fmt.Printf("My Name is %s, My age is %d\n", name, age)
}

demo应用接收两个参数name和age,然后打印出来。打开cobra自动生成的root.go文件可以看到,cmd包进行了一些初始化操作并提供了Execute接口。十分简单,其中viper是cobra集成的配置文件读取的库。cobra的所有命令都是通过cobra.Command这个结构体实现的。为了实现demo功能,显然我们需要修改RootCmd。修改后的代码如下:

// Copyright © 2019 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"
	"os"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"demo/imp"
)

var cfgFile string
var name string
var age int

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "demo",
	Short: "A test demo",
	Long: `Demo is a test appcation for print things.`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	Run: func(cmd *cobra.Command, args []string) { 
	    if len(name) == 0 {
		    cmd.Help()
			return
		}
		imp.Show(name, age)
	},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports persistent flags, which, if defined here,
	// will be global for your application.
	//rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.demo.yaml)")

	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	//rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
	rootCmd.Flags().StringVarP(&name, "name", "n", "", "person's name ")
	rootCmd.Flags().IntVarP(&age, "age", "a", 0, "person's age")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" {
		// Use config file from the flag.
		viper.SetConfigFile(cfgFile)
	} else {
		// Find home directory.
		home, err := homedir.Dir()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		// Search config in home directory with name ".demo" (without extension).
		viper.AddConfigPath(home)
		viper.SetConfigName(".demo")
	}

	viper.AutomaticEnv() // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}

在$GOPATH/src/demo目录下,编译demo可执行程序

go install

到此demo的功能已经实现了,我们编译运行一下看看实际效果。执行demo程序

$ demo
Demo is a test appcation for print things.

Usage:
  demo [flags]

Flags:
  -a, --age int         person's age
      --config string   config file (default is $HOME/.demo.yaml)
  -h, --help            help for demo
  -n, --name string     person's name
  -t, --toggle          Help message for toggle
$ demo --name xiaoxu918 --age 25
My Name is xiaoxu918, My Age is 25

实现有子命令的CLIs程序

在$GOPATH/src/demo目录下,继续使用cobra为demo添加子命令test。

cobra add test

在src目录下demo的文件夹下生成了一个cmd\test.go文件,如下:

demo
    cmd/
       root.go
       test.go
   main.go

更新编译demo应用

go install

接下来的操作就和上面修改root.go文件一样去配置test子命令,此处不再赘述,查看效果

demo

可以看出demo既支持直接使用标记flag,又能使用子命令

demo test -h

附加命令

附加命令可以在/cmd/文件夹中写,例如一个版本信息文件,可以创建/cmd/version.go。代码如下:

package cmd

import (
	"fmt"
	"github.com/spf13/cobra"
)

func init() {
	rootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of Demo",
	Long:  `All software has versions. This is demo's`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Demo Version: v1.0")
	},
}

更新编译demo应用

go install
demo

测试一下。当然,建议版本信息使用flag实现。

demo version
Demo Version: v1.0

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

调试九法

调试九法

David J.Agans / 赵俐 / 人民邮电出版社 / 2010-12-7 / 35.00元

硬件缺陷和软件错误是“技术侦探”的劲敌,它们负隅顽抗,见缝插针。本书提出的九条简单实用的规则,适用于任何软件应用程序和硬件系统,可以帮助软硬件调试工程师检测任何bug,不管它们有多么狡猾和隐秘。 作者使用真实示例展示了如何应用简单有效的通用策略来排查各种各样的问题,例如芯片过热、由蛋酒引起的电路短路、触摸屏失真,等等。本书给出了真正能够隔离关键因素、运行测试序列和查找失败原因的技术。 ......一起来看看 《调试九法》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具