代码拉取完成,页面将自动刷新
同步操作将从 tanghc/code-gen 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"gopkg.in/yaml.v3"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
)
type CodeFile struct {
Folder string `json:"folder"`
FileName string `json:"fileName"`
Content string `json:"content"`
}
type GeneratorParam struct {
DatasourceConfigId uint64 `json:"datasourceConfigId"`
TableNames []string `json:"tableNames"`
TemplateConfigGroupName string `json:"templateConfigGroupName"`
PackageName string `json:"packageName"`
DelPrefix string `json:"delPrefix"`
Author string `json:"author"`
Charset string `json:"charset"`
BizName string `json:"bizName"`
}
type Result struct {
Code string `json:"code"`
Data []CodeFile `json:"data"`
Msg string `json:"msg"`
}
type Config struct {
Code struct {
Addr string `yaml:"addr"`
Behavior struct {
Cover bool `yaml:"cover"`
} `yaml:"behavior"`
Options struct {
DataSource uint64 `yaml:"datasource"`
Table string `yaml:"table"`
Template string `yaml:"template"`
Charset string `yaml:"charset"`
PackageName string `yaml:"packageName"`
DelPrefix string `yaml:"delPrefix"`
Author string `yaml:"author"`
BizName string `yaml:"bizName"`
} `yaml:"options"`
} `yaml:"code-gen"`
}
func main() {
codeConfig, err := analysisYaml()
if err != nil {
fmt.Println("Error:", err)
return
}
// 创建一个 GeneratorParam 实例
generatorParam := GeneratorParam{
DatasourceConfigId: codeConfig.Code.Options.DataSource,
TableNames: strings.Split(codeConfig.Code.Options.Table, ","),
TemplateConfigGroupName: codeConfig.Code.Options.Template,
Charset: codeConfig.Code.Options.Charset,
PackageName: codeConfig.Code.Options.PackageName,
DelPrefix: codeConfig.Code.Options.DelPrefix,
Author: codeConfig.Code.Options.Author,
BizName: codeConfig.Code.Options.BizName,
}
if len(generatorParam.TableNames) == 0 {
fmt.Println("Error: table不能为空")
}
if codeConfig.Code.Options.DataSource == 0 {
fmt.Println("Error: DataSource不能为空")
}
if codeConfig.Code.Options.Template == "" {
fmt.Println("Error: template不能为空")
}
if codeConfig.Code.Options.Charset == "" {
generatorParam.Charset = "UTF-8"
}
if codeConfig.Code.Addr == "" {
codeConfig.Code.Addr = "127.0.0.1:6969"
}
data, err := requestCodeFile(&generatorParam, "http://"+codeConfig.Code.Addr+"/generate/codeFile")
if err != nil {
fmt.Println(err)
return
}
addFile := make([]*CodeFile, 0)
for _, v := range *data {
path := v.Folder + "/" + v.FileName
if _, err := os.Stat(v.Folder + "/" + v.FileName); err == nil {
fmt.Printf("File %s exists\n", path)
} else if os.IsNotExist(err) {
addFile = append(addFile, &v)
} else {
fmt.Printf("Error checking file %s: %v\n", path, err)
return
}
}
if len(addFile) < len(*data) {
for {
fmt.Printf("请选择生成文件的方式?1:覆盖 2:追加 0:退出:\n")
var input int
fmt.Scanln(&input)
// 判断输入并输出对应结果
switch input {
case 1:
err, cnt := copy2File(data, true)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("code-gen成功!生成文件数:", cnt)
return
case 2:
err, cnt := copy2File(data, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("code-gen成功!生成文件数:", cnt)
return
case 0:
os.Exit(0)
default:
fmt.Println("无效输入,请输入1:覆盖 2:追加 0:取消 ")
}
}
}
err, cnt := copy2File(data, true)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("code-gen成功!生成文件数:", cnt)
}
func analysisYaml() (*Config, error) {
dir, err := os.Getwd()
if err != nil {
return &Config{}, err
}
filePath := filepath.Join(dir, "code-gen.yaml")
// 读取 YAML 文件内容
yamlFile, err := ioutil.ReadFile(filePath)
if err != nil {
return &Config{}, err
}
// 解析 YAML 文件内容
var config Config
if err := yaml.Unmarshal(yamlFile, &config); err != nil {
return &Config{}, err
}
return &config, nil
}
func requestCodeFile(generatorParam *GeneratorParam, url string) (*[]CodeFile, error) {
// 将 GeneratorParam 实例转换为 JSON 字符串
postData, err := json.Marshal(generatorParam)
if err != nil {
return nil, errors.New("Error marshalling JSON:" + err.Error())
}
// 发送 POST 请求
resp, err := http.Post(url, "application/json", bytes.NewBuffer(postData))
if err != nil {
return nil, errors.New("Error sending POST request:" + err.Error())
}
defer resp.Body.Close()
// 读取响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.New("Error reading response body:" + err.Error())
}
var rs = &Result{}
err = json.Unmarshal(body, rs)
if err != nil {
return nil, errors.New("Error unmarshal response body:" + err.Error())
}
if rs.Code != "0" {
return nil, errors.New(rs.Msg)
}
return &rs.Data, nil
}
func isValidPathFormat(path string) bool {
// 定义正则表达式,匹配路径是否只包含有效字符(字母、数字、下划线、斜杠、横杠和点)
validPathRegex := regexp.MustCompile(`^[\w\/.-]+$`)
return validPathRegex.MatchString(path)
}
func isValidFileFormat(path string) bool {
// 定义正则表达式,匹配路径是否只包含有效字符(字母、数字、下划线、横杠和点)
validPathRegex := regexp.MustCompile(`^[\w\-.]+$`)
return validPathRegex.MatchString(path)
}
func copy2File(generate *[]CodeFile, isCover bool) (error, int) {
for _, codeFile := range *generate {
if strings.TrimSpace(codeFile.Folder) == "" {
return errors.New("模版:目录为空!"), 0
}
if !isValidPathFormat(codeFile.Folder) {
return errors.New(codeFile.Folder + "模版:目录格式错误!匹配路径是否只包含有效字符(字母、数字、下划线、斜杠、横杠和点)"), 0
}
if !isValidFileFormat(codeFile.FileName) {
return errors.New(codeFile.FileName + ":文件名格式错误!匹配路径是否只包含有效字符(字母、数字、下划线、横杠和点)"), 0
}
}
var count int
for _, codeFile := range *generate {
execFile := "./"
// 要生成的 Go 文件名
fileName := strings.Trim(codeFile.FileName, "/\\")
folderPath := strings.Trim(codeFile.Folder, "/\\")
// 要写入 Go 文件的内容
content := codeFile.Content
// 创建文件夹
folder := filepath.Join(execFile, folderPath)
err := os.MkdirAll(folder, 0755)
if err != nil {
return err, 0
}
// 写入文件
filePath := filepath.Join(folder, fileName)
// 检查文件是否存在
if _, err := os.Stat(filePath); err == nil {
if !isCover {
// 文件已存在且isCover为false,跳过写入
continue
}
}
err = ioutil.WriteFile(filePath, []byte(content), 0644)
if err != nil {
fmt.Println(err)
continue
}
count++
}
return nil, count
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。