优化命令提示
This commit is contained in:
		
							parent
							
								
									086e30c6ca
								
							
						
					
					
						commit
						9d673b8066
					
				
							
								
								
									
										34
									
								
								cmd/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								cmd/cmd.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	template = "git@golib-ssh.gaore.com:GaoreGo/hertz_demo.git"
 | 
			
		||||
	project  string
 | 
			
		||||
	branch   = "master"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var rootCmd = &cobra.Command{
 | 
			
		||||
	Use:   "hertz_scaffold",
 | 
			
		||||
	Short: "hertz框架脚手架",
 | 
			
		||||
	Long:  `以golib.gaore.com/GaoreGo/hertz_demo为模板的脚手架`,
 | 
			
		||||
	Run: func(cmd *cobra.Command, args []string) {
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Execute 执行命令
 | 
			
		||||
func Execute() {
 | 
			
		||||
	if err := rootCmd.Execute(); err != nil {
 | 
			
		||||
		log.Panicln(err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	rootCmd.AddCommand(createCmd)
 | 
			
		||||
	rootCmd.AddCommand(updateCmd)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								cmd/create.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								cmd/create.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var createCmd = &cobra.Command{
 | 
			
		||||
	Use:   "create",
 | 
			
		||||
	Short: "创建一个新项目",
 | 
			
		||||
	Long:  `通过hertz_demo为模板创建一个新项目`,
 | 
			
		||||
	Run: func(cmd *cobra.Command, args []string) {
 | 
			
		||||
		handleCreateCommand(args)
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	createCmd.Flags().StringVarP(&project, "project", "p", "", "项目名称")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleCreateCommand(args []string) {
 | 
			
		||||
	err := handleRemoteTemplate(template, branch, project)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("Error creating project: %s\n", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("Project %s created successfully!\n", project)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								cmd/helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								cmd/helpers.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
			
		||||
package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getModuleName(goModPath string) (string, error) {
 | 
			
		||||
	content, err := os.ReadFile(goModPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lines := strings.Split(string(content), "\n")
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		if strings.HasPrefix(line, "module ") {
 | 
			
		||||
			return strings.TrimSpace(strings.TrimPrefix(line, "module ")), nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "", fmt.Errorf("module name not found in go.mod")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleRemoteTemplate(templateRepo, branch, projectPath string) (err error) {
 | 
			
		||||
	// 创建临时目录
 | 
			
		||||
	tempDir, err := os.MkdirTemp("", "template-*")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error creating temporary directory: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 清理临时目录
 | 
			
		||||
	defer os.RemoveAll(tempDir)
 | 
			
		||||
 | 
			
		||||
	// 克隆模板仓库
 | 
			
		||||
	cloneCmd := exec.Command("git", "clone", "-b", branch, templateRepo, tempDir)
 | 
			
		||||
	cloneCmd.Stdout = io.Discard
 | 
			
		||||
	cloneCmd.Stderr = os.Stderr
 | 
			
		||||
 | 
			
		||||
	if err = cloneCmd.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("error cloning template repository: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return copyTemplate(tempDir, projectPath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func copyTemplate(src, dist string) (err error) {
 | 
			
		||||
	// 读取 go.mod 文件中的模块名称
 | 
			
		||||
	oldModuleName, err := getModuleName(filepath.Join(src, "go.mod"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("error reading module name: %s", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
	replacements := map[string]string{
 | 
			
		||||
		oldModuleName: filepath.Base(dist),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 获取相对路径
 | 
			
		||||
		relPath, err := filepath.Rel(src, path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 获取目标路径
 | 
			
		||||
		targetPath := filepath.Join(dist, relPath)
 | 
			
		||||
 | 
			
		||||
		if info.IsDir() && filepath.Base(path) == ".git" {
 | 
			
		||||
			return filepath.SkipDir
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if info.IsDir() {
 | 
			
		||||
			// 创建目录
 | 
			
		||||
			return os.MkdirAll(targetPath, info.Mode())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return copyAndReplaceFile(path, targetPath, info.Mode(), replacements)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func copyAndReplaceFile(src, dist string, mode os.FileMode, replacements map[string]string) (err error) {
 | 
			
		||||
 | 
			
		||||
	// 读取源文件
 | 
			
		||||
	sourceFile, err := os.Open(src)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer sourceFile.Close()
 | 
			
		||||
 | 
			
		||||
	content, err := io.ReadAll(sourceFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newContent := string(content)
 | 
			
		||||
	for key, value := range replacements {
 | 
			
		||||
		newContent = strings.ReplaceAll(newContent, key, value)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 读取目标文件
 | 
			
		||||
	targetFile, err := os.OpenFile(dist, os.O_CREATE|os.O_RDWR|os.O_TRUNC, mode)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer targetFile.Close()
 | 
			
		||||
 | 
			
		||||
	_, err = targetFile.WriteString(newContent)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								cmd/update.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								cmd/update.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var updateCmd = &cobra.Command{
 | 
			
		||||
	Use:   "update",
 | 
			
		||||
	Short: "更新项目",
 | 
			
		||||
	Long:  `Update the current project`,
 | 
			
		||||
	Run: func(cmd *cobra.Command, args []string) {
 | 
			
		||||
		fmt.Println("还没做")
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.mod
									
									
									
									
									
								
							@ -1,3 +1,9 @@
 | 
			
		||||
module golib.gaore.com/xuy2/hertz_scaffold
 | 
			
		||||
 | 
			
		||||
go 1.20
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 | 
			
		||||
	github.com/spf13/cobra v1.8.1 // indirect
 | 
			
		||||
	github.com/spf13/pflag v1.0.5 // indirect
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
			
		||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 | 
			
		||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 | 
			
		||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
			
		||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
 | 
			
		||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
 | 
			
		||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 | 
			
		||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
			
		||||
							
								
								
									
										163
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								main.go
									
									
									
									
									
								
							@ -2,167 +2,8 @@
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
import "golib.gaore.com/xuy2/hertz_scaffold/cmd"
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
 | 
			
		||||
	if len(os.Args) < 2 {
 | 
			
		||||
		fmt.Println("Usage: hertz_scaffold create -p <project_name>")
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 解析子命令
 | 
			
		||||
	subCommand := os.Args[1]
 | 
			
		||||
	if subCommand != "create" && subCommand != "update" {
 | 
			
		||||
		log.Printf("Unknown subcommand: %s\n", subCommand)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch subCommand {
 | 
			
		||||
	case "create":
 | 
			
		||||
		handleCreateCommand(os.Args[2:])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleCreateCommand(args []string) {
 | 
			
		||||
	var (
 | 
			
		||||
		template    = "git@golib-ssh.gaore.com:GaoreGo/hertz_demo.git"
 | 
			
		||||
		branch      = "master"
 | 
			
		||||
		projectPath string
 | 
			
		||||
		err         error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	flagSet := flag.NewFlagSet("create", flag.ExitOnError)
 | 
			
		||||
	flagSet.StringVar(&projectPath, "p", "", "Path to the new project")
 | 
			
		||||
	flagSet.Parse(args)
 | 
			
		||||
 | 
			
		||||
	if projectPath == "" {
 | 
			
		||||
		log.Printf("Error: -p flag is required\n")
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = handleRemoteTemplate(template, branch, projectPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("Error creating project: %s\n", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("Project %s created successfully!\n", projectPath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getModuleName(goModPath string) (string, error) {
 | 
			
		||||
	content, err := os.ReadFile(goModPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lines := strings.Split(string(content), "\n")
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		if strings.HasPrefix(line, "module ") {
 | 
			
		||||
			return strings.TrimSpace(strings.TrimPrefix(line, "module ")), nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "", fmt.Errorf("module name not found in go.mod")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleRemoteTemplate(templateRepo, branch, projectPath string) (err error) {
 | 
			
		||||
	// 创建临时目录
 | 
			
		||||
	tempDir, err := os.MkdirTemp("", "template-*")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error creating temporary directory: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 清理临时目录
 | 
			
		||||
	defer os.RemoveAll(tempDir)
 | 
			
		||||
 | 
			
		||||
	// 克隆模板仓库
 | 
			
		||||
	cloneCmd := exec.Command("git", "clone", "-b", branch, templateRepo, tempDir)
 | 
			
		||||
	cloneCmd.Stdout = os.Stdout
 | 
			
		||||
	cloneCmd.Stderr = os.Stderr
 | 
			
		||||
 | 
			
		||||
	if err = cloneCmd.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("error cloning template repository: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return copyTemplate(tempDir, projectPath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func copyTemplate(src, dist string) (err error) {
 | 
			
		||||
	// 读取 go.mod 文件中的模块名称
 | 
			
		||||
	oldModuleName, err := getModuleName(filepath.Join(src, "go.mod"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("error reading module name: %s", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
	replacements := map[string]string{
 | 
			
		||||
		oldModuleName: filepath.Base(dist),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 获取相对路径
 | 
			
		||||
		relPath, err := filepath.Rel(src, path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 获取目标路径
 | 
			
		||||
		targetPath := filepath.Join(dist, relPath)
 | 
			
		||||
 | 
			
		||||
		if info.IsDir() && filepath.Base(path) == ".git" {
 | 
			
		||||
			return filepath.SkipDir
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if info.IsDir() {
 | 
			
		||||
			// 创建目录
 | 
			
		||||
			return os.MkdirAll(targetPath, info.Mode())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return copyAndReplaceFile(path, targetPath, info.Mode(), replacements)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func copyAndReplaceFile(src, dist string, mode os.FileMode, replacements map[string]string) (err error) {
 | 
			
		||||
 | 
			
		||||
	// 读取源文件
 | 
			
		||||
	sourceFile, err := os.Open(src)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer sourceFile.Close()
 | 
			
		||||
 | 
			
		||||
	content, err := io.ReadAll(sourceFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newContent := string(content)
 | 
			
		||||
	for key, value := range replacements {
 | 
			
		||||
		newContent = strings.ReplaceAll(newContent, key, value)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 读取目标文件
 | 
			
		||||
	targetFile, err := os.OpenFile(dist, os.O_CREATE|os.O_RDWR|os.O_TRUNC, mode)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer targetFile.Close()
 | 
			
		||||
 | 
			
		||||
	_, err = targetFile.WriteString(newContent)
 | 
			
		||||
	return
 | 
			
		||||
	cmd.Execute()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user