1
0
mirror of https://github.com/beego/bee.git synced 2024-11-24 13:30:53 +00:00

Merge pull request #735 from flycash/v1.12.3

V1.12.3
This commit is contained in:
Ming Deng 2020-11-08 20:36:12 +08:00 committed by GitHub
commit d459bbfc09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 324 additions and 167 deletions

View File

@ -1,6 +1,6 @@
language: go language: go
go: go:
- 1.12.17 - 1.14.11
install: install:
- export PATH=$PATH:$HOME/gopath/bin - export PATH=$PATH:$HOME/gopath/bin
- go get -u github.com/opennota/check/cmd/structcheck - go get -u github.com/opennota/check/cmd/structcheck

View File

@ -16,7 +16,7 @@ Bee is a command-line tool facilitating development of Beego-based application.
To install `bee` use the `go get` command: To install `bee` use the `go get` command:
```bash ```bash
go get github.com/beego/bee go get github.com/beego/bee@v1.12.3
``` ```
Then you can add `bee` binary to PATH environment variable in your `~/.bashrc` or `~/.bash_profile` file: Then you can add `bee` binary to PATH environment variable in your `~/.bashrc` or `~/.bash_profile` file:
@ -25,12 +25,6 @@ Then you can add `bee` binary to PATH environment variable in your `~/.bashrc` o
export PATH=$PATH:<your_main_gopath>/bin export PATH=$PATH:<your_main_gopath>/bin
``` ```
> If you already have `bee` installed, updating `bee` is simple:
```bash
go get -u github.com/beego/bee
```
## Basic commands ## Basic commands
Bee provides a variety of commands which can be helpful at various stages of development. The top level commands include: Bee provides a variety of commands which can be helpful at various stages of development. The top level commands include:

View File

@ -31,6 +31,7 @@ import (
_ "github.com/beego/bee/cmd/commands/rs" _ "github.com/beego/bee/cmd/commands/rs"
_ "github.com/beego/bee/cmd/commands/run" _ "github.com/beego/bee/cmd/commands/run"
_ "github.com/beego/bee/cmd/commands/server" _ "github.com/beego/bee/cmd/commands/server"
_ "github.com/beego/bee/cmd/commands/update"
_ "github.com/beego/bee/cmd/commands/version" _ "github.com/beego/bee/cmd/commands/version"
"github.com/beego/bee/utils" "github.com/beego/bee/utils"
) )

View File

