zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Go --- 命令行工具Cobra

2023-03-14 22:59:59 时间

Cobra

Cobra既是一个用于创建强大的现代CLI应用程序的库,也是一个用于生成应用程序和命令文件的程序。

简单来讲就是用来写命令的,例如常见的 version ,help,build 啥的

image

cobra的简单使用

首先是项目结构

▾ appName/
    ▾ cmd/
        root.go
        yourCmd.go
      main.go

下面这个是我的项目结构

image

在 Cobra 的应用程序中他的main.go文件中就只是用来初始化Corbra的。

下面是main.go文件里的内容

package main
// 这个 pathToYourApp 就是你应用程序的路径
import (
  "{pathToYourApp}/cmd"
)
func main() {
  cmd.Execute()
}

Cobra不需要任何特殊的构造函数。只需创建您的命令。

需要有一个root.go文件在cmd文件中,内容大概如下

package cmd
import (
    "fmt"
    "os"
    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)
var (
    // 使用的标志
    cfgFile     string
    userLicense string
    rootCmd = &cobra.Command{
        Use:   "cobra",
        Short: "A generator for Cobra based Applications",
        Long: `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.`,
    }
)
// 用于执行root
func Execute() error {
    return rootCmd.Execute()
}
// 初始化配置
func init() {
    cobra.OnInitialize(initConfig)
    rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
    rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
    rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project")
    rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
    viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
    viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
    viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
    viper.SetDefault("license", "apache")
//  rootCmd.AddCommand(addCmd)
//  rootCmd.AddCommand(initCmd)
}
func initConfig() {
    if cfgFile != "" {
        // 使用标签中的配置
        viper.SetConfigFile(cfgFile)
    } else {
        // 在主目录下寻找基础配置
        home, err := os.UserHomeDir()
        cobra.CheckErr(err)
        // 在主目录下找不到 ".cobra" 文件的情况
        viper.AddConfigPath(home)
        viper.SetConfigType("yaml")
        viper.SetConfigName(".cobra")
    }
    viper.AutomaticEnv()
    if err := viper.ReadInConfig(); err == nil {
        fmt.Println("Using config file:", viper.ConfigFileUsed())
    }
}

有了 root.go 后就可以写自己的命令了

就比如说 version 命令,在 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 Hugo",
   Long:  `All software has versions. This is Hugo's`,
    // 执行该命令时,会执行的函数
   Run: func(cmd *cobra.Command, args []string) {
      fmt.Println("this is test cobra example")
   },
}

接着整理依赖就行了

# 初始化go.mod文件
go mod init
# 整理依赖
go mod vendor

然后构建exe可执行文件

go build main.go

接着测试写的version

# 先查看总的命令
> main
# 然后查看version命令
> main version

结果:

image

基本的操作会了,然后整点花活

整个server的命令,在cmd文件中创建server.go ,内容如下

package cmd
import (
   "github.com/gin-gonic/gin"
   "github.com/spf13/cobra"
)
func init() {
   rootCmd.AddCommand(serverCmd)
}
var serverCmd = &cobra.Command{
   Use:   "server",
   Short: "Print the version number of Hugo",
   Long:  `All software has versions. This is Hugo's`,
   Run: func(cmd *cobra.Command, args []string) {
      r := gin.Default()
      r.GET("/", func(context *gin.Context) {
         context.JSON(200,gin.H{
            "每一天":"都要开心",
         })
      })
      r.Run()
   },
}

因为需要导入新的依赖,这是我们再进行依赖的整理

go mod vendor

重新构建.exe文件(删除老的main.exe 文件)

> go build main.go

执行server命令

> main server

然后打开浏览器,你便会得到

image

如果gin无法执行,可能是端口被占用,检查端口后再运行

cobra.Command 常用的参数

  • Use
    • 使用信息
  • Short
    • 'help’输出中显示的简短描述。
  • Long
    • 'help’输出中显示的详细描述。
  • Run: func(cmd *Command, args []string)
    • 通常是实际的功函数。大多数命令只会实现这一点。
  • RunE: func(cmd *Command, args []string) error
    • 和Run一样,但是返回一个error

其余信息建议去看Cobra项目: Cobra项目地址