first commit
This commit is contained in:
commit
ecdea80122
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/scaffold.iml" filepath="$PROJECT_DIR$/.idea/scaffold.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
9
.idea/scaffold.iml
Normal file
9
.idea/scaffold.iml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
170
main.go
Normal file
170
main.go
Normal file
@ -0,0 +1,170 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var (
|
||||
localTemplatePath string
|
||||
remoteTemplatePath string
|
||||
projectName string
|
||||
branch string
|
||||
)
|
||||
|
||||
flag.StringVar(&localTemplatePath, "local", "", "本地模板路径")
|
||||
flag.StringVar(&remoteTemplatePath, "remote", "", "远程仓库url")
|
||||
flag.StringVar(&projectName, "name", "", "项目名称")
|
||||
flag.StringVar(&branch, "branch", "main", "要使用的分支(仅当模板是远程仓库时)")
|
||||
|
||||
flag.Parse()
|
||||
if localTemplatePath == "" && remoteTemplatePath == "" {
|
||||
log.Println("请指定本地模板路径或远程仓库url")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if projectName == "" {
|
||||
log.Println("请指定项目名称")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
templatePath := ""
|
||||
if localTemplatePath != "" {
|
||||
templatePath = localTemplatePath
|
||||
}
|
||||
|
||||
if remoteTemplatePath != "" {
|
||||
templatePath = remoteTemplatePath
|
||||
}
|
||||
|
||||
replacements := getReplacements()
|
||||
if _, ok := replacements["{{PROJECT_NAME}}"]; !ok {
|
||||
replacements["{{PROJECT_NAME}}"] = projectName
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if remoteTemplatePath != "" {
|
||||
err = handleRemoteTemplate(templatePath, branch, projectName, replacements)
|
||||
} else {
|
||||
err = copyTemplate(templatePath, projectName, replacements)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error creating project: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("Project %s created successfully!\n", projectName)
|
||||
}
|
||||
|
||||
func handleRemoteTemplate(templateRepo, branch, projectName string, replacements map[string]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, projectName, replacements)
|
||||
}
|
||||
|
||||
func getReplacements() map[string]string {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
replacements := make(map[string]string)
|
||||
fmt.Println("输入替换值(key=value),空行结束: ")
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
scanner.Scan()
|
||||
line := scanner.Text()
|
||||
if line == "" {
|
||||
break
|
||||
}
|
||||
|
||||
splits := strings.Split(line, "=")
|
||||
if len(splits) != 2 {
|
||||
fmt.Println("无效输入,请以key=value格式输入")
|
||||
continue
|
||||
}
|
||||
|
||||
replacements[splits[0]] = splits[1]
|
||||
}
|
||||
|
||||
return replacements
|
||||
}
|
||||
|
||||
func copyTemplate(src, dist string, replacements map[string]string) (err error) {
|
||||
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() {
|
||||
// 创建目录
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user