@ -34,9 +34,10 @@ var CmdApiapp = &commands.Command{
Short: "Creates a Beego API application", Short: "Creates a Beego API application",
Long: ` Long: `
The command 'api' creates a Beego API application. The command 'api' creates a Beego API application.
now default supoort generate a go modules project.
{{"Example:"|bold}} {{"Example:"|bold}}
$ bee api [appname] [-tables=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-module=true] [-beego=v1.12.1] $ bee api [appname] [-tables=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-gopath=false] [-beego=v1.12.1]
If 'conn' argument is empty, the command will generate an example API application. Otherwise the command If 'conn' argument is empty, the command will generate an example API application. Otherwise the command
will connect to your database and generate models based on the existing tables. will connect to your database and generate models based on the existing tables.
@ -543,15 +544,15 @@ func TestGet(t *testing.T) {
} }
` `
var module utils.DocValue var gopath utils.DocValue
var beegoVersion utils.DocValue var beegoVersion utils.DocValue
func init() { func init() {
CmdApiapp.Flag.Var(&generate.Tables, "tables", "List of table names separated by a comma.") CmdApiapp.Flag.Var(&generate.Tables, "tables", "List of table names separated by a comma.")
CmdApiapp.Flag.Var(&generate.SQLDriver, "driver", "Database driver. Either mysql, postgres or sqlite.") CmdApiapp.Flag.Var(&generate.SQLDriver, "driver", "Database driver. Either mysql, postgres or sqlite.")
CmdApiapp.Flag.Var(&generate.SQLConn, "conn", "Connection string used by the driver to connect to a database instance.") CmdApiapp.Flag.Var(&generate.SQLConn, "conn", "Connection string used by the driver to connect to a database instance.")
CmdApiapp.Flag.Var(&module, "module", "Support go modules") CmdApiapp.Flag.Var(&gopath, "gopath", "Support go path,default false")
CmdApiapp.Flag.Var(&beegoVersion, "beego", "set beego version,only take effect by -module=true") CmdApiapp.Flag.Var(&beegoVersion, "beego", "set beego version,only take effect by go mod")
commands.AvailableCommands = append(commands.AvailableCommands, CmdApiapp) commands.AvailableCommands = append(commands.AvailableCommands, CmdApiapp)
} }
@ -563,14 +564,15 @@ func createAPI(cmd *commands.Command, args []string) int {
} }
if len(args) >= 2 { if len(args) >= 2 {
cmd.Flag.Parse(args[1:]) err := cmd.Flag.Parse(args[1:])
} else { if err != nil {
module = "false" beeLogger.Log.Fatal("Parse args err " + err.Error())
}
} }
var appPath string var appPath string
var packPath string var packPath string
var err error var err error
if module != `true` { if gopath == `true` {
beeLogger.Log.Info("generate api project support GOPATH") beeLogger.Log.Info("generate api project support GOPATH")
version.ShowShortVersionBanner() version.ShowShortVersionBanner()
appPath, packPath, err = utils.CheckEnv(args[0]) appPath, packPath, err = utils.CheckEnv(args[0])
@ -605,7 +607,7 @@ func createAPI(cmd *commands.Command, args []string) int {
beeLogger.Log.Info("Creating API...") beeLogger.Log.Info("Creating API...")
os.MkdirAll(appPath, 0755) os.MkdirAll(appPath, 0755)
if module == `true` { //generate first for calc model name if gopath != `true` { //generate first for calc model name
fmt.Fprintf(output, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(appPath, "go.mod"), "\x1b[0m") fmt.Fprintf(output, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(appPath, "go.mod"), "\x1b[0m")
utils.WriteToFile(path.Join(appPath, "go.mod"), fmt.Sprintf(goMod, packPath, utils.GetGoVersionSkipMinor(), beegoVersion.String())) utils.WriteToFile(path.Join(appPath, "go.mod"), fmt.Sprintf(goMod, packPath, utils.GetGoVersionSkipMinor(), beegoVersion.String()))
} }

View File

@ -65,6 +65,7 @@ func (c *Command) Out() io.Writer {
if c.output != nil { if c.output != nil {
return *c.output return *c.output
} }
return colors.NewColorWriter(os.Stderr) return colors.NewColorWriter(os.Stderr)
} }

View File

@ -24,7 +24,7 @@ var CmdHproseapp = &commands.Command{
{{"To scaffold out your application, use:"|bold}} {{"To scaffold out your application, use:"|bold}}
$ bee hprose [appname] [-tables=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-module=true] [-beego=v1.12.1] $ bee hprose [appname] [-tables=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-gopath=false] [-beego=v1.12.1]
If 'conn' is empty, the command will generate a sample application. Otherwise the command If 'conn' is empty, the command will generate a sample application. Otherwise the command
will connect to your database and generate models based on the existing tables. will connect to your database and generate models based on the existing tables.
@ -52,15 +52,15 @@ require github.com/astaxie/beego %s
require github.com/smartystreets/goconvey v1.6.4 require github.com/smartystreets/goconvey v1.6.4
` `
var module utils.DocValue var gopath utils.DocValue
var beegoVersion utils.DocValue var beegoVersion utils.DocValue
func init() { func init() {
CmdHproseapp.Flag.Var(&generate.Tables, "tables", "List of table names separated by a comma.") CmdHproseapp.Flag.Var(&generate.Tables, "tables", "List of table names separated by a comma.")
CmdHproseapp.Flag.Var(&generate.SQLDriver, "driver", "Database driver. Either mysql, postgres or sqlite.") CmdHproseapp.Flag.Var(&generate.SQLDriver, "driver", "Database driver. Either mysql, postgres or sqlite.")
CmdHproseapp.Flag.Var(&generate.SQLConn, "conn", "Connection string used by the driver to connect to a database instance.") CmdHproseapp.Flag.Var(&generate.SQLConn, "conn", "Connection string used by the driver to connect to a database instance.")
CmdHproseapp.Flag.Var(&module, "module", "Support go modules") CmdHproseapp.Flag.Var(&gopath, "gopath", "Support go path,default false")
CmdHproseapp.Flag.Var(&beegoVersion, "beego", "set beego version,only take effect by -module=true") CmdHproseapp.Flag.Var(&beegoVersion, "beego", "set beego version,only take effect by go mod")
commands.AvailableCommands = append(commands.AvailableCommands, CmdHproseapp) commands.AvailableCommands = append(commands.AvailableCommands, CmdHproseapp)
} }
@ -71,15 +71,16 @@ func createhprose(cmd *commands.Command, args []string) int {
} }
curpath, _ := os.Getwd() curpath, _ := os.Getwd()
if len(args) > 1 { if len(args) >= 2 {
cmd.Flag.Parse(args[1:]) err := cmd.Flag.Parse(args[1:])
} else { if err != nil {
module = "false" beeLogger.Log.Fatal("Parse args err " + err.Error())
}
} }
var apppath string var apppath string
var packpath string var packpath string
var err error var err error
if module != `true` { if gopath == `true` {
beeLogger.Log.Info("generate api project support GOPATH") beeLogger.Log.Info("generate api project support GOPATH")
version.ShowShortVersionBanner() version.ShowShortVersionBanner()
apppath, packpath, err = utils.CheckEnv(args[0]) apppath, packpath, err = utils.CheckEnv(args[0])
@ -109,7 +110,7 @@ func createhprose(cmd *commands.Command, args []string) int {
beeLogger.Log.Info("Creating Hprose application...") beeLogger.Log.Info("Creating Hprose application...")
os.MkdirAll(apppath, 0755) os.MkdirAll(apppath, 0755)
if module == `true` { //generate first for calc model name if gopath != `true` { //generate first for calc model name
fmt.Fprintf(output, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "go.mod"), "\x1b[0m") fmt.Fprintf(output, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "go.mod"), "\x1b[0m")
utils.WriteToFile(path.Join(apppath, "go.mod"), fmt.Sprintf(goMod, packpath, utils.GetGoVersionSkipMinor(), beegoVersion.String())) utils.WriteToFile(path.Join(apppath, "go.mod"), fmt.Sprintf(goMod, packpath, utils.GetGoVersionSkipMinor(), beegoVersion.String()))
} }

View File

@ -31,12 +31,12 @@ var gopath utils.DocValue
var beegoVersion utils.DocValue var beegoVersion utils.DocValue
var CmdNew = &commands.Command{ var CmdNew = &commands.Command{
UsageLine: "new [appname] [-module=true] [-beego=v1.12.1]", UsageLine: "new [appname] [-gopath=false] [-beego=v1.12.1]",
Short: "Creates a Beego application", Short: "Creates a Beego application",
Long: ` Long: `
Creates a Beego application for the given app name in the current directory. Creates a Beego application for the given app name in the current directory.
now supoort generate a go modules project now default supoort generate a go modules project
The command 'new' creates a folder named [appname] [-module=true] [-beego=v1.12.1] and generates the following structure: The command 'new' creates a folder named [appname] [-gopath=false] [-beego=v1.12.1] and generates the following structure:
main.go main.go
go.mod go.mod
@ -255,8 +255,8 @@ var reloadJsClient = `function b(a){var c=new WebSocket(a);c.onclose=function(){
` `
func init() { func init() {
CmdNew.Flag.Var(&gopath, "gopath", "Support go path") CmdNew.Flag.Var(&gopath, "gopath", "Support go path,default false")
CmdNew.Flag.Var(&beegoVersion, "beego", "set beego version,only take effect by module mod") CmdNew.Flag.Var(&beegoVersion, "beego", "set beego version,only take effect by go mod")
commands.AvailableCommands = append(commands.AvailableCommands, CmdNew) commands.AvailableCommands = append(commands.AvailableCommands, CmdNew)
} }

View File

@ -0,0 +1,38 @@
package update
import (
"flag"
"os"
"os/exec"
"github.com/beego/bee/cmd/commands"
"github.com/beego/bee/config"
beeLogger "github.com/beego/bee/logger"
)
var CmdUpdate = &commands.Command{
UsageLine: "update",
Short: "Update Bee",
Long: `
Automatic run command "go get -u github.com/beego/bee" for selfupdate
`,
Run: updateBee,
}
func init() {
fs := flag.NewFlagSet("update", flag.ContinueOnError)
CmdUpdate.Flag = *fs
commands.AvailableCommands = append(commands.AvailableCommands, CmdUpdate)
}
func updateBee(cmd *commands.Command, args []string) int {
beeLogger.Log.Info("Updating")
beePath := config.GitRemotePath
cmdUp := exec.Command("go", "get", "-u", beePath)
cmdUp.Stdout = os.Stdout
cmdUp.Stderr = os.Stderr
if err := cmdUp.Run(); err != nil {
beeLogger.Log.Warnf("Run cmd err:%s",err)
}
return 0
}

View File

@ -14,11 +14,13 @@ import (
"runtime" "runtime"
"strings" "strings"
"gopkg.in/yaml.v2"
"github.com/beego/bee/cmd/commands" "github.com/beego/bee/cmd/commands"
"github.com/beego/bee/config"
beeLogger "github.com/beego/bee/logger" beeLogger "github.com/beego/bee/logger"
"github.com/beego/bee/logger/colors" "github.com/beego/bee/logger/colors"
"github.com/beego/bee/utils" "github.com/beego/bee/utils"
"gopkg.in/yaml.v2"
) )
const verboseVersionBanner string = `%s%s______ const verboseVersionBanner string = `%s%s______
@ -57,7 +59,7 @@ Prints the current Bee, Beego and Go version alongside the platform information.
} }
var outputFormat string var outputFormat string
const version = "1.11.0" const version = config.Version
func init() { func init() {
fs := flag.NewFlagSet("version", flag.ContinueOnError) fs := flag.NewFlagSet("version", flag.ContinueOnError)

View File

@ -19,12 +19,19 @@ import (
"os" "os"
"path/filepath" "path/filepath"
beeLogger "github.com/beego/bee/logger"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
beeLogger "github.com/beego/bee/logger"
) )
const confVer = 0 const confVer = 0
const (
Version = "1.12.0"
GitRemotePath = "github.com/beego/bee"
)
var Conf = struct { var Conf = struct {
Version int Version int
WatchExts []string `json:"watch_ext" yaml:"watch_ext"` WatchExts []string `json:"watch_ext" yaml:"watch_ext"`

View File

@ -19,6 +19,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"go/ast" "go/ast"
"go/build"
"go/parser" "go/parser"
"go/token" "go/token"
"os" "os"
@ -37,7 +38,6 @@ import (
"github.com/astaxie/beego/swagger" "github.com/astaxie/beego/swagger"
"github.com/astaxie/beego/utils" "github.com/astaxie/beego/utils"
beeLogger "github.com/beego/bee/logger" beeLogger "github.com/beego/bee/logger"
bu "github.com/beego/bee/utils"
) )
const ( const (
@ -102,8 +102,8 @@ func init() {
astPkgs = make([]*ast.Package, 0) astPkgs = make([]*ast.Package, 0)
} }
// ParsePackagesFromDir parses packages from a given directory // parsePackagesFromDir parses packages from a given directory
func ParsePackagesFromDir(dirpath string) { func parsePackagesFromDir(dirpath string) {
c := make(chan error) c := make(chan error)
go func() { go func() {
@ -157,8 +157,14 @@ func parsePackageFromDir(path string) error {
// GenerateDocs generates documentations for a given path. // GenerateDocs generates documentations for a given path.
func GenerateDocs(curpath string) { func GenerateDocs(curpath string) {
fset := token.NewFileSet() pkgspath := curpath
workspace := os.Getenv("BeeWorkspace")
if workspace != "" {
pkgspath = workspace
}
parsePackagesFromDir(pkgspath)
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filepath.Join(curpath, "routers", "router.go"), nil, parser.ParseComments) f, err := parser.ParseFile(fset, filepath.Join(curpath, "routers", "router.go"), nil, parser.ParseComments)
if err != nil { if err != nil {
beeLogger.Log.Fatalf("Error while parsing router.go: %s", err) beeLogger.Log.Fatalf("Error while parsing router.go: %s", err)
@ -263,7 +269,7 @@ func GenerateDocs(curpath string) {
if im.Name != nil { if im.Name != nil {
localName = im.Name.Name localName = im.Name.Name
} }
analyseControllerPkg(path.Join(curpath, "vendor"), localName, im.Path.Value) analyseControllerPkg(localName, im.Path.Value)
} }
for _, d := range f.Decls { for _, d := range f.Decls {
switch specDecl := d.(type) { switch specDecl := d.(type) {
@ -418,7 +424,7 @@ func analyseNSInclude(baseurl string, ce *ast.CallExpr) string {
return cname return cname
} }
func analyseControllerPkg(vendorPath, localName, pkgpath string) { func analyseControllerPkg(localName, pkgpath string) {
pkgpath = strings.Trim(pkgpath, "\"") pkgpath = strings.Trim(pkgpath, "\"")
if isSystemPackage(pkgpath) { if isSystemPackage(pkgpath) {
return return
@ -433,36 +439,18 @@ func analyseControllerPkg(vendorPath, localName, pkgpath string) {
importlist[pps[len(pps)-1]] = pkgpath importlist[pps[len(pps)-1]] = pkgpath
} }
pkgRealpath := "" pkg, err := build.Default.Import(pkgpath, ".", build.FindOnly)
if err != nil {
if bu.IsGOMODULE() { beeLogger.Log.Fatalf("Package %s cannot be imported: %v", pkgpath, err)
pkgRealpath = filepath.Join(bu.GetBeeWorkPath(), "..", pkgpath)
} else {
gopaths := bu.GetGOPATHs()
if len(gopaths) == 0 {
beeLogger.Log.Fatal("GOPATH environment variable is not set or empty")
}
wg, _ := filepath.EvalSymlinks(filepath.Join(vendorPath, pkgpath))
if utils.FileExists(wg) {
pkgRealpath = wg
} else {
wgopath := gopaths
for _, wg := range wgopath {
wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", pkgpath))
if utils.FileExists(wg) {
pkgRealpath = wg
break
}
}
}
} }
pkgRealpath := pkg.Dir
if pkgRealpath != "" { if pkgRealpath != "" {
if _, ok := pkgCache[pkgpath]; ok { if _, ok := pkgCache[pkgpath]; ok {
return return
} }
pkgCache[pkgpath] = struct{}{} pkgCache[pkgpath] = struct{}{}
} else { } else {
beeLogger.Log.Fatalf("Package '%s' does not exist in the GOPATH or vendor path", pkgpath) beeLogger.Log.Fatalf("Package '%s' does not have source directory", pkgpath)
} }
fileSet := token.NewFileSet() fileSet := token.NewFileSet()

3
go.mod
View File

@ -1,9 +1,8 @@
module github.com/beego/bee module github.com/beego/bee
go 1.13 go 1.14
require ( require (
github.com/BurntSushi/toml v0.3.1
github.com/astaxie/beego v1.12.1 github.com/astaxie/beego v1.12.1
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915 github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915

View File

@ -5,7 +5,7 @@ import (
beeLogger "github.com/beego/bee/logger" beeLogger "github.com/beego/bee/logger"
"io/ioutil" "io/ioutil"
) )
var CompareExcept = []string{"@BeeGenerateTime"}
func (c *Container) GenConfig() { func (c *Container) GenConfig() {
if utils.IsExist(c.BeegoProFile) { if utils.IsExist(c.BeegoProFile) {
beeLogger.Log.Fatalf("beego pro toml exist") beeLogger.Log.Fatalf("beego pro toml exist")

View File

@ -28,25 +28,26 @@ var DefaultBeegoPro = &Container{
ProType: "default", ProType: "default",
ApiPrefix: "/api", ApiPrefix: "/api",
EnableModule: nil, EnableModule: nil,
Models: make(map[string]TextModel, 0), Models: make(map[string]TextModel),
GitRemotePath: "https://github.com/beego/beego-pro.git", GitRemotePath: "https://github.com/beego/beego-pro.git",
Branch: "master", Branch: "master",
GitLocalPath: system.BeegoHome + "/beego-pro", GitLocalPath: system.BeegoHome + "/beego-pro",
EnableFormat: true, EnableFormat: true,
SourceGen: "text", SourceGen: "text",
EnableGitPull: true, EnableGitPull: true,
RefreshGitTime: 24 * 3600,
Path: map[string]string{ Path: map[string]string{
"beego": ".", "beego": ".",
}, },
EnableGomod: true, EnableGomod: true,
RefreshGitTime: 24 * 3600,
Extend: nil,
}, },
GenerateTime: time.Now().Format(MDateFormat), GenerateTime: time.Now().Format(MDateFormat),
GenerateTimeUnix: time.Now().Unix(), GenerateTimeUnix: time.Now().Unix(),
TmplOption: TmplOption{}, TmplOption: TmplOption{},
CurPath: system.CurrentDir, CurPath: system.CurrentDir,
EnableModules: make(map[string]interface{}, 0), // get the user configuration, get the enable module result EnableModules: make(map[string]interface{}), // get the user configuration, get the enable module result
FunctionOnce: make(map[string]sync.Once, 0), // get the tmpl configuration, get the function once result FunctionOnce: make(map[string]sync.Once), // get the tmpl configuration, get the function once result
} }
func (c *Container) Run() { func (c *Container) Run() {
@ -128,7 +129,7 @@ func (c *Container) initTemplateOption() {
} }
for _, value := range c.TmplOption.Descriptor { for _, value := range c.TmplOption.Descriptor {
if value.Once == true { if value.Once {
c.FunctionOnce[value.SrcName] = sync.Once{} c.FunctionOnce[value.SrcName] = sync.Once{}
} }
} }

View File

@ -10,7 +10,6 @@ import (
type MysqlParser struct { type MysqlParser struct {
userOption UserOption userOption UserOption
tmplOption TmplOption tmplOption TmplOption
db *sql.DB
} }
func (m *MysqlParser) RegisterOption(userOption UserOption, tmplOption TmplOption) { func (m *MysqlParser) RegisterOption(userOption UserOption, tmplOption TmplOption) {

View File

@ -49,9 +49,9 @@ func pongo2CamelString(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *p
return pongo2.AsValue(utils.CamelString(t)), nil return pongo2.AsValue(utils.CamelString(t)), nil
} }
func upperFirst(str string) string { //func upperFirst(str string) string {
return strings.Replace(str, string(str[0]), strings.ToUpper(string(str[0])), 1) // return strings.Replace(str, string(str[0]), strings.ToUpper(string(str[0])), 1)
} //}
func lowerFirst(str string) string { func lowerFirst(str string) string {
return strings.Replace(str, string(str[0]), strings.ToLower(string(str[0])), 1) return strings.Replace(str, string(str[0]), strings.ToLower(string(str[0])), 1)

View File

@ -1,13 +1,18 @@
package beegopro package beegopro
import ( import (
"github.com/beego/bee/internal/pkg/system" "go/format"
beeLogger "github.com/beego/bee/logger" "io/ioutil"
"os"
"path"
"path/filepath"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/flosch/pongo2" "github.com/flosch/pongo2"
"github.com/smartwalle/pongo2render" "github.com/smartwalle/pongo2render"
"path"
"path/filepath" "github.com/beego/bee/internal/pkg/system"
beeLogger "github.com/beego/bee/logger"
) )
// render // render
@ -34,7 +39,7 @@ func NewRender(m RenderInfo) *RenderFile {
newDescriptor, pathCtx = m.Descriptor.Parse(m.ModelName, m.Option.Path) newDescriptor, pathCtx = m.Descriptor.Parse(m.ModelName, m.Option.Path)
obj := &RenderFile{ obj := &RenderFile{
Context: make(pongo2.Context, 0), Context: make(pongo2.Context),
Option: m.Option, Option: m.Option,
ModelName: m.ModelName, ModelName: m.ModelName,
GenerateTime: m.GenerateTime, GenerateTime: m.GenerateTime,
@ -61,7 +66,7 @@ func NewRender(m RenderInfo) *RenderFile {
modelSchemas := m.Content.ToModelSchemas() modelSchemas := m.Content.ToModelSchemas()
camelPrimaryKey := modelSchemas.GetPrimaryKey() camelPrimaryKey := modelSchemas.GetPrimaryKey()
importMaps := make(map[string]struct{}, 0) importMaps := make(map[string]struct{})
if modelSchemas.IsExistTime() { if modelSchemas.IsExistTime() {
importMaps["time"] = struct{}{} importMaps["time"] = struct{}{}
} }
@ -114,10 +119,36 @@ func (r *RenderFile) Exec(name string) {
beeLogger.Log.Fatalf("Could not create the %s render tmpl: %s", name, err) beeLogger.Log.Fatalf("Could not create the %s render tmpl: %s", name, err)
return return
} }
err = r.write(r.FlushFile, buf) _, err = os.Stat(r.Descriptor.DstPath)
var orgContent []byte
if err == nil {
if org, err := os.OpenFile(r.Descriptor.DstPath, os.O_RDONLY, 0666); err == nil {
orgContent,_ = ioutil.ReadAll(org)
org.Close()
} else {
beeLogger.Log.Infof("file err %s", err)
}
}
// Replace or create when content changes
output := []byte(buf)
ext := filepath.Ext(r.FlushFile)
if r.Option.EnableFormat && ext == ".go" {
// format code
var bts []byte
bts, err = format.Source([]byte(buf))
if err != nil {
beeLogger.Log.Warnf("format buf error %s", err.Error())
}
output = bts
}
if FileContentChange(orgContent, output, GetSeg(ext)) {
err = r.write(r.FlushFile, output)
if err != nil { if err != nil {
beeLogger.Log.Fatalf("Could not create file: %s", err) beeLogger.Log.Fatalf("Could not create file: %s", err)
return return
} }
beeLogger.Log.Infof("create file '%s' from %s", r.FlushFile, r.PackageName) beeLogger.Log.Infof("create file '%s' from %s", r.FlushFile, r.PackageName)
} }
}

View File

@ -75,7 +75,7 @@ func (descriptor Descriptor) Parse(modelName string, paths map[string]string) (n
newDescriptor = descriptor newDescriptor = descriptor
render := pongo2render.NewRender("") render := pongo2render.NewRender("")
ctx = make(pongo2.Context, 0) ctx = make(pongo2.Context)
for key, value := range paths { for key, value := range paths {
absFile, err = filepath.Abs(value) absFile, err = filepath.Abs(value)
if err != nil { if err != nil {
@ -110,10 +110,7 @@ func (descriptor Descriptor) Parse(modelName string, paths map[string]string) (n
} }
func (descriptor Descriptor) IsExistScript() bool { func (descriptor Descriptor) IsExistScript() bool {
if descriptor.Script != "" { return descriptor.Script != ""
return true
}
return false
} }
func (d Descriptor) ExecScript(path string) (err error) { func (d Descriptor) ExecScript(path string) (err error) {

View File

@ -1,26 +1,27 @@
package beegopro package beegopro
import ( import (
"crypto/md5"
"errors" "errors"
"fmt" "fmt"
"github.com/beego/bee/internal/pkg/utils"
beeLogger "github.com/beego/bee/logger"
"go/format"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
"github.com/beego/bee/internal/pkg/utils"
beeLogger "github.com/beego/bee/logger"
) )
// write to file // write to file
func (c *RenderFile) write(filename string, buf string) (err error) { func (c *RenderFile) write(filename string, buf []byte) (err error) {
if utils.IsExist(filename) && !isNeedOverwrite(filename) { if utils.IsExist(filename) && !isNeedOverwrite(filename) {
return return
} }
filePath := path.Dir(filename) filePath := filepath.Dir(filename)
err = createPath(filePath) err = createPath(filePath)
if err != nil { if err != nil {
err = errors.New("write create path " + err.Error()) err = errors.New("write create path " + err.Error())
@ -37,7 +38,7 @@ func (c *RenderFile) write(filename string, buf string) (err error) {
name := path.Base(filename) name := path.Base(filename)
if utils.IsExist(filename) { if utils.IsExist(filename) {
bakName := fmt.Sprintf("%s/%s.%s.bak", filePathBak, name, time.Now().Format("2006.01.02.15.04.05")) 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) beeLogger.Log.Infof("bak file '%s'", bakName)
if err := os.Rename(filename, bakName); err != nil { if err := os.Rename(filename, bakName); err != nil {
err = errors.New("file is bak error, path is " + bakName) err = errors.New("file is bak error, path is " + bakName)
@ -46,26 +47,18 @@ func (c *RenderFile) write(filename string, buf string) (err error) {
} }
file, err := os.Create(filename) file, err := os.Create(filename)
defer file.Close() defer func() {
err = file.Close()
if err != nil {
beeLogger.Log.Fatalf("file close error, err %s", err)
}
}()
if err != nil { if err != nil {
err = errors.New("write create file " + err.Error()) err = errors.New("write create file " + err.Error())
return return
} }
output := []byte(buf) err = ioutil.WriteFile(filename, buf, 0644)
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 { if err != nil {
err = errors.New("write write file " + err.Error()) err = errors.New("write write file " + err.Error())
return return
@ -74,11 +67,7 @@ func (c *RenderFile) write(filename string, buf string) (err error) {
} }
func isNeedOverwrite(fileName string) (flag bool) { func isNeedOverwrite(fileName string) (flag bool) {
seg := "//" seg := GetSeg(filepath.Ext(fileName))
ext := filepath.Ext(fileName)
if ext == ".sql" {
seg = "--"
}
f, err := os.Open(fileName) f, err := os.Open(fileName)
if err != nil { if err != nil {
@ -183,3 +172,44 @@ func getModelType(orm string) (inputType, goType, mysqlType, tag string) {
} }
return 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 "//"
}
}

View File

@ -206,19 +206,3 @@ func concatenateError(err error, stderr string) error {
} }
return fmt.Errorf("%v: %s", err, stderr) return fmt.Errorf("%v: %s", err, stderr)
} }
// getGitProjectName 获取项目名称
func getGitProjectName(url string) (name string, err error) {
if !strings.Contains(url, ".git") {
return "", errors.New("Project address does not contain .git")
}
fileSlice := strings.Split(url, "/")
projectName := fileSlice[len(fileSlice)-1]
if projectName == "" {
return "", errors.New("Project name does not exist")
}
nameSlice := strings.Split(projectName, ".git")
return nameSlice[0], nil
}

16
main.go
View File

@ -21,19 +21,11 @@ import (
"github.com/beego/bee/cmd" "github.com/beego/bee/cmd"
"github.com/beego/bee/cmd/commands" "github.com/beego/bee/cmd/commands"
"github.com/beego/bee/config" "github.com/beego/bee/config"
"github.com/beego/bee/generate/swaggergen"
"github.com/beego/bee/utils" "github.com/beego/bee/utils"
) )
var (
workspace = os.Getenv("BeeWorkspace")
)
func main() { func main() {
currentpath, _ := os.Getwd() utils.NoticeUpdateBee()
if workspace != "" {
currentpath = workspace
}
flag.Usage = cmd.Usage flag.Usage = cmd.Usage
flag.Parse() flag.Parse()
log.SetFlags(0) log.SetFlags(0)
@ -66,12 +58,6 @@ func main() {
} }
config.LoadConfig() config.LoadConfig()
// Check if current directory is inside the GOPATH,
// if so parse the packages inside it.
if utils.IsInGOPATH(currentpath) && cmd.IfGenerateDocs(c.Name(), args) {
swaggergen.ParsePackagesFromDir(currentpath)
}
os.Exit(c.Run(c, args)) os.Exit(c.Run(c, args))
return return
} }

View File

@ -16,29 +16,38 @@ package utils
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http"
"os" "os"
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
"strconv"
"strings" "strings"
"text/template" "text/template"
"time" "time"
"unicode" "unicode"
"github.com/beego/bee/config"
"github.com/beego/bee/internal/pkg/system"
beeLogger "github.com/beego/bee/logger" beeLogger "github.com/beego/bee/logger"
"github.com/beego/bee/logger/colors" "github.com/beego/bee/logger/colors"
) )
type tagName struct {
Name string `json:"name"`
}
func GetBeeWorkPath() string { func GetBeeWorkPath() string {
beePath, err := filepath.Abs(filepath.Dir(os.Args[0])) curpath, err := os.Getwd()
if err != nil { if err != nil {
panic(err) panic(err)
} }
return beePath return curpath
} }
// Go is a basic promise implementation: it wraps calls a function in a goroutine // Go is a basic promise implementation: it wraps calls a function in a goroutine
@ -313,7 +322,7 @@ func Tmpl(text string, data interface{}) {
func CheckEnv(appname string) (apppath, packpath string, err error) { func CheckEnv(appname string) (apppath, packpath string, err error) {
gps := GetGOPATHs() gps := GetGOPATHs()
if len(gps) == 0 { if len(gps) == 0 {
beeLogger.Log.Error("if you want new a go module project,please add param `-module=true` and set env `G111MODULE=on`") beeLogger.Log.Error("if you want new a go module project,please add param `-gopath=false`.")
beeLogger.Log.Fatal("GOPATH environment variable is not set or empty") beeLogger.Log.Fatal("GOPATH environment variable is not set or empty")
} }
currpath, _ := os.Getwd() currpath, _ := os.Getwd()
@ -463,3 +472,90 @@ func IsGOMODULE() bool {
} }
return false return false
} }
func NoticeUpdateBee() {
cmd := exec.Command("go", "version")
cmd.Output()
if cmd.Process == nil || cmd.Process.Pid <= 0 {
beeLogger.Log.Warn("There is no go environment")
return
}
beeHome := system.BeegoHome
if !IsExist(beeHome) {
if err := os.MkdirAll(beeHome, 0755); err != nil {
beeLogger.Log.Fatalf("Could not create the directory: %s", err)
return
}
}
fp := beeHome + "/.noticeUpdateBee"
timeNow := time.Now().Unix()
var timeOld int64
if !IsExist(fp) {
f, err := os.Create(fp)
if err != nil {
beeLogger.Log.Warnf("Create noticeUpdateBee file err: %s", err)
return
}
defer f.Close()
}
oldContent, err := ioutil.ReadFile(fp)
if err != nil {
beeLogger.Log.Warnf("Read noticeUpdateBee file err: %s", err)
return
}
timeOld, _ = strconv.ParseInt(string(oldContent), 10, 64)
if timeNow-timeOld < 24*60*60 {
return
}
w, err := os.OpenFile(fp, os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
beeLogger.Log.Warnf("Open noticeUpdateBee file err: %s", err)
return
}
defer w.Close()
timeNowStr := strconv.FormatInt(timeNow, 10)
if _, err := w.WriteString(timeNowStr); err != nil {
beeLogger.Log.Warnf("Update noticeUpdateBee file err: %s", err)
return
}
beeLogger.Log.Info("Getting bee latest version...")
versionLast := BeeLastVersion()
versionNow := config.Version
if versionLast == ""{
beeLogger.Log.Warn("Get latest version err")
return
}
if versionNow != versionLast {
beeLogger.Log.Warnf("Update available %s ==> %s", versionNow, versionLast)
beeLogger.Log.Warn("Run `bee update` to update")
}
beeLogger.Log.Info("Your bee are up to date")
}
func BeeLastVersion() (version string) {
var url = "https://api.github.com/repos/beego/bee/tags"
resp, err := http.Get(url)
if err != nil {
beeLogger.Log.Warnf("Get bee tags from github error: %s", err)
return
}
defer resp.Body.Close()
bodyContent, _ := ioutil.ReadAll(resp.Body)
var tags []tagName
if err = json.Unmarshal(bodyContent, &tags); err != nil {
beeLogger.Log.Warnf("Unmarshal tags body error: %s", err)
return
}
if len(tags) < 1 {
beeLogger.Log.Warn("There is no tags")
return
}
last := tags[0]
re, _ := regexp.Compile(`[0-9.]+`)
versionList := re.FindStringSubmatch(last.Name)
if len(versionList) > 0 {
return versionList[0]
}
beeLogger.Log.Warn("There is no tags")
return
}