From 7187205143158a0c8e93a10f0d46a1b3c16d7f12 Mon Sep 17 00:00:00 2001 From: Rogee Date: Wed, 10 Sep 2025 14:38:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=A1=8C=E5=B7=A5=E5=85=B7=E7=9A=84=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=8C=E5=8C=85=E6=8B=AC=E8=B7=AF=E5=BE=84=E3=80=81?= =?UTF-8?q?=E5=B9=B2=E8=BF=90=E8=A1=8C=E6=A8=A1=E5=BC=8F=E5=92=8C=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E7=9B=AE=E5=BD=95=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/buf.go | 31 ++++++++++++++++++++------- cmd/fmt.go | 50 +++++++++++++++++++++++++++++------------- cmd/gen_model.go | 47 ++++++++++++++++++++++++---------------- cmd/gen_route.go | 42 +++++++++++++++++++++--------------- cmd/migrate.go | 25 ++++++++++++--------- cmd/swag_fmt.go | 27 +++++++++++++---------- cmd/swag_init.go | 56 +++++++++++++++++++++++++++--------------------- 7 files changed, 174 insertions(+), 104 deletions(-) diff --git a/cmd/buf.go b/cmd/buf.go index 01b4ada..e3cf3b3 100644 --- a/cmd/buf.go +++ b/cmd/buf.go @@ -9,16 +9,21 @@ import ( ) func CommandBuf(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "buf", - Short: "run buf commands", - RunE: commandBufE, - } + cmd := &cobra.Command{ + Use: "buf", + Short: "run buf commands", + RunE: commandBufE, + } + + cmd.Flags().String("dir", ".", "Directory to run buf from") + cmd.Flags().Bool("dry-run", false, "Preview buf command without executing") root.AddCommand(cmd) } func commandBufE(cmd *cobra.Command, args []string) error { + dir := cmd.Flag("dir").Value.String() + dryRun, _ := cmd.Flags().GetBool("dry-run") if _, err := exec.LookPath("buf"); err != nil { log.Warn("buf 命令不存在,正在安装 buf...") log.Info("go install github.com/bufbuild/buf/cmd/buf@v1.48.0") @@ -33,9 +38,19 @@ func commandBufE(cmd *cobra.Command, args []string) error { } } - log.Info("buf 命令已存在,正在运行 buf generate...") - log.Info("PROTOBUF GUIDE: https://buf.build/docs/best-practices/style-guide/") - generateCmd := exec.Command("buf", "generate") + // preflight: ensure buf.yaml exists + if _, err := os.Stat(filepath.Join(dir, "buf.yaml")); err != nil { + log.Warnf("未找到 %s,buf generate 可能失败", filepath.Join(dir, "buf.yaml")) + } + + log.Info("buf 命令已存在,正在运行 buf generate...") + log.Info("PROTOBUF GUIDE: https://buf.build/docs/best-practices/style-guide/") + if dryRun { + log.Infof("[dry-run] (cd %s && buf generate)", dir) + return nil + } + generateCmd := exec.Command("buf", "generate") + generateCmd.Dir = dir if err := generateCmd.Run(); err != nil { return fmt.Errorf("运行 buf generate 失败: %v", err) } diff --git a/cmd/fmt.go b/cmd/fmt.go index 6c826d6..8db64f6 100644 --- a/cmd/fmt.go +++ b/cmd/fmt.go @@ -10,17 +10,20 @@ import ( ) func CommandFmt(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "fmt", - Short: "fmt codes", - RunE: commandFmtE, - } + cmd := &cobra.Command{ + Use: "fmt", + Short: "fmt codes", + RunE: commandFmtE, + } + + cmd.Flags().Bool("check", false, "Check formatting without writing changes") + cmd.Flags().String("path", ".", "Path to format (default .)") root.AddCommand(cmd) } func commandFmtE(cmd *cobra.Command, args []string) error { - log.Info("开始格式化代码") + log.Info("开始格式化代码") if _, err := exec.LookPath("gofumpt"); err != nil { log.Info("gofumpt 不存在,正在安装...") installCmd := exec.Command("go", "install", "mvdan.cc/gofumpt@latest") @@ -34,14 +37,31 @@ func commandFmtE(cmd *cobra.Command, args []string) error { } } - log.Info("运行 gofumpt...") - gofumptCmd := exec.Command("gofumpt", "-l", "-extra", "-w", ".") - gofumptCmd.Stdout = os.Stdout - gofumptCmd.Stderr = os.Stderr - if err := gofumptCmd.Run(); err != nil { - return fmt.Errorf("运行 gofumpt 失败: %v", err) - } + check, _ := cmd.Flags().GetBool("check") + path, _ := cmd.Flags().GetString("path") - log.Info("格式化代码完成") - return nil + if check { + log.Info("运行 gofumpt 检查模式...") + out, err := exec.Command("gofumpt", "-l", "-extra", path).CombinedOutput() + if err != nil { + return fmt.Errorf("运行 gofumpt 失败: %v", err) + } + if len(out) > 0 { + fmt.Fprintln(os.Stdout, string(out)) + return fmt.Errorf("发现未格式化文件,请运行: gofumpt -l -extra -w %s", path) + } + log.Info("代码格式良好") + return nil + } + + log.Info("运行 gofumpt...") + gofumptCmd := exec.Command("gofumpt", "-l", "-extra", "-w", path) + gofumptCmd.Stdout = os.Stdout + gofumptCmd.Stderr = os.Stderr + if err := gofumptCmd.Run(); err != nil { + return fmt.Errorf("运行 gofumpt 失败: %v", err) + } + + log.Info("格式化代码完成") + return nil } diff --git a/cmd/gen_model.go b/cmd/gen_model.go index e8c6f72..1d28f47 100644 --- a/cmd/gen_model.go +++ b/cmd/gen_model.go @@ -25,12 +25,16 @@ import ( ) func CommandGenModel(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "model", - Aliases: []string{"m"}, - Short: "Generate jet models", - RunE: commandGenModelE, - } + cmd := &cobra.Command{ + Use: "model", + Aliases: []string{"m"}, + Short: "Generate jet models", + RunE: commandGenModelE, + } + + cmd.Flags().String("schema", "", "Override database schema") + cmd.Flags().Bool("rename-schemas", true, "Rename generated database/ to database/schemas") + cmd.Flags().String("schemas-out", "database/schemas", "Schemas output directory when renaming") root.AddCommand(cmd) } @@ -40,10 +44,15 @@ func commandGenModelE(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "parse go.mod") } - _, dbConf, err := pgDatabase.GetDB(cmd.Flag("config").Value.String()) - if err != nil { - return errors.Wrap(err, "get db") - } + _, dbConf, err := pgDatabase.GetDB(cmd.Flag("config").Value.String()) + if err != nil { + return errors.Wrap(err, "get db") + } + + // optional schema override + if s := cmd.Flag("schema").Value.String(); s != "" { + dbConf.Schema = s + } v := viper.New() v.SetConfigType("yaml") @@ -166,14 +175,16 @@ func commandGenModelE(cmd *cobra.Command, args []string) error { return err } - if err := os.RemoveAll("database/schemas"); err != nil { - return err - } - - dataPath := fmt.Sprintf("database/%s", cfg.Database) - if err := os.Rename(dataPath, "database/schemas"); err != nil { - return err - } + if rename, _ := cmd.Flags().GetBool("rename-schemas"); rename { + out := cmd.Flag("schemas-out").Value.String() + if err := os.RemoveAll(out); err != nil { + return err + } + dataPath := fmt.Sprintf("database/%s", cfg.Database) + if err := os.Rename(dataPath, out); err != nil { + return err + } + } if err := astModel.Generate(generatedTables, transformer); err != nil { return err diff --git a/cmd/gen_route.go b/cmd/gen_route.go index 6b5e0a3..653631e 100644 --- a/cmd/gen_route.go +++ b/cmd/gen_route.go @@ -1,6 +1,7 @@ package cmd import ( + "fmt" "io/fs" "os" "path/filepath" @@ -14,28 +15,35 @@ import ( ) func CommandGenRoute(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "route", - Short: "generate routes", - RunE: commandGenRouteE, - PostRunE: commandGenProviderE, - } + cmd := &cobra.Command{ + Use: "route", + Short: "generate routes", + RunE: commandGenRouteE, + PostRunE: commandGenProviderE, + } - root.AddCommand(cmd) + cmd.Flags().String("path", ".", "Base path to scan (defaults to CWD)") + + root.AddCommand(cmd) } // https://go.ipao.vip/atomctl/pkg/swag?tab=readme-ov-file#api-operation func commandGenRouteE(cmd *cobra.Command, args []string) error { - var err error - var path string - if len(args) > 0 { - path = args[0] - } else { - path, err = os.Getwd() - if err != nil { - return err - } - } + var err error + var path string + if len(args) > 0 { + path = args[0] + } else { + path, err = os.Getwd() + if err != nil { + return err + } + } + + // allow overriding via --path flag + if f := cmd.Flag("path"); f != nil && f.Value.String() != "." && f.Value.String() != "" { + path = f.Value.String() + } path, _ = filepath.Abs(path) diff --git a/cmd/migrate.go b/cmd/migrate.go index 6cc2216..1e80da0 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -13,12 +13,14 @@ import ( // migrate func CommandMigrate(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "migrate [up|up-by-one|up-to|create|down|down-to|fix|redo|reset|status|version]", - Aliases: []string{"m"}, - RunE: commandMigrate, - } - cmd.Flags().StringP("config", "c", "config.toml", "database config file") + cmd := &cobra.Command{ + Use: "migrate [up|up-by-one|up-to|create|down|down-to|fix|redo|reset|status|version]", + Aliases: []string{"m"}, + RunE: commandMigrate, + } + cmd.Flags().StringP("config", "c", "config.toml", "database config file") + cmd.Flags().String("dir", "database/migrations", "migrations directory") + cmd.Flags().String("table", "migrations", "migrations table name") root.AddCommand(cmd) } @@ -39,10 +41,13 @@ func commandMigrate(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "get db") } - action, args := args[0], args[1:] - log.Infof("migration action: %s args: %+v", action, args) + action, args := args[0], args[1:] + log.Infof("migration action: %s args: %+v", action, args) - goose.SetTableName("migrations") + dir := cmd.Flag("dir").Value.String() + table := cmd.Flag("table").Value.String() - return goose.RunContext(context.Background(), action, db, "database/migrations", args...) + goose.SetTableName(table) + + return goose.RunContext(context.Background(), action, db, dir, args...) } diff --git a/cmd/swag_fmt.go b/cmd/swag_fmt.go index 180bc43..c3e8419 100644 --- a/cmd/swag_fmt.go +++ b/cmd/swag_fmt.go @@ -6,20 +6,25 @@ import ( ) func CommandSwagFmt(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "fmt", - Aliases: []string{"f"}, - Short: "swag format", - RunE: commandSwagFmtE, - } + cmd := &cobra.Command{ + Use: "fmt", + Aliases: []string{"f"}, + Short: "swag format", + RunE: commandSwagFmtE, + } + + cmd.Flags().String("dir", "./app/http", "SearchDir for swag format") + cmd.Flags().String("main", "main.go", "MainFile for swag format") root.AddCommand(cmd) } func commandSwagFmtE(cmd *cobra.Command, args []string) error { - return format.New().Build(&format.Config{ - SearchDir: "./app/http", - Excludes: "", - MainFile: "main.go", - }) + dir := cmd.Flag("dir").Value.String() + main := cmd.Flag("main").Value.String() + return format.New().Build(&format.Config{ + SearchDir: dir, + Excludes: "", + MainFile: main, + }) } diff --git a/cmd/swag_init.go b/cmd/swag_init.go index eeb0c7d..7c97fe3 100644 --- a/cmd/swag_init.go +++ b/cmd/swag_init.go @@ -11,39 +11,45 @@ import ( ) func CommandSwagInit(root *cobra.Command) { - cmd := &cobra.Command{ - Use: "init", - Short: "swag init", - Aliases: []string{"i"}, - RunE: commandSwagInitE, - } + cmd := &cobra.Command{ + Use: "init", + Short: "swag init", + Aliases: []string{"i"}, + RunE: commandSwagInitE, + } + + cmd.Flags().String("dir", ".", "SearchDir (project root)") + cmd.Flags().String("out", "docs", "Output dir for generated docs") + cmd.Flags().String("main", "main.go", "Main API file path") root.AddCommand(cmd) } func commandSwagInitE(cmd *cobra.Command, args []string) error { - pwd, err := os.Getwd() - if err != nil { - return err - } - if len(args) > 0 { - pwd = args[0] - } + root := cmd.Flag("dir").Value.String() + if root == "" { + var err error + root, err = os.Getwd() + if err != nil { return err } + } leftDelim, rightDelim := "{{", "}}" - return gen.New().Build(&gen.Config{ - SearchDir: pwd, - Excludes: "", - ParseExtension: "", - MainAPIFile: "main.go", - PropNamingStrategy: swag.CamelCase, - OutputDir: filepath.Join(pwd, "docs"), - OutputTypes: []string{"go", "json", "yaml"}, - ParseVendor: false, - ParseDependency: 0, - MarkdownFilesDir: "", - ParseInternal: false, + outDir := cmd.Flag("out").Value.String() + mainFile := cmd.Flag("main").Value.String() + + return gen.New().Build(&gen.Config{ + SearchDir: root, + Excludes: "", + ParseExtension: "", + MainAPIFile: mainFile, + PropNamingStrategy: swag.CamelCase, + OutputDir: filepath.Join(root, outDir), + OutputTypes: []string{"go", "json", "yaml"}, + ParseVendor: false, + ParseDependency: 0, + MarkdownFilesDir: "", + ParseInternal: false, Strict: false, GeneratedTime: false, RequiredByDefault: false,