From 3627eb2ddcb9f9f58d6c58d12bd5947f618051c0 Mon Sep 17 00:00:00 2001 From: Sergey Lanzman Date: Sat, 23 Jul 2016 21:05:44 +0300 Subject: [PATCH 01/14] refactor generate migration --- g.go | 8 +-- g_migration.go | 157 ++++++++++++++++++++++++++++++++++++++++++++++++- g_scaffold.go | 122 +++----------------------------------- 3 files changed, 166 insertions(+), 121 deletions(-) diff --git a/g.go b/g.go index 3cccfbf..bc4b123 100644 --- a/g.go +++ b/g.go @@ -170,11 +170,9 @@ func generateCode(cmd *Command, args []string) int { upsql := "" downsql := "" if fields != "" { - upsql = `m.SQL("CREATE TABLE ` + mname + "(" + generateSQLFromFields(fields.String()) + `)");` - downsql = `m.SQL("DROP TABLE ` + "`" + mname + "`" + `")` - if driver == "postgres" { - downsql = strings.Replace(downsql, "`", "", -1) - } + dbMigrator := newDBDriver() + upsql = dbMigrator.generateCreateUp(mname) + downsql = dbMigrator.generateCreateDown(mname) } generateMigration(mname, upsql, downsql, currpath) case "controller": diff --git a/g_migration.go b/g_migration.go index 4135ebe..c0485ef 100644 --- a/g_migration.go +++ b/g_migration.go @@ -25,15 +25,168 @@ import ( const ( MPath = "migrations" MDateFormat = "20060102_150405" + DBPath = "database" ) +type DBDriver interface { + generateCreateUp(tableName string) string + generateCreateDown(tableName string) string +} + +type mysqlDriver struct{} + +func (m mysqlDriver) generateCreateUp(tableName string) string { + upsql := `m.SQL("CREATE TABLE ` + tableName + "(" + m.generateSQLFromFields(fields.String()) + `)");` + return upsql +} + +func (m mysqlDriver) generateCreateDown(tableName string) string { + downsql := `m.SQL("DROP TABLE ` + "`" + tableName + "`" + `")` + return downsql +} + +func (m mysqlDriver) generateSQLFromFields(fields string) string { + sql, tags := "", "" + fds := strings.Split(fields, ",") + for i, v := range fds { + kv := strings.SplitN(v, ":", 2) + if len(kv) != 2 { + ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n") + return "" + } + typ, tag := m.getSQLType(kv[1]) + if typ == "" { + ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n") + return "" + } + if i == 0 && strings.ToLower(kv[0]) != "id" { + sql += "`id` int(11) NOT NULL AUTO_INCREMENT," + tags = tags + "PRIMARY KEY (`id`)," + } + sql += "`" + snakeString(kv[0]) + "` " + typ + "," + if tag != "" { + tags = tags + fmt.Sprintf(tag, "`"+snakeString(kv[0])+"`") + "," + } + } + sql = strings.TrimRight(sql+tags, ",") + return sql +} + +func (m mysqlDriver) getSQLType(ktype string) (tp, tag string) { + kv := strings.SplitN(ktype, ":", 2) + switch kv[0] { + case "string": + if len(kv) == 2 { + return "varchar(" + kv[1] + ") NOT NULL", "" + } + return "varchar(128) NOT NULL", "" + case "text": + return "longtext NOT NULL", "" + case "auto": + return "int(11) NOT NULL AUTO_INCREMENT", "" + case "pk": + return "int(11) NOT NULL", "PRIMARY KEY (%s)" + case "datetime": + return "datetime NOT NULL", "" + case "int", "int8", "int16", "int32", "int64": + fallthrough + case "uint", "uint8", "uint16", "uint32", "uint64": + return "int(11) DEFAULT NULL", "" + case "bool": + return "tinyint(1) NOT NULL", "" + case "float32", "float64": + return "float NOT NULL", "" + case "float": + return "float NOT NULL", "" + } + return "", "" +} + +type postgresqlDriver struct{} + +func (m postgresqlDriver) generateCreateUp(tableName string) string { + upsql := `m.SQL("CREATE TABLE ` + tableName + "(" + m.generateSQLFromFields(fields.String()) + `)");` + return upsql +} + +func (m postgresqlDriver) generateCreateDown(tableName string) string { + downsql := `m.SQL("DROP TABLE ` + tableName + `")` + return downsql +} + +func (m postgresqlDriver) generateSQLFromFields(fields string) string { + sql, tags := "", "" + fds := strings.Split(fields, ",") + for i, v := range fds { + kv := strings.SplitN(v, ":", 2) + if len(kv) != 2 { + ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n") + return "" + } + typ, tag := m.getSQLType(kv[1]) + if typ == "" { + ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n") + return "" + } + if i == 0 && strings.ToLower(kv[0]) != "id" { + sql += "id interger serial primary key," + } + sql += snakeString(kv[0]) + " " + typ + "," + if tag != "" { + tags = tags + fmt.Sprintf(tag, snakeString(kv[0])) + "," + } + } + if tags != "" { + sql = strings.TrimRight(sql+" "+tags, ",") + } else { + sql = strings.TrimRight(sql, ",") + } + return sql +} + +func (m postgresqlDriver) getSQLType(ktype string) (tp, tag string) { + kv := strings.SplitN(ktype, ":", 2) + switch kv[0] { + case "string": + if len(kv) == 2 { + return "char(" + kv[1] + ") NOT NULL", "" + } + return "TEXT NOT NULL", "" + case "text": + return "TEXT NOT NULL", "" + case "auto", "pk": + return "serial primary key", "" + case "datetime": + return "TIMESTAMP WITHOUT TIME ZONE NOT NULL", "" + case "int", "int8", "int16", "int32", "int64": + fallthrough + case "uint", "uint8", "uint16", "uint32", "uint64": + return "integer DEFAULT NULL", "" + case "bool": + return "boolean NOT NULL", "" + case "float32", "float64", "float": + return "numeric NOT NULL", "" + } + return "", "" +} + +func newDBDriver() DBDriver { + switch driver { + case "mysql": + return mysqlDriver{} + case "postgres": + return postgresqlDriver{} + default: + panic("driver not supported") + } +} + // generateMigration generates migration file template for database schema update. // The generated file template consists of an up() method for updating schema and // a down() method for reverting the update. func generateMigration(mname, upsql, downsql, curpath string) { w := NewColorWriter(os.Stdout) - - migrationFilePath := path.Join(curpath, "database", MPath) + migrationFilePath := path.Join(curpath, DBPath, MPath) if _, err := os.Stat(migrationFilePath); os.IsNotExist(err) { // create migrations directory if err := os.MkdirAll(migrationFilePath, 0777); err != nil { diff --git a/g_scaffold.go b/g_scaffold.go index 8222b57..cccda16 100644 --- a/g_scaffold.go +++ b/g_scaffold.go @@ -1,9 +1,6 @@ package main -import ( - "fmt" - "strings" -) +import "strings" func generateScaffold(sname, fields, currpath, driver, conn string) { ColorLog("[INFO] Do you want to create a '%v' model? [Yes|No] ", sname) @@ -31,11 +28,13 @@ func generateScaffold(sname, fields, currpath, driver, conn string) { upsql := "" downsql := "" if fields != "" { - upsql = `m.SQL("CREATE TABLE ` + sname + "(" + generateSQLFromFields(fields) + `)");` - downsql = `m.SQL("DROP TABLE ` + "`" + sname + "`" + `")` - if driver == "" { - downsql = strings.Replace(downsql, "`", "", -1) - } + dbMigrator := newDBDriver() + upsql = dbMigrator.generateCreateUp(sname) + downsql = dbMigrator.generateCreateDown(sname) + //todo remove + //if driver == "" { + // downsql = strings.Replace(downsql, "`", "", -1) + //} } generateMigration(sname, upsql, downsql, currpath) } @@ -47,108 +46,3 @@ func generateScaffold(sname, fields, currpath, driver, conn string) { } ColorLog("[INFO] All done! Don't forget to add beego.Router(\"/%v\" ,&controllers.%vController{}) to routers/route.go\n", sname, strings.Title(sname)) } - -func generateSQLFromFields(fields string) string { - sql := "" - tags := "" - fds := strings.Split(fields, ",") - for i, v := range fds { - kv := strings.SplitN(v, ":", 2) - if len(kv) != 2 { - ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n") - return "" - } - typ, tag := "", "" - switch driver { - case "mysql": - typ, tag = getSQLTypeMysql(kv[1]) - case "postgres": - typ, tag = getSQLTypePostgresql(kv[1]) - default: - typ, tag = getSQLTypeMysql(kv[1]) - } - if typ == "" { - ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n") - return "" - } - if i == 0 && strings.ToLower(kv[0]) != "id" { - switch driver { - case "mysql": - sql = sql + "`id` int(11) NOT NULL AUTO_INCREMENT," - tags = tags + "PRIMARY KEY (`id`)," - case "postgres": - sql = sql + "id interger serial primary key," - default: - sql = sql + "`id` int(11) NOT NULL AUTO_INCREMENT," - tags = tags + "PRIMARY KEY (`id`)," - } - } - - sql = sql + "`" + snakeString(kv[0]) + "` " + typ + "," - if tag != "" { - tags = tags + fmt.Sprintf(tag, "`"+snakeString(kv[0])+"`") + "," - } - } - if driver == "postgres" { - sql = strings.Replace(sql, "`", "", -1) - tags = strings.Replace(tags, "`", "", -1) - } - sql = strings.TrimRight(sql+tags, ",") - return sql -} - -func getSQLTypeMysql(ktype string) (tp, tag string) { - kv := strings.SplitN(ktype, ":", 2) - switch kv[0] { - case "string": - if len(kv) == 2 { - return "varchar(" + kv[1] + ") NOT NULL", "" - } - return "varchar(128) NOT NULL", "" - case "text": - return "longtext NOT NULL", "" - case "auto": - return "int(11) NOT NULL AUTO_INCREMENT", "" - case "pk": - return "int(11) NOT NULL", "PRIMARY KEY (%s)" - case "datetime": - return "datetime NOT NULL", "" - case "int", "int8", "int16", "int32", "int64": - fallthrough - case "uint", "uint8", "uint16", "uint32", "uint64": - return "int(11) DEFAULT NULL", "" - case "bool": - return "tinyint(1) NOT NULL", "" - case "float32", "float64": - return "float NOT NULL", "" - case "float": - return "float NOT NULL", "" - } - return "", "" -} - -func getSQLTypePostgresql(ktype string) (tp, tag string) { - kv := strings.SplitN(ktype, ":", 2) - switch kv[0] { - case "string": - if len(kv) == 2 { - return "char(" + kv[1] + ") NOT NULL", "" - } - return "TEXT NOT NULL", "" - case "text": - return "TEXT NOT NULL", "" - case "auto", "pk": - return "serial primary key", "" - case "datetime": - return "TIMESTAMP WITHOUT TIME ZONE NOT NULL", "" - case "int", "int8", "int16", "int32", "int64": - fallthrough - case "uint", "uint8", "uint16", "uint32", "uint64": - return "integer DEFAULT NULL", "" - case "bool": - return "boolean NOT NULL", "" - case "float32", "float64", "float": - return "numeric NOT NULL", "" - } - return "", "" -} From cad9b71bbf09924b5ff821b98443c57ac92ffeda Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 19 Aug 2016 22:48:21 +0800 Subject: [PATCH 02/14] hotfix: fix the generate from conn. --- apiapp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiapp.go b/apiapp.go index dda3a22..5a07120 100644 --- a/apiapp.go +++ b/apiapp.go @@ -606,7 +606,7 @@ func createapi(cmd *Command, args []string) int { ColorLog("[INFO] Using '%s' as 'driver'\n", driver) ColorLog("[INFO] Using '%s' as 'conn'\n", conn) ColorLog("[INFO] Using '%s' as 'tables'\n", tables) - generateAppcode(string(driver), string(conn), "3", string(tables), path.Join(apppath, args[0])) + generateAppcode(string(driver), string(conn), "3", string(tables), apppath) } else { os.Mkdir(path.Join(apppath, "models"), 0755) fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models"), "\x1b[0m") From 340859ea10c1f7e8de1f1aa57e13533ca11b2a4a Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 19 Aug 2016 23:00:08 +0800 Subject: [PATCH 03/14] remove docs package --- apiapp.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apiapp.go b/apiapp.go index 5a07120..d76bf34 100644 --- a/apiapp.go +++ b/apiapp.go @@ -69,7 +69,6 @@ EnableDocs = true var apiMaingo = `package main import ( - _ "{{.Appname}}/docs" _ "{{.Appname}}/routers" "github.com/astaxie/beego" @@ -87,7 +86,6 @@ func main() { var apiMainconngo = `package main import ( - _ "{{.Appname}}/docs" _ "{{.Appname}}/routers" "github.com/astaxie/beego" @@ -578,8 +576,6 @@ func createapi(cmd *Command, args []string) int { fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "conf"), "\x1b[0m") os.Mkdir(path.Join(apppath, "controllers"), 0755) fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "controllers"), "\x1b[0m") - os.Mkdir(path.Join(apppath, "docs"), 0755) - fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "docs"), "\x1b[0m") os.Mkdir(path.Join(apppath, "tests"), 0755) fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "tests"), "\x1b[0m") fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "conf", "app.conf"), "\x1b[0m") From 6ccd0e7d9f6d3b5d029d7f0c9975286f623896b6 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 19 Aug 2016 23:31:25 +0800 Subject: [PATCH 04/14] remove bee api default docs --- apiapp.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/apiapp.go b/apiapp.go index d76bf34..d05e0ad 100644 --- a/apiapp.go +++ b/apiapp.go @@ -631,9 +631,6 @@ func createapi(cmd *Command, args []string) int { fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models", "user.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "models", "user.go"), apiModels2) - fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "docs", "doc.go"), "\x1b[0m") - WriteToFile(path.Join(apppath, "docs", "doc.go"), "package docs") - fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "main.go"), strings.Replace(apiMaingo, "{{.Appname}}", packpath, -1)) From 31eaaa14e79638079f5d8fee808aa1bbd4546a7d Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 19 Aug 2016 23:31:52 +0800 Subject: [PATCH 05/14] fix: if current path is in GOPATH, create api in current path --- apiapp.go | 10 ++++++++++ new.go | 22 ++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apiapp.go b/apiapp.go index d05e0ad..f79a7f8 100644 --- a/apiapp.go +++ b/apiapp.go @@ -645,9 +645,19 @@ func checkEnv(appname string) (apppath, packpath string, err error) { ColorLog("[ERRO] Fail to start[ %s ]\n", "GOPATH environment variable is not set or empty") os.Exit(2) } + currpath, _ := os.Getwd() + currpath = path.Join(currpath, appname) + for _, gpath := range gps { + gsrcpath := path.Join(gpath, "src") + if strings.HasPrefix(currpath, gsrcpath) { + return currpath, currpath[len(gsrcpath):], nil + } + } + // In case of multiple paths in the GOPATH, by default // we use the first path gopath := gps[0] + ColorLog("[%s]You current workdir is not a $GOPATH/src, bee will create the application in GOPATH: %s\n", WARN, gopath) Debugf("GOPATH: %s", gopath) gosrcpath := path.Join(gopath, "src") diff --git a/new.go b/new.go index ccdc4f9..e0ba92f 100644 --- a/new.go +++ b/new.go @@ -56,26 +56,16 @@ func init() { func createApp(cmd *Command, args []string) int { ShowShortVersionBanner() - w := NewColorWriter(os.Stdout) - if len(args) != 1 { ColorLog("[ERRO] Argument [appname] is missing\n") os.Exit(2) } - - gps := GetGOPATHs() - if len(gps) == 0 { - ColorLog("[ERRO] Fail to start[ %s ]\n", "GOPATH environment variable is not set or empty") + apppath, packpath, err := checkEnv(args[0]) + if err != nil { + fmt.Println(err) os.Exit(2) } - // In case of multiple paths in the GOPATH, by default - // we use the first path - gopath := gps[0] - Debugf("GOPATH: %s", gopath) - - gosrcpath := path.Join(gopath, "src") // User's workspace - apppath := path.Join(gosrcpath, args[0]) if isExist(apppath) { ColorLog("[ERRO] Path (%s) already exists\n", apppath) @@ -119,13 +109,13 @@ func createApp(cmd *Command, args []string) int { WriteToFile(path.Join(apppath, "views", "index.tpl"), indextpl) fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "routers", "router.go"), "\x1b[0m") - WriteToFile(path.Join(apppath, "routers", "router.go"), strings.Replace(router, "{{.Appname}}", strings.Join(strings.Split(apppath[len(gosrcpath)+1:], string(path.Separator)), "/"), -1)) + WriteToFile(path.Join(apppath, "routers", "router.go"), strings.Replace(router, "{{.Appname}}", packpath, -1)) fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "tests", "default_test.go"), "\x1b[0m") - WriteToFile(path.Join(apppath, "tests", "default_test.go"), strings.Replace(test, "{{.Appname}}", strings.Join(strings.Split(apppath[len(gosrcpath)+1:], string(path.Separator)), "/"), -1)) + WriteToFile(path.Join(apppath, "tests", "default_test.go"), strings.Replace(test, "{{.Appname}}", packpath, -1)) fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m") - WriteToFile(path.Join(apppath, "main.go"), strings.Replace(maingo, "{{.Appname}}", strings.Join(strings.Split(apppath[len(gosrcpath)+1:], string(path.Separator)), "/"), -1)) + WriteToFile(path.Join(apppath, "main.go"), strings.Replace(maingo, "{{.Appname}}", packpath, -1)) ColorLog("[SUCC] New application successfully created!\n") return 0 From b5bf9d07c3d0b345ee0c73f2cb65469368bf9bd4 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 19 Aug 2016 23:45:18 +0800 Subject: [PATCH 06/14] unzip to swagger while not swagger-2 --- apiapp.go | 2 +- rundocs.go | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/apiapp.go b/apiapp.go index f79a7f8..4d4e58a 100644 --- a/apiapp.go +++ b/apiapp.go @@ -650,7 +650,7 @@ func checkEnv(appname string) (apppath, packpath string, err error) { for _, gpath := range gps { gsrcpath := path.Join(gpath, "src") if strings.HasPrefix(currpath, gsrcpath) { - return currpath, currpath[len(gsrcpath):], nil + return currpath, currpath[len(gsrcpath)+1:], nil } } diff --git a/rundocs.go b/rundocs.go index 8c840af..35eef7e 100644 --- a/rundocs.go +++ b/rundocs.go @@ -20,6 +20,7 @@ import ( "log" "net/http" "os" + "strings" ) var cmdRundocs = &Command{ @@ -120,6 +121,7 @@ func unzipAndDelete(src string) error { } defer r.Close() + rp := strings.NewReplacer("swagger-"+swaggerVersion, "swagger") for _, f := range r.File { rc, err := f.Open() if err != nil { @@ -127,11 +129,12 @@ func unzipAndDelete(src string) error { } defer rc.Close() + fname := rp.Replace(f.Name) if f.FileInfo().IsDir() { - os.MkdirAll(f.Name, f.Mode()) + os.MkdirAll(fname, f.Mode()) } else { f, err := os.OpenFile( - f.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } @@ -143,11 +146,6 @@ func unzipAndDelete(src string) error { } } } - os.RemoveAll("swagger") - err = os.Rename("swagger-"+swaggerVersion, "swagger") - if err != nil { - ColorLog("[%s]Rename swagger-%s to swagger:%s\n", ERRO, swaggerVersion, err) - } ColorLog("[%s]Start delete src file %s\n", INFO, src) return os.RemoveAll(src) } From 5309c72ef751bd4edb45d1702996eb279033b281 Mon Sep 17 00:00:00 2001 From: astaxie Date: Sat, 20 Aug 2016 00:14:39 +0800 Subject: [PATCH 07/14] support success response array objects --- g_docs.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/g_docs.go b/g_docs.go index 3a9b98d..76d11f7 100644 --- a/g_docs.go +++ b/g_docs.go @@ -405,6 +405,23 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat } modelsList[pkgpath+controllerName][st[2]] = mod appendModels(cmpath, pkgpath, controllerName, realTypes) + } else if st[1] == "{array}" { + rs.Schema.Type = "array" + if sType, ok := basicTypes[st[2]]; ok { + typeFormat := strings.Split(sType, ":") + rs.Schema.Type = typeFormat[0] + rs.Schema.Format = typeFormat[1] + } else { + cmpath, m, mod, realTypes := getModel(st[2]) + rs.Schema.Items = &swagger.Propertie{ + Ref: "#/definitions/" + m, + } + if _, ok := modelsList[pkgpath+controllerName]; !ok { + modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema, 0) + } + modelsList[pkgpath+controllerName][st[2]] = mod + appendModels(cmpath, pkgpath, controllerName, realTypes) + } } opts.Responses[st[0]] = rs } else if strings.HasPrefix(t, "@Param") { From ca2f60c72d8d7cb3a3ebcea51612b0cfc77c8ca7 Mon Sep 17 00:00:00 2001 From: tnextday Date: Sat, 20 Aug 2016 11:17:30 +0800 Subject: [PATCH 08/14] add array type support in comment param --- g_docs.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/g_docs.go b/g_docs.go index 3a9b98d..aa82fef 100644 --- a/g_docs.go +++ b/g_docs.go @@ -442,16 +442,33 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat modelsList[pkgpath+controllerName][typ] = mod appendModels(cmpath, pkgpath, controllerName, realTypes) } else { + isArray := false + paraType := "" + paraFormat := "" + if strings.HasPrefix(typ, "[]") { + typ = typ[2:] + isArray = true + } if typ == "string" || typ == "number" || typ == "integer" || typ == "boolean" || typ == "array" || typ == "file" { - para.Type = typ + paraType = typ } else if sType, ok := basicTypes[typ]; ok { typeFormat := strings.Split(sType, ":") - para.Type = typeFormat[0] - para.Format = typeFormat[1] + paraType = typeFormat[0] + paraFormat = typeFormat[1] } else { fmt.Fprintf(os.Stderr, "[%s.%s] Unknow param type: %s\n", controllerName, funcName, typ) } + if isArray { + para.Type = "array" + para.Items = &swagger.ParameterItems{ + Type: paraType, + Format: paraFormat, + } + } else { + para.Type = paraType + para.Format = paraFormat + } } if len(p) > 4 { para.Required, _ = strconv.ParseBool(p[3]) @@ -614,7 +631,6 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp Type: typeFormat[0], Format: typeFormat[1], } - } else { mp.Items = &swagger.Propertie{ Ref: "#/definitions/" + realType, From c3ff72ae77166485b35aeb8d875356360967906d Mon Sep 17 00:00:00 2001 From: tnextday Date: Sat, 20 Aug 2016 15:12:15 +0800 Subject: [PATCH 09/14] Add support for query param array format. exmple: // @Param app query []string true support multipil app params Update support for responses object format. exmple: // @Success 200 success // @Success 200 {object} int64 success count // @Success 200 {object} []int64 success ids // @Success 200 {array} int64 success ids --- g_docs.go | 109 ++++++++++++++++++++++++------------------------------ 1 file changed, 48 insertions(+), 61 deletions(-) diff --git a/g_docs.go b/g_docs.go index c977d9c..1be9fba 100644 --- a/g_docs.go +++ b/g_docs.go @@ -328,6 +328,17 @@ func isSystemPackage(pkgpath string) bool { return false } +func peekNextSplitString(ss string) (s string, spacePos int) { + spacePos = strings.IndexFunc(ss, unicode.IsSpace) + if spacePos < 0 { + s = ss + spacePos = len(ss) + } else { + s = strings.TrimSpace(ss[:spacePos]) + } + return +} + // parse the func comments func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpath string) error { var routerPath string @@ -358,72 +369,48 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat } else if strings.HasPrefix(t, "@Success") { ss := strings.TrimSpace(t[len("@Success"):]) rs := swagger.Response{} - st := make([]string, 3) - j := 0 - var tmp []rune - start := false - - for i, c := range ss { - if unicode.IsSpace(c) { - if !start && j < 2 { - continue - } - if j == 0 || j == 1 { - st[j] = string(tmp) - tmp = make([]rune, 0) - j++ - start = false - if j == 1 { - continue - } else { - st[j] = strings.TrimSpace(ss[i+1:]) - break - - } - } - } else { - start = true - tmp = append(tmp, c) + respCode, pos := peekNextSplitString(ss) + ss = strings.TrimSpace(ss[pos:]) + respType, pos := peekNextSplitString(ss) + if respType == "{object}" || respType == "{array}" { + isArray := respType == "{array}" + ss = strings.TrimSpace(ss[pos:]) + schemaName, pos := peekNextSplitString(ss) + if schemaName == "" { + ColorLog("[ERRO][%s.%s] Schema must follow {object} or {array}\n", controllerName, funcName) + os.Exit(-1) } - } - if len(tmp) > 0 && st[2] == "" { - st[2] = strings.TrimSpace(string(tmp)) - } - rs.Description = st[2] - if st[1] == "{object}" { - if st[2] == "" { - panic(controllerName + " " + funcName + " has no object") + if strings.HasPrefix(schemaName, "[]") { + schemaName = schemaName[2:] + isArray = true } - cmpath, m, mod, realTypes := getModel(st[2]) - //ll := strings.Split(st[2], ".") - //opts.Type = ll[len(ll)-1] - rs.Schema = &swagger.Schema{ - Ref: "#/definitions/" + m, - } - if _, ok := modelsList[pkgpath+controllerName]; !ok { - modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema, 0) - } - modelsList[pkgpath+controllerName][st[2]] = mod - appendModels(cmpath, pkgpath, controllerName, realTypes) - } else if st[1] == "{array}" { - rs.Schema.Type = "array" - if sType, ok := basicTypes[st[2]]; ok { + schema := swagger.Schema{} + if sType, ok := basicTypes[schemaName]; ok { typeFormat := strings.Split(sType, ":") - rs.Schema.Type = typeFormat[0] - rs.Schema.Format = typeFormat[1] + schema.Type = typeFormat[0] + schema.Format = typeFormat[1] } else { - cmpath, m, mod, realTypes := getModel(st[2]) - rs.Schema.Items = &swagger.Propertie{ - Ref: "#/definitions/" + m, - } + cmpath, m, mod, realTypes := getModel(schemaName) + schema.Ref = "#/definitions/" + m if _, ok := modelsList[pkgpath+controllerName]; !ok { modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema, 0) } - modelsList[pkgpath+controllerName][st[2]] = mod + modelsList[pkgpath+controllerName][schemaName] = mod appendModels(cmpath, pkgpath, controllerName, realTypes) } + if isArray { + rs.Schema = &swagger.Schema{ + Type: "array", + Items: &schema, + } + }else { + rs.Schema = &schema + } + rs.Description = strings.TrimSpace(ss[pos:]) + } else { + rs.Description = strings.TrimSpace(ss) } - opts.Responses[st[0]] = rs + opts.Responses[respCode] = rs } else if strings.HasPrefix(t, "@Param") { para := swagger.Parameter{} p := getparams(strings.TrimSpace(t[len("@Param "):])) @@ -443,7 +430,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat case "body": break default: - fmt.Fprintf(os.Stderr, "[%s.%s] Unknow param location: %s, Possible values are `query`, `header`, `path`, `formData` or `body`.\n", controllerName, funcName, p[1]) + ColorLog("[WARN][%s.%s] Unknow param location: %s, Possible values are `query`, `header`, `path`, `formData` or `body`.\n", controllerName, funcName, p[1]) } para.In = p[1] pp := strings.Split(p[2], ".") @@ -474,7 +461,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat paraType = typeFormat[0] paraFormat = typeFormat[1] } else { - fmt.Fprintf(os.Stderr, "[%s.%s] Unknow param type: %s\n", controllerName, funcName, typ) + ColorLog("[WARN][%s.%s] Unknow param type: %s\n", controllerName, funcName, typ) } if isArray { para.Type = "array" @@ -625,7 +612,7 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp } ts, ok := d.Decl.(*ast.TypeSpec) if !ok { - ColorLog("Unknown type without TypeSec: %v", d) + ColorLog("Unknown type without TypeSec: %v\n", d) os.Exit(1) } st, ok := ts.Type.(*ast.StructType) @@ -717,8 +704,8 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp } } if m.Title == "" { - ColorLog("can't find the object: %s", str) - os.Exit(1) + ColorLog("[ERRO]can't find the object: %s\n", str) + //os.Exit(1) } if len(rootapi.Definitions) == 0 { rootapi.Definitions = make(map[string]swagger.Schema) From c9d5fbfe64e330d6c0293f175c126d2c4bc07912 Mon Sep 17 00:00:00 2001 From: Kyaw Myint Thein Date: Sun, 21 Aug 2016 10:55:10 +0800 Subject: [PATCH 10/14] add runmode flag on bee run to set BEEGO_RUNMODE env --- run.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/run.go b/run.go index b2f94da..8aab6b5 100644 --- a/run.go +++ b/run.go @@ -24,7 +24,7 @@ import ( ) var cmdRun = &Command{ - UsageLine: "run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] [-vendor=true] [-e=folderToExclude] [-tags=goBuildTags]", + UsageLine: "run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] [-vendor=true] [-e=folderToExclude] [-tags=goBuildTags] [-runmode=BEEGO_RUNMODE]", Short: "run the app and start a Web server for development", Long: ` Run command will supervise the file system of the beego project using inotify, @@ -51,6 +51,8 @@ var ( vendorWatch bool // Current user workspace currentGoPath string + // Current runmode + runmode string ) func init() { @@ -61,6 +63,7 @@ func init() { cmdRun.Flag.Var(&excludedPaths, "e", "Excluded paths[].") cmdRun.Flag.BoolVar(&vendorWatch, "vendor", false, "Watch vendor folder") cmdRun.Flag.StringVar(&buildTags, "tags", "", "Build tags (https://golang.org/pkg/go/build/)") + cmdRun.Flag.StringVar(&runmode, "runmode", "", "Set BEEGO_RUNMODE env variable.") exit = make(chan bool) } @@ -100,6 +103,16 @@ func runApp(cmd *Command, args []string) int { Debugf("current path:%s\n", currpath) + if runmode == "prod" || runmode == "dev"{ + os.Setenv("BEEGO_RUNMODE", runmode) + ColorLog("[INFO] Using '%s' as 'runmode'\n", os.Getenv("BEEGO_RUNMODE")) + }else if runmode != ""{ + os.Setenv("BEEGO_RUNMODE", runmode) + ColorLog("[WARN] Using '%s' as 'runmode'\n", os.Getenv("BEEGO_RUNMODE")) + }else if os.Getenv("BEEGO_RUNMODE") != ""{ + ColorLog("[WARN] Using '%s' as 'runmode'\n", os.Getenv("BEEGO_RUNMODE")) + } + err := loadConfig() if err != nil { ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err) From 368b69b73f82763c386ab9314f7b7d1c089b3939 Mon Sep 17 00:00:00 2001 From: Kyaw Myint Thein Date: Sun, 21 Aug 2016 10:56:28 +0800 Subject: [PATCH 11/14] update readme file for bee run --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fecb3e9..e9a60e1 100644 --- a/README.md +++ b/README.md @@ -288,7 +288,7 @@ For instance, to get more information about the `run` command: ```bash $ bee help run -usage: bee run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] +usage: bee run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] [-runmode=BEEGO_RUNMODE] start the appname throw exec.Command From 07ca4481b0e7b4a0633f573b52c86bedef4eed2c Mon Sep 17 00:00:00 2001 From: tnextday Date: Mon, 22 Aug 2016 16:11:06 +0800 Subject: [PATCH 12/14] add todo --- g_docs.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/g_docs.go b/g_docs.go index 1be9fba..f6cf29f 100644 --- a/g_docs.go +++ b/g_docs.go @@ -615,6 +615,7 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp ColorLog("Unknown type without TypeSec: %v\n", d) os.Exit(1) } + // TODO support other types, such as `ArrayType`, `MapType`, `InterfaceType` etc... st, ok := ts.Type.(*ast.StructType) if !ok { continue @@ -704,7 +705,8 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp } } if m.Title == "" { - ColorLog("[ERRO]can't find the object: %s\n", str) + ColorLog("[WARN]can't find the object: %s\n", str) + // TODO remove when all type have been supported //os.Exit(1) } if len(rootapi.Definitions) == 0 { From 98f4ff83c13bc871e618309f4d07a428474612f9 Mon Sep 17 00:00:00 2001 From: Faissal Elamraoui Date: Mon, 22 Aug 2016 18:29:11 +0200 Subject: [PATCH 13/14] docs: Updated README.md The README.md is updated to include the latest changes in bee and Beego. New submission guidelines are added to organize contributions to the project. --- README.md | 517 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 301 insertions(+), 216 deletions(-) diff --git a/README.md b/README.md index e9a60e1..16f6039 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,17 @@ bee === -[![Build Status](https://drone.io/github.com/beego/bee/status.png)](https://drone.io/github.com/beego/bee/latest) +Bee is a command-line tool facilitating development of Beego-based application. -Bee is a command line tool facilitating development with beego framework. +[![Build Status](https://drone.io/github.com/beego/bee/status.png)](https://drone.io/github.com/beego/bee/latest) ## Requirements - Go version >= 1.3. - ## Installation -Begin by installing `bee` using `go get` command. +To install `bee` use the `go get` command: ```bash go get github.com/beego/bee @@ -32,242 +31,225 @@ go get -u github.com/beego/bee ## Basic commands -Bee provides a variety of commands which can be helpful at various stage of development. The top level commands include: -```base - new create an application base on beego framework - run run the app which can hot compile - pack compress an beego project - api create an api application base on beego framework - bale packs non-Go files to Go source files - version show the bee & beego version - generate source code generator - migrate run database migrations - hprose create an rpc application use hprose base on beego framework +Bee provides a variety of commands which can be helpful at various stages of development. The top level commands include: ``` -## bee version + new Create a Beego application + run Run the app and start a Web server for development + pack Compress a beego project into a single file + api Create an API beego application + hprose Create an rpc application use hprose base on beego framework + bale Packs non-Go files to Go source files + version Prints the current Bee version + generate Source code generator + migrate Run database migrations + fix Fix the Beego application to make it compatible with Beego 1.6 +``` +### bee version -The first command is the easiest: displaying which version of `bee`, `beego` and `go` is installed on your machine: +To display the current version of `bee`, `beego` and `go` installed on your machine: ```bash $ bee version -bee :1.2.2 -beego :1.4.0 -Go :go version go1.2.1 linux/amd64 +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 + +├── Beego : 1.7.0 +├── GoVersion : go1.6.2 +├── GOOS : windows +├── GOARCH : amd64 +├── NumCPU : 4 +├── GOPATH : C:\Users\beeuser\go +├── GOROOT : C:\go +├── Compiler : gc +└── Date : Monday, 22 Aug 2016 ``` -## bee new +### bee new -Creating a new beego web application is no big deal, too. +To create a new Beego web application: ```bash -$ bee new myapp -[INFO] Creating application... -/home/zheng/gopath/src/myapp/ -/home/zheng/gopath/src/myapp/conf/ -/home/zheng/gopath/src/myapp/controllers/ -/home/zheng/gopath/src/myapp/models/ -/home/zheng/gopath/src/myapp/routers/ -/home/zheng/gopath/src/myapp/tests/ -/home/zheng/gopath/src/myapp/static/ -/home/zheng/gopath/src/myapp/static/js/ -/home/zheng/gopath/src/myapp/static/css/ -/home/zheng/gopath/src/myapp/static/img/ -/home/zheng/gopath/src/myapp/views/ -/home/zheng/gopath/src/myapp/conf/app.conf -/home/zheng/gopath/src/myapp/controllers/default.go -/home/zheng/gopath/src/myapp/views/index.tpl -/home/zheng/gopath/src/myapp/routers/router.go -/home/zheng/gopath/src/myapp/tests/default_test.go -/home/zheng/gopath/src/myapp/main.go -2014/08/29 15:45:47 [SUCC] New application successfully created! +$ bee new my-web-app +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 +2016/08/22 14:53:45 [INFO] Creating application... + create C:\Users\beeuser\go\src\github.com\user\my-web-app\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\conf\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\controllers\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\models\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\routers\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\tests\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\static\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\static\js\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\static\css\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\static\img\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\views\ + create C:\Users\beeuser\go\src\github.com\user\my-web-app\conf\app.conf + create C:\Users\beeuser\go\src\github.com\user\my-web-app\controllers\default.go + create C:\Users\beeuser\go\src\github.com\user\my-web-app\views\index.tpl + create C:\Users\beeuser\go\src\github.com\user\my-web-app\routers\router.go + create C:\Users\beeuser\go\src\github.com\user\my-web-app\tests\default_test.go + create C:\Users\beeuser\go\src\github.com\user\my-web-app\main.go +2016/08/22 14:53:45 [SUCC] New application successfully created! ``` -## bee run +For more information on the usage, run `bee help new`. -To run the application we just created, navigate to the application folder and execute `bee run`. +### bee run + +To run the application we just created, you can navigate to the application folder and execute: ```bash -$ cd myapp -$ bee run +$ cd my-web-app && bee run ``` -## bee pack +Or from anywhere in your machine: + +``` +$ bee run github.com/user/my-web-app +``` + +For more information on the usage, run `bee help run`. + +### bee pack + +To compress a Beego application into a single deployable file: ```bash -usage: bee pack - -compress an beego project - --p app path. default is current path --b build specify platform app. default true --ba additional args of go build --be=[] additional ENV Variables of go build. eg: GOARCH=arm --o compressed file output dir. default use current path --f="" format. [ tar.gz / zip ]. default tar.gz --exp="" relpath exclude prefix. default: . --exs="" relpath exclude suffix. default: .go:.DS_Store:.tmp - all path use : as separator --exr=[] file/directory name exclude by Regexp. default: ^. --fs=false follow symlink. default false --ss=false skip symlink. default false - default embed symlink into compressed file --v=false verbose +$ bee pack +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 +2016/08/22 15:11:01 Packaging application: C:\Users\beeuser\go\src\github.com\user\my-web-app +2016/08/22 15:11:01 Building application... +2016/08/22 15:11:01 Env: GOOS=windows GOARCH=amd64 +2016/08/22 15:11:08 Build successful +2016/08/22 15:11:08 Excluding relpath prefix: . +2016/08/22 15:11:08 Excluding relpath suffix: .go:.DS_Store:.tmp +2016/08/22 15:11:10 Writing to output: `C:\Users\beeuser\go\src\github.com\user\my-web-app\my-web-app.tar.gz` ``` -## bee api +For more information on the usage, run `bee help pack`. + +### bee api + +To create a Beego API application: ```bash -usage: bee api [appname] - -create an api application base on beego framework - -bee api [appname] [-tables=""] [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] - -tables: a list of table names separated by ',', default is empty, indicating all tables - -driver: [mysql | postgres | sqlite], the default is mysql - -conn: the connection string used by the driver, the default is '' - e.g. for mysql: root:@tcp(127.0.0.1:3306)/test - e.g. for postgres: postgres://postgres:postgres@127.0.0.1:5432/postgres - -if conn is empty will create a example api application. otherwise generate api application based on an existing database. - -In the current path, will create a folder named [appname] - -In the appname folder has the follow struct: - - ├── conf - │ └── app.conf - ├── controllers - │ └── object.go - │ └── user.go - ├── routers - │ └── router.go - ├── tests - │ └── default_test.go - ├── main.go - └── models - └── object.go - └── user.go +$ bee api my-api +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 +2016/08/22 15:14:10 [INFO] Creating API... + create C:\Users\beeuser\go\src\github.com\user\my-api + create C:\Users\beeuser\go\src\github.com\user\my-api\conf + create C:\Users\beeuser\go\src\github.com\user\my-api\controllers + create C:\Users\beeuser\go\src\github.com\user\my-api\tests + create C:\Users\beeuser\go\src\github.com\user\my-api\conf\app.conf + create C:\Users\beeuser\go\src\github.com\user\my-api\models + create C:\Users\beeuser\go\src\github.com\user\my-api\routers\ + create C:\Users\beeuser\go\src\github.com\user\my-api\controllers\object.go + create C:\Users\beeuser\go\src\github.com\user\my-api\controllers\user.go + create C:\Users\beeuser\go\src\github.com\user\my-api\tests\default_test.go + create C:\Users\beeuser\go\src\github.com\user\my-api\routers\router.go + create C:\Users\beeuser\go\src\github.com\user\my-api\models\object.go + create C:\Users\beeuser\go\src\github.com\user\my-api\models\user.go + create C:\Users\beeuser\go\src\github.com\user\my-api\main.go +2016/08/22 15:14:10 [SUCC] New API successfully created! ``` -## bee hprose +For more information on the usage, run `bee help api`. + +### bee hprose + +To create an Hprose RPC application based on Beego: ```bash -usage: bee hprose [appname] - -create an rpc application use hprose base on beego framework - -bee hprose [appname] [-tables=""] [-driver=mysql] [-conn=root:@tcp(127.0.0.1:3306)/test] - -tables: a list of table names separated by ',', default is empty, indicating all tables - -driver: [mysql | postgres | sqlite], the default is mysql - -conn: the connection string used by the driver, the default is '' - e.g. for mysql: root:@tcp(127.0.0.1:3306)/test - e.g. for postgres: postgres://postgres:postgres@127.0.0.1:5432/postgres - -if conn is empty will create a example rpc application. otherwise generate rpc application use hprose based on an existing database. - -In the current path, will create a folder named [appname] - -In the appname folder has the follow struct: - - ├── conf - │ └── app.conf - ├── main.go - └── models - └── object.go - └── user.go - +$ bee hprose my-rpc-app +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 +2016/08/22 16:09:13 [INFO] Creating Hprose application... + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app\conf + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app\conf\app.conf + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app\models + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app\models\object.go + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app\models\user.go + create C:\Users\beeuser\go\src\github.com\user\my-rpc-app\main.go +2016/08/22 16:09:13 [SUCC] New Hprose application successfully created! ``` -## bee bale +For more information on the usage, run `bee help hprose`. + +### bee bale + +To pack all the static files into Go source files: ```bash -usage: bee bale - -bale packs non-Go files to Go source files and - -auto-generate unpack function to main package then run it - -during the runtime. - -This is mainly used for zealots who are requiring 100% Go code. +$ bee bale +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 +2016/08/22 16:37:24 [INFO] Detected bee.json +2016/08/22 16:37:24 [INFO] Packaging directory(static/js) +2016/08/22 16:37:24 [INFO] Packaging directory(static/css) +2016/08/22 16:37:24 [SUCC] Baled resources successfully! ``` -## bee migrate +For more information on the usage, run `bee help bale`. + +### bee migrate + +For database migrations, use `bee migrate`. + +For more information on the usage, run `bee help migrate`. + +### bee generate + +Bee also comes with a source code generator which speeds up the development. + +For example, to generate a new controller named `hello`: ```bash -usage: bee migrate [Command] - -bee migrate [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] - run all outstanding migrations - -driver: [mysql | postgres | sqlite], the default is mysql - -conn: the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/test - -bee migrate rollback [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] - rollback the last migration operation - -driver: [mysql | postgres | sqlite], the default is mysql - -conn: the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/test - -bee migrate reset [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] - rollback all migrations - -driver: [mysql | postgres| sqlite], the default is mysql - -conn: the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/test - -bee migrate refresh [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] - rollback all migrations and run them all again - -driver: [mysql | postgresql | sqlite], the default is mysql - -conn: the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/test - -``` - -## bee generate - -Bee also comes with a souce code generator which speeds up the development. - -```bash -usage: bee generate [Command] - -bee generate scaffold [scaffoldname] [-fields=""] [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] - The generate scaffold command will do a number of things for you. - -fields: a list of table fields. Format: field:type, ... - -driver: [mysql | postgres | sqlite], the default is mysql - -conn: the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/test - example: bee generate scaffold post -fields="title:string,body:text" - -bee generate model [modelname] [-fields=""] - generate RESTFul model based on fields - -fields: a list of table fields. Format: field:type, ... - -bee generate controller [controllerfile] - generate RESTFul controllers - -bee generate view [viewpath] - generate CRUD view in viewpath - -bee generate migration [migrationfile] [-fields=""] - generate migration file for making database schema update - -fields: a list of table fields. Format: field:type, ... - -bee generate docs - generate swagger doc file - -bee generate test [routerfile] - generate testcase - -bee generate appcode [-tables=""] [-driver="mysql"] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-level=3] - generate appcode based on an existing database - -tables: a list of table names separated by ',', default is empty, indicating all tables - -driver: [mysql | postgres | sqlite], the default is mysql - -conn: the connection string used by the driver. - default for mysql: root:@tcp(127.0.0.1:3306)/test - default for postgres: postgres://postgres:postgres@127.0.0.1:5432/postgres - -level: [1 | 2 | 3], 1 = models; 2 = models,controllers; 3 = models,controllers,router - +$ bee generate controller hello +______ +| ___ \ +| |_/ / ___ ___ +| ___ \ / _ \ / _ \ +| |_/ /| __/| __/ +\____/ \___| \___| v1.5.0 +2016/08/22 16:55:30 [INFO] Using 'Hello' as controller name +2016/08/22 16:55:30 [INFO] Using 'controllers' as package name + create C:\Users\beeuser\go\src\github.com\user\my-web-app/controllers/hello.go +2016/08/22 16:55:30 [SUCC] Controller successfully generated! ``` +For more information on the usage, run `bee help generate`. ## Shortcuts -Because you'll likely type these generator commands over and over, it makes sense to create aliases. +Because you'll likely type these generator commands over and over, it makes sense to create aliases: ```bash # Generator Stuff @@ -278,32 +260,135 @@ alias g:v="bee generate view" alias g:mi="bee generate migration" ``` -These can be stored in, for example, your `~/.bash_profile` or `~/.bashrc` files. +These can be stored , for example, in your `~/.bash_profile` or `~/.bashrc` files. ## Help -If you happend to forget the usage of a command, you can always find the usage information by `bee help `. +To print more information on the usage of a particular command, use `bee help `. For instance, to get more information about the `run` command: ```bash $ bee help run -usage: bee run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] [-runmode=BEEGO_RUNMODE] +usage: bee run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] [-vendor=true] [-e=folderToExclude] [-tags=goBuildTags] -start the appname throw exec.Command +Run command will supervise the file system of the beego project using inotify, +it will recompile and restart the app after any modifications. +``` -then start a inotify watch for current dir - -when the file has changed bee will auto go build and restart the app +## Contributing +Bug reports, feature requests and pull requests are always welcome. - file changed - | - check if it's go file - | - yes no - | | - go build do nothing - | - restart app +We work on two branches: `master` for stable, released code and `develop`, a development branch. +It might be important to distinguish them when you are reading the commit history searching for a feature or a bugfix, +or when you are unsure of where to base your work from when contributing. + +### Found a bug? + +Please [submit an issue][new-issue] on GitHub and we will follow up. +Even better, we would appreciate a [Pull Request][new-pr] with a fix for it! + +- If the bug was found in a release, it is best to base your work on `master` and submit your PR against it. +- If the bug was found on `develop` (the development branch), base your work on `develop` and submit your PR against it. + +Please follow the [Pull Request Guidelines][new-pr]. + +### Want a feature? + +Feel free to request a feature by [submitting an issue][new-issue] on GitHub and open the discussion. + +If you'd like to implement a new feature, please consider opening an issue first to talk about it. +It may be that somebody is already working on it, or that there are particular issues that you should be aware of +before implementing the change. If you are about to open a Pull Request, please make sure to follow the [submissions guidelines][new-pr]. + +## Submission Guidelines + +### Submitting an issue + +Before you submit an issue, search the archive, maybe you will find that a similar one already exists. + +If you are submitting an issue for a bug, please include the following: + +- An overview of the issue +- Your use case (why is this a bug for you?) +- The version of `bee` you are running (include the output of `bee version`) +- Steps to reproduce the issue +- Eventually, logs from your application. +- Ideally, a suggested fix + +The more information you give us, the more able to help we will be! + +### Submitting a Pull Request + +- First of all, make sure to base your work on the `develop` branch (the development branch): ``` + # a bugfix branch for develop would be prefixed by fix/ + # a bugfix branch for master would be prefixed by hotfix/ + $ git checkout -b feature/my-feature develop +``` + +- Please create commits containing **related changes**. For example, two different bugfixes should produce two separate commits. +A feature should be made of commits splitted by **logical chunks** (no half-done changes). Use your best judgement as to +how many commits your changes require. + +- Write insightful and descriptive commit messages. It lets us and future contributors quickly understand your changes +without having to read your changes. Please provide a summary in the first line (50-72 characters) and eventually, +go to greater lengths in your message's body. A good example can be found in [Angular commit message format](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format). + +- Please **include the appropriate test cases** for your patch. + +- Make sure all tests pass before submitting your changes. + +- Rebase your commits. It may be that new commits have been introduced on `develop`. +Rebasing will update your branch with the most recent code and make your changes easier to review: + + ``` + $ git fetch + $ git rebase origin/develop + ``` + +- Push your changes: + + ``` + $ git push origin -u feature/my-feature + ``` + +- Open a pull request against the `develop` branch. + +- If we suggest changes: + - Please make the required updates (after discussion if any) + - Only create new commits if it makes sense. Generally, you will want to amend your latest commit or rebase your branch after the new changes: + + ``` + $ git rebase -i develop + # choose which commits to edit and perform the updates + ``` + + - Re-run the tests + - Force push to your branch: + + ``` + $ git push origin feature/my-feature -f + ``` + +[new-issue]: #submitting-an-issue +[new-pr]: #submitting-a-pull-request + +## Licence + +```text +Copyright 2016 bee authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` \ No newline at end of file From f813e990c0e5daa82c646c0a74e0a679928963a7 Mon Sep 17 00:00:00 2001 From: astaxie Date: Wed, 24 Aug 2016 10:54:54 +0800 Subject: [PATCH 14/14] hotfix: schema init --- g_docs.go | 1 + 1 file changed, 1 insertion(+) diff --git a/g_docs.go b/g_docs.go index 76d11f7..6c1e870 100644 --- a/g_docs.go +++ b/g_docs.go @@ -406,6 +406,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat modelsList[pkgpath+controllerName][st[2]] = mod appendModels(cmpath, pkgpath, controllerName, realTypes) } else if st[1] == "{array}" { + rs.Schema = &swagger.Schema{} rs.Schema.Type = "array" if sType, ok := basicTypes[st[2]]; ok { typeFormat := strings.Split(sType, ":")