交互:可以执行命令行的框架才是好框架

news/2025/2/12 15:47:10/

上一节课,我们开始把框架向工业级迭代,重新规划了目录,这一节课将对框架做更大的改动,让框架支持命令行工具。

第三方命令行工具库 cobra

obra 不仅仅能让我们快速构建一个命令行,它更大的优势是能更快地组织起有许多命令行工具,因为从根命令行工具开始,cobra 把所有的命令按照树形结构组织起来了。

在这里插入图片描述
cobra库最核心的数据结构Command:

一个 Command 代表一个执行命令。这个 Command 包含很多可设置的字段,如何使用这个 Command,就取决于我们如何设置这些属性。下面是源码片段,我在注释中列出了这些属性的意义。


// Command代表执行命令的结构
type Command struct {// 代表当前命令的,如何执行,root 最好和生成的命令工具名称一致Use string// 代表这个工具的别名,在 subCommand 中有用,比如 root cmd1 和 root cmd_1 想要都执行一个 subCommand 就需要这样Aliases []string// 由于不强制设置,用于输入错误的时候建议字段SuggestFor []string// 这个就是在 help 的时候一句话描述这个命令的功能Short string// 详细描述这个命令的功能Long string// 例子Example string// 需要验证的参数ValidArgs []string// 有多少个参数,这里放了一个验证函数,可以是 ExactArgs,MaximumNArgs 等,验证有多少个参数Args PositionalArgs// 参数别名ArgAliases []string// 自动生成的命令设置BashCompletionFunction string// 如果这个命令已经废弃了,那么就这里写上废弃信息Deprecated string// 如果这个命令要被隐藏,设置这个字段Hidden bool// Annotations are key/value pairs that can be used by applications to identify or// group commands.Annotations map[string]string// 这个命令的版本Version string// 是否要打印错误信息SilenceErrors bool// 是否要打印如何使用SilenceUsage bool// 是否有 flag,如果这个命令没有 flag,设置为 true,那么所有的命令后面的参数都会是 argumentsDisableFlagParsing bool// 是否打印自动生成字样: ("Auto generated by spf13/cobra...")DisableAutoGenTag bool// 是否显示[flags]字样DisableFlagsInUseLine bool// 是否打印建议DisableSuggestions bool// 两个字符串的差距多少会进入 suggestSuggestionsMinimumDistance int// 是否使用 Traverse 的方式来解析参数TraverseChildren bool// 解析错误白名单, 比如像未知参数FParseErrWhitelist FParseErrWhitelist// The *Run 函数运行顺序://   * PersistentPreRun()//   * PreRun()//   * Run()//   * PostRun()//   * PersistentPostRun()// 会被继承的前置 RunPersistentPreRun func(cmd *Command, args []string)// 会被继承的前置 Run, 带 errorPersistentPreRunE func(cmd *Command, args []string) error// 当前这个命令的前置 RunPreRun func(cmd *Command, args []string)// 当前这个命令的前置 Run,带 ErrorPreRunE func(cmd *Command, args []string) error// zh: 实际跑的时候运行的函数Run func(cmd *Command, args []string)// zh: Run 执行错误了之后RunE func(cmd *Command, args []string) error// 后置运行PostRun func(cmd *Command, args []string)// 后置运行,带 errorPostRunE func(cmd *Command, args []string) error// 会被继承的后置运行PersistentPostRun func(cmd *Command, args []string)// 会被继承的后置运行,带 errorPersistentPostRunE func(cmd *Command, args []string) error}

具体使用的一个场景:


// InitFoo 初始化 Foo 命令
func InitFoo() *cobra.Command {FooCommand.AddCommand(Foo1Command)return FooCommand
}
// FooCommand 代表 Foo 命令
var FooCommand = &cobra.Command{Use:     "foo",Short:   "foo 的简要说明",Long:    "foo 的长说明",Aliases: []string{"fo", "f"},Example: "foo 命令的例子",RunE: func(c *cobra.Command, args []string) error {container := c.GetContainer()log.Println(container)return nil},
}
// Foo1Command 代表 Foo 命令的子命令 Foo1
var Foo1Command = &cobra.Command{Use:     "foo1",Short:   "foo1 的简要说明",Long:    "foo1 的长说明",Aliases: []string{"fo1", "f1"},Example: "foo1 命令的例子",RunE: func(c *cobra.Command, args []string) error {container := c.GetContainer()log.Println(container)return nil},
}
  • Use 代表这个命令的调用关键字,比如要调用 Foo1 命令,我们就要用 ./hade foo foo1 。Short 代表这个命令的简短说明,它会出现在上级命令的使用文档中。
  • Long 代表这个命令的长说明,它会出现在当前命令的使用文档中。
  • Aliases 是当前命令的别名,等同于 Use 字段;
  • Example 是当前命令的例子,也是显示在当前命令的使用文档中。

而 RunE 代表当前命令的真正执行函数:

RunE: func(c *cobra.Command, args []string) error 

这个执行函数的参数有两个:一个是 cobra.Command,表示当前的这个命令;而第二个参数是 args,表示当前这个命令的参数,返回值是一个 error,代表命令的执行成功或者失败。

如何使用命令行cobra

首先,引入到库,在framework目录下创建cobra目录,将v1.2.1版本的源码放置进去,删去其中的go.mod和go.sum, 然后全文替换github.com/spf13.cobra为自己的项目地址。

为了让cmd命令执行时从参数command中获取到容器,进而从服务容器获取到服务实例,我们将服务容器嵌入到Command结构中,因此将服务器容器挂载到根Command上,所有子命令通过Root()方法获取。

最后,使用命令行后,http服务的启动也是通过command的命令执行的,为了从容器中获取gin.engine,需要将engine也作为一个服务注册到容器中。

【小结】:

  1. cobra逐层构建command,运行通过RuneE函数
  2. 将gin.Engine和上节的app目录结构,都作为服务提供者注入到服务容器中

http://www.ppmy.cn/news/30724.html

相关文章

HTTPS简介

HTTPS是HTTP开启TLS传输协议,客户端要拿到服务端的公钥,用公钥加密数据后再进行传输,防止数据泄露后背篡改。它要解决两个问题:怎么保证公钥可信怎么加密数据公钥可信问题客户端从服务端获取公钥的时候,存在请求被拦截…

sort函数对结构体|pair对组|vector容器|map排序|二维数组的第x列 的排序

目录 sort对 vector容器 sort对 vector<pair<int,int>>对组 sort对 结构体 结构体外部规定排序 结构体内部运算符重载 map容器的排序 map的键排序 map的值排序 sort对二维数组的排序 sort对 vector容器 sort()函数可以用于对vector容器进行排序。具体来…

curl请求常用参数和返回码

curl是一个用于传输数据的工具&#xff0c;支持各种协议&#xff0c;如HTTP、FTP、SMTP等。以下是一些常用的curl请求参数及其作用&#xff1a; -X, --request&#xff1a;指定HTTP请求方法&#xff0c;常见的有GET、POST、PUT、DELETE等。 -H, --header&#xff1a;设置HTTP请…

【LeetCode】1. 两数之和

题目链接&#xff1a;https://leetcode.cn/problems/two-sum/ &#x1f4d5;题目要求&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入…

webview的工作、内存泄漏、漏洞以及缓存机制原理原理+方案解决

分析一段appium的日志来分析webview的工作原理&#xff0c;文章尾部附有自动化脚本及完整日志&#xff1a; 解析&#xff1a; 获取上下文列表 服务端发送命令adb shell cat /proc/net/unix获取域套接字列表。那什么是域套接字呢&#xff1f; 域套接字&#xff1a;是unix系统里…

c语言基础练习题详解

&#x1f49e;&#x1f49e; 1.C语言程序的基本单位是&#xff08;C&#xff09;。 A&#xff0e;程序行 B&#xff0e; 语句 C&#xff0e; 函数 D&#xff0e;字符 &#x1f49e;&#x1f49e; 2.已知各变量的类型说明如下&#xff1a; int m6,n,a,b; unsigned long w8;…

【Linux】-- 权限和Shell运行原理

目录 Shell的运行原理 用户切换 su - / su sudo 权限 chmod chown chgrp 八进制方法修改文件属性 目录权限 粘滞位 umask 自定义默认权限 Shell的运行原理 广义上&#xff0c;Linux发行版 Linux内核 外壳程序 Linux 从广义上来理解它是一个操作系统 而从狭义上…

云原生架构设计原则及典型技术

云原生是面向云应用设计的一种思想理念&#xff0c;充分发挥云效能的最佳实践路径&#xff0c;帮助企业构建弹性可靠、松耦合、易管理可观测的应用系统&#xff0c;提升交付效率&#xff0c;降低运维复杂度。代表技术包括不可变基础设施、服务网格、声明式 API 及 Serverless 等…