使用命令启动服务
例如
初始化
vblog-api init
启动服务
vblog-api start -f etc/confit.toml
版本号
vblog-api -v
需要借助一个强大的CLI库 Cobra
https://github.com/spf13/cobra
安装
go get -u github.com/spf13/cobra@latest
迁移服务
修改入口文件main.go
package main
import (
_ "gitee.com/hexug/vblog/tree/master/api/apps/all"
"gitee.com/hexug/vblog/tree/master/api/cmd"
)
func main() {
//conf.LoadConfigFromToml("etc/config.toml")
//conf.LoadConfigFromEnv()
//logger.L().Infoln("配置读取完成。")
//apps.InitApps()
//logger.L().Infoln("app初始化完成")
////gin.SetMode(gin.ReleaseMode)
//engine := gin.Default()
//router := engine.Group("/vblog/api/v1")
//apps.InitApis(router)
//svc := conf.C().Server
//engine.Run(fmt.Sprintf("%s:%d", svc.Host, svc.Port))
//将上面的逻辑都迁移到start命令下
//在这里只要执行命令的入口函数就好了
cmd.Execute()
}
创建最顶层的命令
package cmd
import (
"fmt"
"gitee.com/hexug/vblog/tree/master/api/cmd/initial"
"gitee.com/hexug/vblog/tree/master/api/cmd/start"
"github.com/spf13/cobra"
)
var (
version bool
//创建根命令
rootCmd = &cobra.Command{
/*
Use是单行用法消息。
建议的语法如下:
[]标识可选参数。不包含在括号中的参数是必需的。
...表示可以为上一个参数指定多个值。
\表示互斥信息。可以使用分隔符左侧的参数或分隔符右侧的参数。不能在一次使用命令时同时使用两个参数。
{}在需要其中一个参数时分隔一组互斥参数。如果参数为可选,它们用括号([])括起来。
示例:add [-F file | -D dir]... [-f format] file
*/
Use: "vblog-api",
// short是“help”输出中显示的简短描述。
Short: "vblog的后端服务",
// Long是“help<this command>”输出中显示的长消息。
Long: "一个前后端分离的vblog demo",
//Example是如何使用该命令的示例。
Example: "vblog-api -v",
/*
//钩子函数
// PersistentPeRun:此命令的子级将继承并执行。
PersistentPreRun func(cmd *Command, args []string)
// PreRun: 此命令的子级将不会继承。
PreRun func(cmd *Command, args []string)
// Run: 通常为实际工作的函数。大多数命令只会实现这一点。
Run func(cmd *Command, args []string)
// PostRun: 在“Run”之后运行。
PostRun func(cmd *Command, args []string)
// PersistentPostRun: 此命令的子级将在PostRun之后继承并执行。
PersistentPostRun func(cmd *Command, args []string)
*/
Run: func(cmd *cobra.Command, args []string) {
//当带了version参数,就打印版本号
if version {
fmt.Println("vblog-api Version 1.0.1")
return
}
//否则打印帮助信息
err := cmd.Help()
cobra.CheckErr(err)
},
}
)
func Execute() {
//添加其他子命令
rootCmd.AddCommand(initial.Cmd)
rootCmd.AddCommand(start.Cmd)
//执行根命令的入口函数
if err := rootCmd.Execute(); err != nil {
//fmt.Fprintln(os.Stderr, err)
//os.Exit(1)
return
}
}
//初始化的时候获取参数的值 绑定了一个本地变量version 用来显示版本
func init() {
rootCmd.Flags().BoolVarP(&version, "version", "v", false, "版本")
}
创建子命令
初始化子命令,这里未实现具体逻辑
package initial
import (
"github.com/spf13/cobra"
)
var (
Cmd = &cobra.Command{
Use: "init",
Short: "初始化",
Long: "初始化",
Run: func(cmd *cobra.Command, args []string) {
cmd.Println("这是初始化的命令")
cmd.Println("尚未实现")
},
}
)
启动服务的子命令
package start
import (
"fmt"
"gitee.com/hexug/vblog/tree/master/api/apps"
"gitee.com/hexug/vblog/tree/master/api/conf"
"gitee.com/hexug/vblog/tree/master/api/logger"
"github.com/gin-gonic/gin"
"github.com/spf13/cobra"
)
var (
configType string
configPath string
Cmd = &cobra.Command{
Use: "start",
Short: "启动服务",
Long: "启动服务",
Example: "vblog-api start -t file -f etc/config.toml",
Run: func(cmd *cobra.Command, args []string) {
//判断指定的配置文件类型
switch configType {
case "file":
cmd.Println("从file加载配置文件:", configPath)
conf.LoadConfigFromToml(configPath)
case "env":
cmd.Println("从环境变量加载配置")
conf.LoadConfigFromEnv()
case "etcd":
cmd.Println("尚未实现")
return
default:
cmd.PrintErrln("选择的加载配置类型有误,目前只允许['file','env','etcd']")
return
}
logger.L().Infoln("配置加载完成。")
apps.InitApps()
logger.L().Infoln("app初始化完成")
//gin.SetMode(gin.ReleaseMode)
engine := gin.Default()
router := engine.Group("/vblog/api/v1")
apps.InitApis(router)
svc := conf.C().Server
err := engine.Run(fmt.Sprintf("%s:%d", svc.Host, svc.Port))
if err != nil {
cmd.Println(err.Error())
}
},
}
)
func init() {
//给start命令添加flag
Cmd.Flags().StringVarP(&configType, "config-type", "t", "file", "指定加载配置的类型")
Cmd.Flags().StringVarP(&configPath, "config-path", "f", "etc/config.toml", "指定配置文件")
}
标签:cobra,vblog,CLI,--,cmd,api,func,工程化,com
From: https://www.cnblogs.com/guangdelw/p/17034045.html