runningwater 8 місяців тому
батько
коміт
0858721bd7
6 змінених файлів з 127 додано та 42 видалено
  1. 27 0
      app/cmd/cmd.go
  2. 40 0
      app/cmd/serve.go
  3. 2 0
      go.mod
  4. 6 0
      go.sum
  5. 44 42
      main.go
  6. 8 0
      pkg/helpers/helpers.go

+ 27 - 0
app/cmd/cmd.go

@@ -0,0 +1,27 @@
+package cmd
+
+import (
+	"os"
+
+	"github.com/runningwater/gohub/pkg/helpers"
+	"github.com/spf13/cobra"
+)
+
+// Env 全局选项 --env 配置的值
+var Env string
+
+// RegisterGlobalFlags 注册全局选项(flag)
+func RegisterGlobalFlags(rootCmd *cobra.Command) {
+	rootCmd.PersistentFlags().StringVarP(&Env, "env", "e", "", "加载.env文件,如 --env=local, 加载的是.env.local 文件")
+}
+
+// RegisterDefaultCmd 注册默认命令
+func RegisterDefaultCmd(rootCmd *cobra.Command, subCmd *cobra.Command) {
+	cmd, _, err := rootCmd.Find(os.Args[1:])
+	firstArg := helpers.FirstElement(os.Args[1:])
+
+	if err == nil && cmd.Use == rootCmd.Use && firstArg != "-h" && firstArg != "--help" {
+		args := append([]string{subCmd.Use}, os.Args[1:]...)
+		rootCmd.SetArgs(args)
+	}
+}

+ 40 - 0
app/cmd/serve.go

@@ -0,0 +1,40 @@
+package cmd
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/runningwater/gohub/bootstrap"
+	"github.com/runningwater/gohub/pkg/config"
+	"github.com/runningwater/gohub/pkg/console"
+	"github.com/runningwater/gohub/pkg/logger"
+	"github.com/spf13/cobra"
+)
+
+var CmdServe = &cobra.Command{
+	Use:   "serve",
+	Short: "Start web server",
+	Long:  "Start the server - Gin server",
+	Run:   runWeb,
+	Args:  cobra.NoArgs,
+}
+
+func runWeb(cmd *cobra.Command, args []string) {
+	// 设置 gin 的运行模式, 支持 debug, release, test
+	// release 模式会屏蔽调试信息,官方建议生产环境中使用
+	// 非 release 模式 gin 终端打印太多信息,干扰到我们程序中的 Log
+	// 故此设置为 release 模式
+	gin.SetMode(gin.ReleaseMode)
+
+	// gin 框架初始化
+	router := gin.New()
+
+	// 初始化路由绑定
+	bootstrap.SetupRoute(router)
+
+	// 运行服务
+	err := router.Run(":" + config.Get("app.port"))
+	if err != nil {
+		logger.ErrorString("CMD", "serve", err.Error())
+		console.Exit("Unable to start server, error:" + err.Error())
+	}
+
+}

+ 2 - 0
go.mod

@@ -15,6 +15,7 @@ require (
 	github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
 	github.com/mojocn/base64Captcha v1.3.8
 	github.com/spf13/cast v1.7.1
+	github.com/spf13/cobra v1.9.1
 	github.com/spf13/viper v1.20.1
 	github.com/thedevsaddam/govalidator v1.9.10
 	go.uber.org/zap v1.27.0
@@ -45,6 +46,7 @@ require (
 	github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
+	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect

+ 6 - 0
go.sum

@@ -66,6 +66,7 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ
 github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
 github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -131,6 +132,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
@@ -193,6 +196,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
 github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -204,6 +208,8 @@ github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
 github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
 github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
 github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=

+ 44 - 42
main.go

@@ -1,14 +1,16 @@
 package main
 
 import (
-	"flag"
 	"fmt"
+	"os"
 
-	"github.com/gin-gonic/gin"
+	"github.com/spf13/cobra"
 
+	"github.com/runningwater/gohub/app/cmd"
 	"github.com/runningwater/gohub/bootstrap"
 	appConfig "github.com/runningwater/gohub/config"
 	"github.com/runningwater/gohub/pkg/config"
+	"github.com/runningwater/gohub/pkg/console"
 )
 
 func init() {
@@ -17,45 +19,45 @@ func init() {
 }
 
 func main() {
-	//  配置初始化,依赖命令行 --env 参数
-	var env string
-	flag.StringVar(&env, "env", "", "加载.env 文件,如 --env=local, 加载的是 .env.local 文件")
-	flag.Parse()
-	config.InitConfig(env)
-
-	// 初始化 Logger
-	bootstrap.SetupLogger()
-
-	// 初始化 DB
-	// 注意: 初始化 DB 前应该先初始化 logger
-	bootstrap.SetupDB()
-
-	// 初始化 Redis
-	bootstrap.SetupRedis()
-
-	// gin 框架设置为发布模式,线上环境需要设置
-	gin.SetMode(gin.ReleaseMode)
-
-	// Gin 框架初始化
-	r := gin.New()
-
-	// 初始化路由绑定
-	bootstrap.SetupRoute(r)
-
-	// r.GET("/test_auth", middlewares.AuthJWT(), func(c *gin.Context) {
-	// 	userModle := auth.CurrentUser(c)
-	// 	response.Data(c, userModle)
-	// })
-	// r.GET("/test_gust", middlewares.GuestJWT(), func(c *gin.Context) {
-	// 	response.Data(c, "hello")
-	// })
-
-	// 测试发送短信
-	// verifycode.NewVerifyCode().SendSMS("15968875425")
-
-	// 启动 HTTP 服务,监听在我们指定的端口上
-	err := r.Run(":" + config.Get("app.port"))
-	if err != nil {
-		fmt.Println("启动失败", err.Error())
+
+	// 应用主入口,默认调用 cmd.CmdServe 命令
+	// 该命令会启动 HTTP 服务
+	var rootCmd = &cobra.Command{
+		Use:   "gohub",
+		Short: "gohub is a simple forum project",
+		Long:  `Default will run "serve" command, you can use "-h" flag to see all subcommands`,
+
+		// 所有子命令都会调用以下代码来初始化配置信息
+		PersistentPreRun: func(command *cobra.Command, args []string) {
+			// 配置初始化,依赖命令行 --env 参数
+			config.InitConfig(cmd.Env)
+			// 初始化 Logger
+			bootstrap.SetupLogger()
+
+			// 初始化 DB
+			// 注意: 初始化 DB 前应该先初始化 logger
+			bootstrap.SetupDB()
+
+			// 初始化 Redis
+			bootstrap.SetupRedis()
+		},
+	}
+
+	// 注册子命令
+	rootCmd.AddCommand(
+		cmd.CmdServe,
+		// cmd.CmdKey,
+		// cmd.CmdPlay,
+	)
+
+	// 配置默认运行 Web 服务
+	cmd.RegisterDefaultCmd(rootCmd, cmd.CmdServe)
+
+	// 注册全局参数 --env
+	cmd.RegisterGlobalFlags(rootCmd)
+
+	// 执行主命令
+	if err := rootCmd.Execute(); err != nil {
+		console.Exit(fmt.Sprintf("Failed to run app with %v: %s", os.Args, err.Error()))
 	}
 }

+ 8 - 0
pkg/helpers/helpers.go

@@ -54,3 +54,11 @@ func RandomNumber(length int) string {
 	}
 	return string(b)
 }
+
+// FirstElement 获取 args[0],避免 panic
+func FirstElement(args []string) string {
+	if len(args) > 0 {
+		return args[0]
+	}
+	return ""
+}