内容简介: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
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具
- MySQL 创建用户及权限的操作命令
- 使用 seed 命令创建模拟数据(学习笔记)
- laravel 创建自定义的artisan make命令
- 用命令创建用户、配置 IIS、配置 SQL Server
- 如何创建Perl脚本以获取一些“命名”命令行参数?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。