本文上一文章《Golang实践录:命令行cobra库实例》 的优化,主要的子命令的业务实现的整理。

起因

旧版本中,每个子命令的入口函数,均需一一判断传入参数,并调用对应的业务实现函数,编码扩展稍有繁琐,而且也不美观。
思考再三,决定使用结构体数组的形式来优化。

思路

此思路来源于 busybox 。

首先定义结构体:

// 命令列表,包括名称,帮助信息
type UserCmdFunc struct {Name stringShortHelp string// LongHelp stringFunc func(args []string)
}

再实现遍历命令列表函数:

func PrintHelpInfo(theCmd []conf.UserCmdFunc) {fmt.Println("valid command: ");for _, item:=range theCmd {fmt.Println(item.Name, "\t:", item.ShortHelp)}
}

在使用时,只需要定义结构体数组,并填写对应的命令名称,帮助信息,及对应的函数指针即可。示例:

var theCmd = []conf.UserCmdFunc{conf.UserCmdFunc {Name: "foo",ShortHelp: "just a foo help info",Func: foo,},conf.UserCmdFunc {"watch", "watch config file", testWatch,},
}

当命令不合法——亦即无法在结构体数组中找到时,提示合法的命令,提高体验。
由于各子命令位于不同的包中,实际上 theCmd 及子命令入口函数绝大部分代码是相同的,容易扩展。

实现

以子命令 test 为例,旧版本入口源码如下:

