2020-07-04 14:58:03 +00:00
|
|
|
package beegopro
|
|
|
|
|
|
|
|
import (
|
2020-07-24 18:56:02 +00:00
|
|
|
"crypto/md5"
|
2020-07-04 14:58:03 +00:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2020-07-26 13:26:33 +00:00
|
|
|
"github.com/beego/bee/internal/pkg/command"
|
|
|
|
"github.com/beego/bee/internal/pkg/system"
|
2020-07-04 14:58:03 +00:00
|
|
|
"github.com/beego/bee/internal/pkg/utils"
|
|
|
|
beeLogger "github.com/beego/bee/logger"
|
|
|
|
"go/format"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"path/filepath"
|
2020-07-26 13:26:33 +00:00
|
|
|
"strconv"
|
2020-07-04 14:58:03 +00:00
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// write to file
|
2020-07-26 06:27:27 +00:00
|
|
|
func (c *RenderFile) write(filename string, buf []byte) (err error) {
|
2020-07-04 14:58:03 +00:00
|
|
|
if utils.IsExist(filename) && !isNeedOverwrite(filename) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-24 07:15:29 +00:00
|
|
|
filePath := filepath.Dir(filename)
|
2020-07-04 14:58:03 +00:00
|
|
|
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) {
|
2020-07-24 07:15:29 +00:00
|
|
|
bakName := fmt.Sprintf("%s/%s.%s.bak", filePathBak, filepath.Base(name), time.Now().Format("2006.01.02.15.04.05"))
|
2020-07-04 14:58:03 +00:00
|
|
|
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)
|
2020-07-21 14:24:42 +00:00
|
|
|
defer func() {
|
|
|
|
err = file.Close()
|
|
|
|
if err != nil {
|
|
|
|
beeLogger.Log.Fatalf("file close error, err %s", err)
|
|
|
|
}
|
|
|
|
}()
|
2020-07-04 14:58:03 +00:00
|
|
|
if err != nil {
|
|
|
|
err = errors.New("write create file " + err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
output := []byte(buf)
|
|
|
|
|
|
|
|
if c.Option.EnableFormat && filepath.Ext(filename) == ".go" {
|
|
|
|
// format code
|
|
|
|
var bts []byte
|
|
|
|
bts, err = format.Source([]byte(buf))
|
|
|
|
if err != nil {
|
|
|
|
err = errors.New("format buf error " + err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
output = bts
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ioutil.WriteFile(filename, output, 0644)
|
|
|
|
if err != nil {
|
|
|
|
err = errors.New("write write file " + err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func isNeedOverwrite(fileName string) (flag bool) {
|
2020-07-26 07:48:36 +00:00
|
|
|
seg := GetSeg(filepath.Ext(fileName))
|
2020-07-04 14:58:03 +00:00
|
|
|
|
|
|
|
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 {
|
2020-07-11 09:13:13 +00:00
|
|
|
tag = kv[1]
|
2020-07-04 14:58:03 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2020-07-24 18:56:02 +00:00
|
|
|
|
2020-07-26 07:48:36 +00:00
|
|
|
func FileContentChange(org,new []byte, seg string) bool {
|
2020-07-26 06:27:27 +00:00
|
|
|
if len(org) == 0 {
|
|
|
|
return true
|
2020-07-24 18:56:02 +00:00
|
|
|
}
|
2020-07-26 07:48:36 +00:00
|
|
|
orgContent := GetFilterContent(string(org),seg)
|
2020-07-26 14:09:36 +00:00
|
|
|
newContent := GetFilterContent(string(new),seg)
|
2020-07-24 18:56:02 +00:00
|
|
|
orgMd5 := md5.Sum([]byte(orgContent))
|
|
|
|
newMd5:= md5.Sum([]byte(newContent))
|
|
|
|
if orgMd5 != newMd5 {
|
|
|
|
return true
|
|
|
|
}
|
2020-07-26 06:27:27 +00:00
|
|
|
beeLogger.Log.Infof("File has no change in the content")
|
2020-07-24 18:56:02 +00:00
|
|
|
return false
|
2020-07-26 07:48:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func GetFilterContent(content string, seg string) string {
|
|
|
|
res := ""
|
|
|
|
for _, s := range strings.Split(content, "\n") {
|
|
|
|
s = strings.TrimSpace(strings.TrimPrefix(s, seg))
|
|
|
|
var have = false
|
|
|
|
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 "//"
|
|
|
|
}
|
2020-07-26 13:26:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func UpdateSelf() {
|
|
|
|
path := system.BeegoHome
|
|
|
|
fp := path + "/.updateBee"
|
|
|
|
timeNow := time.Now().Unix()
|
|
|
|
var timeOld int64
|
|
|
|
if utils.IsExist(fp) {
|
|
|
|
oldContent, err := ioutil.ReadFile(fp)
|
|
|
|
if err != nil {
|
|
|
|
beeLogger.Log.Warnf("read file err: %s", err)
|
|
|
|
}
|
|
|
|
timeOld, _ = strconv.ParseInt(string(oldContent), 10, 64)
|
|
|
|
} else {
|
|
|
|
if cf, err := os.OpenFile(fp, os.O_CREATE, 0644); err == nil {
|
|
|
|
cf.Close()
|
2020-07-26 13:32:54 +00:00
|
|
|
} else {
|
2020-07-26 13:26:33 +00:00
|
|
|
beeLogger.Log.Warnf("Create file err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if timeNow-timeOld > 24*60*60 {
|
|
|
|
if w, err := os.OpenFile(fp, os.O_WRONLY|os.O_TRUNC, 0644); err == nil {
|
|
|
|
defer w.Close()
|
|
|
|
timeNowStr := strconv.FormatInt(timeNow, 10)
|
|
|
|
if _, err := w.WriteString(timeNowStr); err != nil {
|
|
|
|
beeLogger.Log.Warnf("Update file err: %s", err)
|
|
|
|
}
|
|
|
|
beeLogger.Log.Info("Updating bee")
|
|
|
|
goGetBee()
|
|
|
|
} else {
|
|
|
|
beeLogger.Log.Warnf("Update Bee file err: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func goGetBee() {
|
|
|
|
beePath := "github.com/beego/bee"
|
|
|
|
done := make(chan int, 1)
|
|
|
|
go func() {
|
|
|
|
stdout, stderr, err := command.ExecCmd("go", "get", "-u", beePath)
|
|
|
|
if err != nil {
|
|
|
|
beeLogger.Log.Warnf("Update Bee err: %s", err)
|
|
|
|
beeLogger.Log.Warnf("Update Bee err: %s", stderr)
|
|
|
|
}
|
|
|
|
beeLogger.Log.Infof("Bee was updated successfully %s", stdout)
|
|
|
|
done <- 1
|
|
|
|
}()
|
|
|
|
// wait 30 second
|
|
|
|
select {
|
|
|
|
case <-done:
|
|
|
|
return
|
|
|
|
case <-time.After(time.Duration(30 * time.Second)):
|
|
|
|
beeLogger.Log.Warn("Update Bee timeout!!!")
|
|
|
|
}
|
2020-07-24 18:56:02 +00:00
|
|
|
}
|