package beegopro import ( "crypto/md5" "errors" "fmt" "io/ioutil" "os" "path" "path/filepath" "strings" "time" "github.com/beego/bee/v2/internal/pkg/utils" beeLogger "github.com/beego/bee/v2/logger" ) // write to file func (c *RenderFile) write(filename string, buf []byte) (err error) { if utils.IsExist(filename) && !isNeedOverwrite(filename) { return } filePath := filepath.Dir(filename) err = createPath(filePath) if err != nil { err = errors.New("write create path " + err.Error()) return } filePathBak := filePath + "/bak" err = createPath(filePathBak) if err != nil { err = errors.New("write create path bak " + err.Error()) return } name := path.Base(filename) if utils.IsExist(filename) { bakName := fmt.Sprintf("%s/%s.%s.bak", filePathBak, filepath.Base(name), time.Now().Format("2006.01.02.15.04.05")) beeLogger.Log.Infof("bak file '%s'", bakName) if err := os.Rename(filename, bakName); err != nil { err = errors.New("file is bak error, path is " + bakName) return err } } file, err := os.Create(filename) defer func() { err = file.Close() if err != nil { beeLogger.Log.Fatalf("file close error, err %s", err) } }() if err != nil { err = errors.New("write create file " + err.Error()) return } err = ioutil.WriteFile(filename, buf, 0644) if err != nil { err = errors.New("write write file " + err.Error()) return } return } func isNeedOverwrite(fileName string) (flag bool) { seg := GetSeg(filepath.Ext(fileName)) f, err := os.Open(fileName) if err != nil { return } defer f.Close() overwrite := "" var contentByte []byte contentByte, err = ioutil.ReadAll(f) if err != nil { return } for _, s := range strings.Split(string(contentByte), "\n") { s = strings.TrimSpace(strings.TrimPrefix(s, seg)) if strings.HasPrefix(s, "@BeeOverwrite") { overwrite = strings.TrimSpace(s[len("@BeeOverwrite"):]) } } if strings.ToLower(overwrite) == "yes" { flag = true return } return } // createPath 调用os.MkdirAll递归创建文件夹 func createPath(filePath string) error { if !utils.IsExist(filePath) { err := os.MkdirAll(filePath, os.ModePerm) return err } return nil } func getPackagePath() (packagePath string) { f, err := os.Open("go.mod") if err != nil { return } defer f.Close() var contentByte []byte contentByte, err = ioutil.ReadAll(f) if err != nil { return } for _, s := range strings.Split(string(contentByte), "\n") { packagePath = strings.TrimSpace(strings.TrimPrefix(s, "module")) return } return } func getModelType(orm string) (inputType, goType, mysqlType, tag string) { kv := strings.SplitN(orm, ",", 2) inputType = kv[0] switch inputType { case "string": goType = "string" tag = "size(255)" // todo use orm data mysqlType = "varchar(255) NOT NULL" case "text": goType = "string" tag = "type(longtext)" mysqlType = "longtext NOT NULL" case "auto": goType = "int" tag = "auto" mysqlType = "int(11) NOT NULL AUTO_INCREMENT" case "pk": goType = "int" tag = "pk" mysqlType = "int(11) NOT NULL" case "datetime": goType = "time.Time" tag = "type(datetime)" mysqlType = "datetime NOT NULL" case "int", "int8", "int16", "int32", "int64": fallthrough case "uint", "uint8", "uint16", "uint32", "uint64": goType = inputType tag = "" mysqlType = "int(11) DEFAULT NULL" case "bool": goType = inputType tag = "" mysqlType = "int(11) DEFAULT NULL" case "float32", "float64": goType = inputType tag = "" mysqlType = "float NOT NULL" case "float": goType = "float64" tag = "" mysqlType = "float NOT NULL" default: beeLogger.Log.Fatalf("not support type: %s", inputType) } // user set orm tag if len(kv) == 2 { tag = kv[1] } return } func FileContentChange(org, new []byte, seg string) bool { if len(org) == 0 { return true } orgContent := GetFilterContent(string(org), seg) newContent := GetFilterContent(string(new), seg) orgMd5 := md5.Sum([]byte(orgContent)) newMd5 := md5.Sum([]byte(newContent)) if orgMd5 != newMd5 { return true } beeLogger.Log.Infof("File has no change in the content") return false } func GetFilterContent(content string, seg string) string { res := "" for _, s := range strings.Split(content, "\n") { s = strings.TrimSpace(strings.TrimPrefix(s, seg)) var have bool for _, except := range CompareExcept { if strings.HasPrefix(s, except) { have = true } } if !have { res += s } } return res } func GetSeg(ext string) string { switch ext { case ".sql": return "--" default: return "//" } }