1
0
mirror of https://github.com/beego/bee.git synced 2024-11-22 05:00:54 +00:00

Merge pull request #322 from amrfaissal/fix-dirparser-and-enhancements

Fix directory parser and enhancements
This commit is contained in:
Faissal Elamraoui 2016-11-22 10:39:41 +01:00 committed by GitHub
commit 1dc55894c9
15 changed files with 113 additions and 79 deletions

View File

@ -538,14 +538,13 @@ func TestGet(t *testing.T) {
func init() {
cmdApiapp.Run = createapi
cmdApiapp.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
cmdApiapp.Flag.Var(&tables, "tables", "specify tables to generate model")
cmdApiapp.Flag.Var(&driver, "driver", "database driver: mysql, postgresql, etc.")
cmdApiapp.Flag.Var(&conn, "conn", "connection string used by the driver to connect to a database instance")
}
func createapi(cmd *Command, args []string) int {
ShowShortVersionBanner()
w := NewColorWriter(os.Stdout)
if len(args) < 1 {
@ -656,7 +655,7 @@ func checkEnv(appname string) (apppath, packpath string, err error) {
// we use the first path
gopath := gps[0]
logger.Warn("You current workdir is not inside $GOPATH/src")
logger.Warn("You current workdir is not inside $GOPATH/src.")
logger.Debugf("GOPATH: %s", __FILE__(), __LINE__(), gopath)
gosrcpath := path.Join(gopath, "src")

View File

@ -32,7 +32,7 @@ var cmdBale = &Command{
Long: `
Bale command compress all the static files in to a single binary file.
This is usefull to not have to carry static files including js, css, images
This is useful to not have to carry static files including js, css, images
and views when publishing a project.
auto-generate unpack function to main package then run it during the runtime.
@ -43,11 +43,10 @@ This is mainly used for zealots who are requiring 100% Go code.
func init() {
cmdBale.Run = runBale
cmdBale.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
}
func runBale(cmd *Command, args []string) int {
ShowShortVersionBanner()
err := loadConfig()
if err != nil {
logger.Fatalf("Failed to load configuration: %s", err)

17
bee.go
View File

@ -33,6 +33,9 @@ type Command struct {
// The args are the arguments after the command name.
Run func(cmd *Command, args []string) int
// PreRun performs an operation before running the command
PreRun func(cmd *Command, args []string)
// UsageLine is the one-line usage message.
// The first word in the line is taken to be the command name.
UsageLine string
@ -93,6 +96,8 @@ var commands = []*Command{
var logger = GetBeeLogger(os.Stdout)
func main() {
currentpath, _ := os.Getwd()
flag.Usage = usage
flag.Parse()
log.SetFlags(0)
@ -116,6 +121,17 @@ func main() {
cmd.Flag.Parse(args[1:])
args = cmd.Flag.Args()
}
if cmd.PreRun != nil {
cmd.PreRun(cmd, args)
}
// Check if current directory is inside the GOPATH,
// if so parse the packages inside it.
if strings.Contains(currentpath, GetGOPATHs()[0]+"/src") {
parsePackagesFromDir(currentpath)
}
os.Exit(cmd.Run(cmd, args))
return
}
@ -142,7 +158,6 @@ Additional help topics:
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
Use "bee help [topic]" for more information about that topic.
`
var helpTemplate = `{{if .Runnable}}usage: bee {{.UsageLine}}

4
fix.go
View File

@ -23,12 +23,12 @@ bee fix help to upgrade the application to beego 1.6
func init() {
cmdFix.Run = runFix
cmdFix.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
}
func runFix(cmd *Command, args []string) int {
ShowShortVersionBanner()
logger.Info("Upgrading the application...")
dir, err := os.Getwd()
if err != nil {
logger.Fatalf("Error while getting the current working directory: %s", err)

3
g.go
View File

@ -69,6 +69,7 @@ var fields docValue
func init() {
cmdGenerate.Run = generateCode
cmdGenerate.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
cmdGenerate.Flag.Var(&tables, "tables", "specify tables to generate model")
cmdGenerate.Flag.Var(&driver, "driver", "database driver: mysql, postgresql, etc.")
cmdGenerate.Flag.Var(&conn, "conn", "connection string used by the driver to connect to a database instance")
@ -77,8 +78,6 @@ func init() {
}
func generateCode(cmd *Command, args []string) int {
ShowShortVersionBanner()
currpath, _ := os.Getwd()
if len(args) < 1 {
logger.Fatal("Command is missing")

View File

@ -32,8 +32,6 @@ import (
"gopkg.in/yaml.v2"
"io/ioutil"
"github.com/astaxie/beego/swagger"
"github.com/astaxie/beego/utils"
)
@ -82,44 +80,60 @@ func init() {
importlist = make(map[string]string)
controllerList = make(map[string]map[string]*swagger.Item)
modelsList = make(map[string]map[string]swagger.Schema)
curPath, _ := os.Getwd()
astPkgs = map[string]*ast.Package{}
parsePackagesFromDir(curPath)
}
func parsePackagesFromDir(path string) {
parsePackageFromDir(path)
list, err := ioutil.ReadDir(path)
if err != nil {
logger.Fatalf("Cannot read directory '%s': %s", path, err)
}
for _, item := range list {
if item.IsDir() && item.Name() != "vendor" {
parsePackagesFromDir(path + "/" + item.Name())
}
func parsePackagesFromDir(dirpath string) {
c := make(chan error)
go func() {
filepath.Walk(dirpath, func(fpath string, fileInfo os.FileInfo, err error) error {
if err != nil {
return nil
}
if !fileInfo.IsDir() {
return nil
}
if fileInfo.Name() != "vendor" {
err = parsePackageFromDir(fpath)
if err != nil {
// Send the error to through the channel and continue walking
c <- fmt.Errorf("Error while parsing directory: %s", err.Error())
return nil
}
}
return nil
})
close(c)
}()
for err := range c {
logger.Warnf("%s", err)
}
}
func parsePackageFromDir(path string) {
func parsePackageFromDir(path string) error {
fileSet := token.NewFileSet()
folderPkgs, err := parser.ParseDir(fileSet, path, func(info os.FileInfo) bool {
name := info.Name()
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
}, parser.ParseComments)
if err != nil {
logger.Fatalf("Error while parsing dir at '%s': %s", path, err)
return err
}
for k, v := range folderPkgs {
astPkgs[k] = v
}
return nil
}
func generateDocs(curpath string) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path.Join(curpath, "routers", "router.go"), nil, parser.ParseComments)
if err != nil {
logger.Fatalf("Error while parsing router.go: %s", err)
}
@ -147,13 +161,13 @@ func generateDocs(curpath string) {
rootapi.Infos.Contact.URL = strings.TrimSpace(s[len("@URL"):])
} else if strings.HasPrefix(s, "@LicenseUrl") {
if rootapi.Infos.License == nil {
rootapi.Infos.License = &swagger.License{URL: strings.TrimSpace(s[len("@LicenseUrl"):])}
rootapi.Infos.License = &swagger.License{URL: strings.TrimSpace(s[len("@LicenseUrl"):])}
} else {
rootapi.Infos.License.URL = strings.TrimSpace(s[len("@LicenseUrl"):])
rootapi.Infos.License.URL = strings.TrimSpace(s[len("@LicenseUrl"):])
}
} else if strings.HasPrefix(s, "@License") {
if rootapi.Infos.License == nil {
rootapi.Infos.License = &swagger.License{Name: strings.TrimSpace(s[len("@License"):])}
rootapi.Infos.License = &swagger.License{Name: strings.TrimSpace(s[len("@License"):])}
} else {
rootapi.Infos.License.Name = strings.TrimSpace(s[len("@License"):])
}

View File

@ -298,14 +298,13 @@ var hproseAddFunctions = []string{}
func init() {
cmdHproseapp.Run = createhprose
cmdHproseapp.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
cmdHproseapp.Flag.Var(&tables, "tables", "specify tables to generate model")
cmdHproseapp.Flag.Var(&driver, "driver", "database driver: mysql, postgresql, etc.")
cmdHproseapp.Flag.Var(&conn, "conn", "connection string used by the driver to connect to a database instance")
}
func createhprose(cmd *Command, args []string) int {
ShowShortVersionBanner()
w := NewColorWriter(os.Stdout)
curpath, _ := os.Getwd()

View File

@ -64,28 +64,26 @@ var (
debugLogRecordTemplate *template.Template
)
func init() {
var (
err error
simpleLogFormat = `{{Now "2006/01/02 15:04:05"}} {{.Level}}{{.ID}} {{.Message}}{{EndLine}}`
debugLogFormat = `{{Now "2006/01/02 15:04:05"}} {{.Level}}{{.ID}} {{.Filename}}:{{.LineNo}} {{.Message}}{{EndLine}}`
)
// Initialize and parse logging templates
funcs := template.FuncMap{
"Now": Now,
"EndLine": EndLine,
}
logRecordTemplate, err = template.New("logRecordTemplate").Funcs(funcs).Parse(simpleLogFormat)
MustCheck(err)
debugLogRecordTemplate, err = template.New("dbgLogRecordTemplate").Funcs(funcs).Parse(debugLogFormat)
MustCheck(err)
}
// GetBeeLogger initializes the logger instance with a NewColorWriter output
// and returns a singleton
func GetBeeLogger(w io.Writer) *BeeLogger {
once.Do(func() {
var (
err error
simpleLogFormat = `{{Now "2006/01/02 15:04:05"}} {{.Level}}{{.ID}} {{.Message}}{{EndLine}}`
debugLogFormat = `{{Now "2006/01/02 15:04:05"}} {{.Level}}{{.ID}} {{.Filename}}:{{.LineNo}} {{.Message}}{{EndLine}}`
)
// Initialize and parse logging templates
funcs := template.FuncMap{
"Now": Now,
"EndLine": EndLine,
}
logRecordTemplate, err = template.New("simpleLogFormat").Funcs(funcs).Parse(simpleLogFormat)
MustCheck(err)
debugLogRecordTemplate, err = template.New("debugLogFormat").Funcs(funcs).Parse(debugLogFormat)
MustCheck(err)
instance = &BeeLogger{output: NewColorWriter(w)}
})
return instance

View File

@ -56,14 +56,13 @@ var mConn docValue
func init() {
cmdMigrate.Run = runMigration
cmdMigrate.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
cmdMigrate.Flag.Var(&mDriver, "driver", "database driver: mysql, postgres, sqlite, etc.")
cmdMigrate.Flag.Var(&mConn, "conn", "connection string used by the driver to connect to a database instance")
}
// runMigration is the entry point for starting a migration
func runMigration(cmd *Command, args []string) int {
ShowShortVersionBanner()
currpath, _ := os.Getwd()
gps := GetGOPATHs()

14
new.go
View File

@ -52,24 +52,24 @@ the following files/directories structure:
func init() {
cmdNew.Run = createApp
cmdNew.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
}
func createApp(cmd *Command, args []string) int {
ShowShortVersionBanner()
w := NewColorWriter(os.Stdout)
if len(args) != 1 {
logger.Error("Argument [appname] is missing")
os.Exit(2)
logger.Fatal("Argument [appname] is missing")
}
apppath, packpath, err := checkEnv(args[0])
if err != nil {
fmt.Println(err)
os.Exit(2)
logger.Fatalf("%s", err)
}
if isExist(apppath) {
logger.Errorf("Path (%s) already exists", apppath)
logger.Warn("Do you want to overwrite it? [Yes|No] ")
logger.Errorf(bold("Application '%s' already exists"), apppath)
logger.Warn(bold("Do you want to overwrite it? [Yes|No] "))
if !askForConfirmation() {
os.Exit(2)
}

View File

@ -101,6 +101,7 @@ func init() {
fs.BoolVar(&verbose, "v", false, "verbose")
cmdPack.Flag = *fs
cmdPack.Run = packApp
cmdPack.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
w = NewColorWriter(os.Stdout)
}
@ -449,8 +450,6 @@ func packDirectory(excludePrefix []string, excludeSuffix []string,
}
func packApp(cmd *Command, args []string) int {
ShowShortVersionBanner()
curPath, _ := os.Getwd()
thePath := ""
@ -593,11 +592,13 @@ func packApp(cmd *Command, args []string) int {
}
}
logger.Infof("Writing to output: %s", outputP)
err = packDirectory(exp, exs, exr, tmpdir, thePath)
if err != nil {
logger.Fatal(err.Error())
}
logger.Infof("Writing to output: %s", outputP)
logger.Success("Application packed!")
return 0
}

3
run.go
View File

@ -56,6 +56,7 @@ var (
func init() {
cmdRun.Run = runApp
cmdRun.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
cmdRun.Flag.Var(&mainFiles, "main", "specify main go files")
cmdRun.Flag.Var(&gendoc, "gendoc", "auto generate the docs")
cmdRun.Flag.Var(&downdoc, "downdoc", "auto download swagger file when not exist")
@ -67,8 +68,6 @@ func init() {
}
func runApp(cmd *Command, args []string) int {
ShowShortVersionBanner()
if len(args) == 0 || args[0] == "watchall" {
currpath, _ = os.Getwd()

View File

@ -53,6 +53,7 @@ var docport docValue
func init() {
cmdRundocs.Run = runDocs
cmdRundocs.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
cmdRundocs.Flag.Var(&isDownload, "isDownload", "weather download the Swagger Docs")
cmdRundocs.Flag.Var(&docport, "docport", "doc server port")
}

View File

@ -31,6 +31,7 @@ var cmdTest = &Command{
func init() {
cmdTest.Run = testApp
cmdTest.PreRun = func(cmd *Command, args []string) { ShowShortVersionBanner() }
}
func safePathAppend(arr []string, paths ...string) []string {

38
util.go
View File

@ -70,24 +70,34 @@ func GetGOPATHs() []string {
func IsBeegoProject(thePath string) bool {
mainFiles := []string{}
hasBeegoRegex := regexp.MustCompile(`(?s)package main.*?import.*?\(.*?github.com/astaxie/beego".*?\).*func main()`)
c := make(chan error)
// Walk the application path tree to look for main files.
// Main files must satisfy the 'hasBeegoRegex' regular expression.
err := filepath.Walk(thePath, func(fpath string, f os.FileInfo, err error) error {
if !f.IsDir() { // Skip sub-directories
data, _err := ioutil.ReadFile(fpath)
if _err != nil {
return _err
go func() {
filepath.Walk(thePath, func(fpath string, f os.FileInfo, err error) error {
if err != nil {
return nil
}
if len(hasBeegoRegex.Find(data)) > 0 {
mainFiles = append(mainFiles, fpath)
}
}
return nil
})
// Skip sub-directories
if !f.IsDir() {
var data []byte
data, err = ioutil.ReadFile(fpath)
if err != nil {
c <- err
return nil
}
if err != nil {
logger.Fatalf("Unable to walk '%s' tree: %v", thePath, err)
return false
if len(hasBeegoRegex.Find(data)) > 0 {
mainFiles = append(mainFiles, fpath)
}
}
return nil
})
close(c)
}()
if err := <-c; err != nil {
logger.Fatalf("Unable to walk '%s' tree: %s", thePath, err)
}
if len(mainFiles) > 0 {