构建Go命令行程序工具链

admin 2022年6月27日23:32:34评论29 views字数 2711阅读9分2秒阅读模式

偷懒的故事

今天的推荐需要从一个偷懒的故事说起···

话说不久前,需要输出一个按发布时间排序的酷Go推荐的历史文章列表,类似于这样:

构建Go命令行程序工具链
于是乎,想着从GoCN上一篇一篇copy文章的标题吧,5篇下来,手眼已经不协调了,此时此刻才想起自己貌似是个码农,此情此景那必须coding一段,让代码来输出这个列表。

思路很简单,看一下GoCN文章列表的API,再看下鉴权方式(看header是通过cookie),然后就可以coding了,通过API拉取文章数据,提取需要的字段再组装成MD输出就完事了!

当准备一个main.go搞定的时候,本着对coding的敬畏,简单的思考了一下程序的可读性、拓展性,决定还是构建一个比较完整的命令行程序,如下:

构建Go命令行程序工具链

主角登场

那么要实现上图的命令行提示,程序参数解析等,不借助于第三方包当然也能实现。但,前人种好的大树为哈不乘凉呢,在业界对于命令行工具的开发已经有比较成熟的实现,下面清楚本文的主角:

  • cobra:应用命令行框架
  • pflag:命令行参数解析
  • viper:配置文件解析
下面结合实际项目来看如何使用这三位大哥来构建Go命令行程序。

先简单看下项目结构:

.
├── cmd
│   ├── pull.go
│   └── root.go
├── config.yaml
├── file
│   └── cool-go.md
├── go.mod
├── go.sum
├── gocn-cli
└── main.go

然后引入上面所推荐的三个库:

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

go get -u github.com/spf13/viper

go get -u github.com/spf13/pflag

Coding

package cmd

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

var (
    cfgFile string
)

func init() {
    cobra.OnInitialize(initConfig)
    
    // 解析配置文件参数
    rootCmd.PersistentFlags().StringVar(&cfgFile, "config""""config file (default is ./config.yaml)")
}

// initConfig viper加载配置文件
func initConfig() {
    if cfgFile != "" {
        viper.SetConfigFile(cfgFile)
    } else {
        viper.AddConfigPath(".")
        viper.SetConfigName("config")
    }
    
    if err := viper.ReadInConfig(); err != nil {
        fmt.Println("Can't read config file:", err)
        os.Exit(1)
    }
}

// 创建全局rootCmd
var rootCmd = &cobra.Command{
    Use:   "gocn-cli",
    Short: "gocn-cli is a command line tool for gocn.com",
    Long:  "gocn-cli is a command line tool for gocn.com",
    Run: func(cmd *cobra.Command, args []string) {
        
    },
}

// Execute 执行命令 main调用
func Execute() {
    if err := rootCmd.Execute(); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

package cmd

import (
 "github.com/spf13/cobra"
 "github.com/spf13/viper"
 "os"
)

var (
 moduleName string
)

func init() {
    // 给rootCmd增加新的命令pullCmd
 rootCmd.AddCommand(pullCmd)

 pullCmd.Flags().StringVarP(&moduleName, "module""m""""module name")
}

var pullCmd = &cobra.Command{
 Use:   "pull gocn data",
 Short: "pull gocn data",
 Run: func(cmd *cobra.Command, args []string) {
  pullHandler()
 },
}

// pullHandler pullCmd 对应的处理函数
func pullHandler() {
 if moduleName == "" {
  fmt.Println("module name is required")
  os.Exit(1)
 }

 switch moduleName {
 case "cool-go":
  pullCoolGo()

 default:
  fmt.Println("module name is invalid")
  os.Exit(1)
 }
}

func pullCoolGo() {
 // TODO Write Your Code
}

结语

以上简单介绍了如何使用cobra、viper、pflag,当然它们的用法还有很多,这里只做个简单的入门。
可见,通过简单的代就能构建出比较好的命令行程序。

参考

  • https://github.com/spf13/cobra
  • https://github.com/spf13/viper
  • https://github.com/spf13/pflag


往期推荐



构建Go命令行程序工具链

等等,怎么使用 SetMemoryLimit?


构建Go命令行程序工具链

第八届 GopherChina 大会蓄势待发!


构建Go命令行程序工具链

这不会又是一个Go的BUG吧?

想要了解Go更多内容,欢迎扫描下方👇 关注 公众号,回复关键词 [实战群]  ,就有机会进群和我们进行交流

构建Go命令行程序工具链

分享、在看与点赞,至少我要拥有一个叭~

构建Go命令行程序工具链
构建Go命令行程序工具链

原文始发于微信公众号(GoCN):构建Go命令行程序工具链

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月27日23:32:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   构建Go命令行程序工具链http://cn-sec.com/archives/1140704.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息