func NewCmdTest() *cobra.Command{var cmd = &cobra.Command{Use:     name,Short:   shortDescription,Long:    longDescription,Example: example,RunE: func(cmd *cobra.Command, args []string) error {if (len(args) == 0) {klog.Warning("no args found")return nil}// !! 以下要一一判断并调用if (args[0] == "foo"){foo(args)} else if (args[0] == "watch"){testWatch(args)} else {klog.Printf("cmd '%v' not support", args[0])return nil} return nil},}return cmd
}

新版本变化如下:

var theCmd = []conf.UserCmdFunc{conf.UserCmdFunc {Name: "foo",ShortHelp: "just a foo help info",Func: foo,},conf.UserCmdFunc {"watch", "watch config file", testWatch,},
}func NewCmdTest() *cobra.Command{var cmd = &cobra.Command{Use:     name,Short:   shortDescription,Long:    longDescription,Example: example,RunE: func(cmd *cobra.Command, args []string) error {//klog.Println(common.DBName)if (len(args) == 0) {klog.Warning("no args found")common.PrintHelpInfo(theCmd)return nil}// !! 遍历并调用即可for _, item:=range theCmd {if (args[0] == item.Name) {item.Func(args)return nil}}klog.Printf("cmd '%v' not support", args[0])common.PrintHelpInfo(theCmd)return nil},}// note:使用子命令形式,下列可在help中展开// 命令参数,保存的值,参数名,默认参数,说明//cmd.Flags().StringVar(&mode, "db", "-", "set the database name")return cmd
}

测试

默认输出帮助信息:

$ ./cmdtool.execmd test tool.命令终端测试示例工具。Usage:cmdtool.exe [command]Examples:comming soon...Available Commands:db          db commandhelp        Help about any commandmisc        misc commandtest        test commandFlags:--config string   config file (config.yaml)-h, --help            help for cmdtool.exe--print           will print sth--version         version for cmdtool.exeUse "cmdtool.exe [command] --help" for more information about a command.

执行子命令,默认将合法的命令输出:


$ ./cmdtool.exe test
[2020-12-02 17:43:40.771 rootCmd.go:112] helloooooo 100s firstblood
[2020-12-02 17:43:40.772 cmd.go:43] no args found
valid command:
foo     : just a foo help info
watch   : watch config file$ ./cmdtool.exe test nocmd
[2020-12-02 17:43:47.953 rootCmd.go:112] helloooooo 100s firstblood
[2020-12-02 17:43:47.954 cmd.go:53] cmd 'nocmd' not support
valid command:
foo     : just a foo help info
watch   : watch config file

源码

源码在此。 本次也修改了 cobra 帮助信息不对齐的小问题。

Golang实践录:命令行cobra库实例优化相关推荐

  1. Golang实践录:命令行cobra库实例再三优化

    本文是上一文章<Golang实践录:命令行cobra库实例优化> 的优化,主要的子命令的业务实现的整理. 起因 上一版本实现的方式,还是有点不满意,格式也不对齐,重要的是,似乎不是正规的方 ...

  2. Golang实践录:命令行cobra库实例

    本文使用 cobra 库实现一个命令行工具,类似 git.docker.kubectl 这类的工具. 本文仅为一个初具模型的示例,但有实践参考意义. 起因 在编程中,很多时候,程序都会处理多个参数,特 ...

  3. golang go get 命令行安装库 报错 go: cannot use path@version syntax in GOPATH mode 解决方法

    go mod作为官方的依赖管理工具,类似于maven这种本地缓存库的管理方式,其主要是通过GOPATH/pkg/mod下的缓存包来对工程进行构建. 问题: 执行go get github.com/go ...

  4. Golang实践录:调用C++函数的优化

    趁着五一放假,趁着有时间,把欠的一些技术集中研究研究,写写文章,好给自己一个交待. 本文继续介绍如何在 Golang 中调用 C++ 函数. 起因 前面文章介绍的方式,在运行时需要指定动态库位置,或将 ...

  5. 基于Golang的CLI 命令行程序开发

    基于Golang的CLI 命令行程序开发 [阅读时间:约15分钟] 一. CLI 命令行程序概述 二. 系统环境&项目介绍&开发准备 1.系统环境 2.项目介绍 3.开发准备 三.具体 ...

  6. python脚本实例手机端-python链接手机用Python实现命令行闹钟脚本实例

    前言: 这篇文章给大家介绍了怎样用python创建一个简单的报警,它可以运行在命令行终端,它需要分钟做为命令行参数,在这个分钟后会打印"wake-up"消息,并响铃报警,你可以用0 ...

  7. ECS(Linux)连接RDS,使用命令行方式连接实例

    使用命令行方式连接实例 通过命令行连接RDS MySQL数据库,连接方式如下: mysql -h<连接地址> -P<端口> -u<用户名> -p -D<数据库 ...

  8. 常用的python命令行解析库

    常用的python命令行解析库,这儿介绍3种: 1.argparse 2.click 3.fire argparse是python自带的模块,要经历解析器初始化.参数定义.解析一套流程,使用起来有些繁 ...

  9. 控制台发送get命令_.NET Core使用命令行参数库构建控制台应用程序

    前言 在我们开发中可能需要设计一次性应用程序,这些实用程序可以利用接近原始源代码的优势,但可以在与主Web应用程序完全独立的安全性上下文中启动.具体在 [管理过程](https://12factor. ...

最新文章

  1. linux教程 sed命令的用法,Linux文本处理三剑客——sed命令使用教程
  2. ubuntu检查端口是否开启_Ubuntu默认防火墙安装、启用、配置、端口、查看状态相关信息...
  3. 【Android开发】Android应用程序目录结构
  4. 全字库说文解字字体_【180期】可商用字体大全,无版权纠纷!
  5. 什么是clearfix?
  6. nodemcu引脚_一、ESP32开发板NodeMCU-32S简介
  7. mysql的日备份和周备份_MySQL完全备份
  8. vivado global和out-of-context 选项
  9. MCtalk教育大咖说:不忘教育初心,柚子练琴聚焦音乐陪练
  10. 记录阿里云增加二级域名步骤[同三级]
  11. request和request.form和request.querystring的区别
  12. 用python爬取隐藏内容_人民日报点赞北大保安小哥,自学Python后,人生开挂了!...
  13. Linux头文件 C/C++头文件
  14. matlab 三角函数 积化和差,三角函数积化和差与和差化积公式
  15. iOS - 选取相册中iCloud云上图片和视频的处理
  16. 35岁程序员:被大厂裁员后,我赚到手的却是这样:
  17. 【iOS-Cocos2d游戏开发之十】添加粒子系统特效并解决粒子特效与Layer之间的坐标问题;
  18. python分词考研英语真题词频(附结果)——读取word、nltk、有道智云API
  19. android联接无线路由器,安卓手机和无线路由器无线连接设置方法
  20. Linux系统DB2数据库安装手册

热门文章

  1. 空值用前值填充_Excel数据填充,原来这么简单
  2. pythonbool类型数组生成_对numpy中布尔型数组的处理方法详解
  3. 蔚来宣布部分车型涨价1万元
  4. 瑞幸“踩”着星巴克登顶?
  5. 近4年个人收款码数据将被追查补税?微信、支付宝紧急回应了
  6. Meta率先发布虚拟世界Horizon Worlds
  7. 他的产品成华强北山寨模板,仅次华为苹果,这个赛道杀入年轻黑马!
  8. realme GT大师版核心参数曝光:同样一亿像素主摄
  9. 荣耀V40屏幕素质得到“认证”:120Hz高刷屏没跑了
  10. 全新液体镜头专利曝光:华为P50系列拍照对焦速度堪比人眼