diff --git a/apiapp.go b/apiapp.go index ee1f1d0..a30c739 100644 --- a/apiapp.go +++ b/apiapp.go @@ -548,6 +548,8 @@ func init() { func createapi(cmd *Command, args []string) int { ShowShortVersionBanner() + w := NewColorWriter(os.Stdout) + if len(args) < 1 { ColorLog("[ERRO] Argument [appname] is missing\n") os.Exit(2) @@ -571,21 +573,21 @@ func createapi(cmd *Command, args []string) int { ColorLog("[INFO] Creating API...\n") os.MkdirAll(apppath, 0755) - fmt.Println("\tcreate\t", apppath) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath, "\x1b[0m") os.Mkdir(path.Join(apppath, "conf"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "conf")) + 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.Println("\tcreate\t", path.Join(apppath, "controllers")) + 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.Println("\tcreate\t", path.Join(apppath, "docs")) + 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.Println("\tcreate\t", path.Join(apppath, "tests")) - fmt.Println("\tcreate\t", path.Join(apppath, "conf", "app.conf")) + 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") WriteToFile(path.Join(apppath, "conf", "app.conf"), strings.Replace(apiconf, "{{.Appname}}", path.Base(args[0]), -1)) if conn != "" { - fmt.Println("\tcreate\t", path.Join(apppath, "main.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m") maingoContent := strings.Replace(apiMainconngo, "{{.Appname}}", packpath, -1) maingoContent = strings.Replace(maingoContent, "{{.DriverName}}", string(driver), -1) if driver == "mysql" { @@ -607,36 +609,36 @@ func createapi(cmd *Command, args []string) int { generateAppcode(string(driver), string(conn), "3", string(tables), path.Join(apppath, args[0])) } else { os.Mkdir(path.Join(apppath, "models"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "models")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models"), "\x1b[0m") os.Mkdir(path.Join(apppath, "routers"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "routers") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "routers")+string(path.Separator), "\x1b[0m") - fmt.Println("\tcreate\t", path.Join(apppath, "controllers", "object.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "controllers", "object.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "controllers", "object.go"), strings.Replace(apiControllers, "{{.Appname}}", packpath, -1)) - fmt.Println("\tcreate\t", path.Join(apppath, "controllers", "user.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "controllers", "user.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "controllers", "user.go"), strings.Replace(apiControllers2, "{{.Appname}}", packpath, -1)) - fmt.Println("\tcreate\t", path.Join(apppath, "tests", "default_test.go")) + 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(apiTests, "{{.Appname}}", packpath, -1)) - fmt.Println("\tcreate\t", path.Join(apppath, "routers", "router.go")) + 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(apirouter, "{{.Appname}}", packpath, -1)) - fmt.Println("\tcreate\t", path.Join(apppath, "models", "object.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models", "object.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "models", "object.go"), apiModels) - fmt.Println("\tcreate\t", path.Join(apppath, "models", "user.go")) + 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.Println("\tcreate\t", path.Join(apppath, "docs", "doc.go")) + 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.Println("\tcreate\t", path.Join(apppath, "main.go")) + 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)) } diff --git a/g.go b/g.go index 3f36c07..61716f8 100644 --- a/g.go +++ b/g.go @@ -35,7 +35,7 @@ bee generate model [modelname] [-fields=""] -fields: a list of table fields. Format: field:type, ... bee generate controller [controllerfile] - generate RESTFul controllers + generate RESTful controllers bee generate view [viewpath] generate CRUD view in viewpath @@ -43,7 +43,7 @@ bee generate view [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 diff --git a/g_appcode.go b/g_appcode.go index 9fea762..522af6a 100644 --- a/g_appcode.go +++ b/g_appcode.go @@ -17,15 +17,14 @@ package main import ( "database/sql" "fmt" + _ "github.com/go-sql-driver/mysql" + _ "github.com/lib/pq" "os" "os/exec" "path" "path/filepath" "regexp" "strings" - - _ "github.com/go-sql-driver/mysql" - _ "github.com/lib/pq" ) const ( @@ -499,7 +498,7 @@ func (mysqlDB *MysqlDB) GetColumns(db *sql.DB, table *Table, blackList map[strin } } -// getGoDataType maps an SQL data type to Golang data type +// GetGoDataType maps an SQL data type to Golang data type func (*MysqlDB) GetGoDataType(sqlType string) (goType string) { var typeMapping = map[string]string{} typeMapping = typeMappingMysql @@ -688,6 +687,8 @@ func (postgresDB *PostgresDB) GetColumns(db *sql.DB, table *Table, blackList map table.Columns = append(table.Columns, col) } } + +// GetGoDataType returns the Go type from the mapped Postgres type func (*PostgresDB) GetGoDataType(sqlType string) (goType string) { if v, ok := typeMappingPostgres[sqlType]; ok { return v @@ -730,6 +731,8 @@ func writeSourceFiles(pkgPath string, tables []*Table, mode byte, paths *MvcPath // writeModelFiles generates model files func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bool) { + w := NewColorWriter(os.Stdout) + for _, tb := range tables { // if selectedTables map is not nil and this table is not selected, ignore it if selectedTables != nil { @@ -742,7 +745,7 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo var f *os.File var err error if isExist(fpath) { - ColorLog("[WARN] %v is exist, do you want to overwrite it? Yes or No?\n", fpath) + ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath) if askForConfirmation() { f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666) if err != nil { @@ -750,7 +753,7 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo continue } } else { - ColorLog("[WARN] skip create file\n") + ColorLog("[WARN] Skipped create file '%s'\n", fpath) continue } } else { @@ -782,14 +785,16 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo ColorLog("[ERRO] Could not write model file to %s\n", fpath) os.Exit(2) } - f.Close() - ColorLog("[INFO] model => %s\n", fpath) + CloseFile(f) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") formatSourceCode(fpath) } } // writeControllerFiles generates controller files func writeControllerFiles(tables []*Table, cPath string, selectedTables map[string]bool, pkgPath string) { + w := NewColorWriter(os.Stdout) + for _, tb := range tables { // if selectedTables map is not nil and this table is not selected, ignore it if selectedTables != nil { @@ -805,7 +810,7 @@ func writeControllerFiles(tables []*Table, cPath string, selectedTables map[stri var f *os.File var err error if isExist(fpath) { - ColorLog("[WARN] %v is exist, do you want to overwrite it? Yes or No?\n", fpath) + ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath) if askForConfirmation() { f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666) if err != nil { @@ -813,7 +818,7 @@ func writeControllerFiles(tables []*Table, cPath string, selectedTables map[stri continue } } else { - ColorLog("[WARN] skip create file\n") + ColorLog("[WARN] Skipped create file '%s'\n", fpath) continue } } else { @@ -829,14 +834,16 @@ func writeControllerFiles(tables []*Table, cPath string, selectedTables map[stri ColorLog("[ERRO] Could not write controller file to %s\n", fpath) os.Exit(2) } - f.Close() - ColorLog("[INFO] controller => %s\n", fpath) + CloseFile(f) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") formatSourceCode(fpath) } } // writeRouterFile generates router file func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bool, pkgPath string) { + w := NewColorWriter(os.Stdout) + var nameSpaces []string for _, tb := range tables { // if selectedTables map is not nil and this table is not selected, ignore it @@ -848,7 +855,7 @@ func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bo if tb.Pk == "" { continue } - // add name spaces + // add namespaces nameSpace := strings.Replace(NamespaceTPL, "{{nameSpace}}", tb.Name, -1) nameSpace = strings.Replace(nameSpace, "{{ctrlName}}", camelCase(tb.Name), -1) nameSpaces = append(nameSpaces, nameSpace) @@ -860,7 +867,7 @@ func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bo var f *os.File var err error if isExist(fpath) { - ColorLog("[WARN] %v is exist, do you want to overwrite it? Yes or No?\n", fpath) + ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath) if askForConfirmation() { f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666) if err != nil { @@ -868,7 +875,7 @@ func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bo return } } else { - ColorLog("[WARN] skip create file\n") + ColorLog("[WARN] Skipped create file '%s'\n", fpath) return } } else { @@ -879,11 +886,11 @@ func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bo } } if _, err := f.WriteString(routerStr); err != nil { - ColorLog("[ERRO] Could not write router file to %s\n", fpath) + ColorLog("[ERRO] Could not write router file to '%s'\n", fpath) os.Exit(2) } - f.Close() - ColorLog("[INFO] router => %s\n", fpath) + CloseFile(f) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") formatSourceCode(fpath) } @@ -966,7 +973,7 @@ func getPackagePath(curpath string) (packpath string) { gopath := os.Getenv("GOPATH") Debugf("gopath:%s", gopath) if gopath == "" { - ColorLog("[ERRO] you should set GOPATH in the env") + ColorLog("[ERRO] You should set GOPATH in the env") os.Exit(2) } diff --git a/g_controllers.go b/g_controllers.go index a4815c0..0345247 100644 --- a/g_controllers.go +++ b/g_controllers.go @@ -15,53 +15,62 @@ package main import ( + "fmt" "os" "path" "strings" - "fmt" ) // article // cms/article // -func generateController(cname, crupath string) { +func generateController(cname, currpath string) { + w := NewColorWriter(os.Stdout) + p, f := path.Split(cname) controllerName := strings.Title(f) packageName := "controllers" + if p != "" { i := strings.LastIndex(p[:len(p)-1], "/") packageName = p[i+1 : len(p)-1] } + ColorLog("[INFO] Using '%s' as controller name\n", controllerName) ColorLog("[INFO] Using '%s' as package name\n", packageName) - fp := path.Join(crupath, "controllers", p) + + fp := path.Join(currpath, "controllers", p) if _, err := os.Stat(fp); os.IsNotExist(err) { - // create controller directory + // Create the controller's directory if err := os.MkdirAll(fp, 0777); err != nil { ColorLog("[ERRO] Could not create controllers directory: %s\n", err) os.Exit(2) } } + fpath := path.Join(fp, strings.ToLower(controllerName)+".go") if f, err := os.OpenFile(fpath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() - modelPath := path.Join(crupath, "models", strings.ToLower(controllerName)+".go") + defer CloseFile(f) + + modelPath := path.Join(currpath, "models", strings.ToLower(controllerName)+".go") + var content string if _, err := os.Stat(modelPath); err == nil { ColorLog("[INFO] Using matching model '%s'\n", controllerName) content = strings.Replace(controllerModelTpl, "{{packageName}}", packageName, -1) - pkgPath := getPackagePath(crupath) + pkgPath := getPackagePath(currpath) content = strings.Replace(content, "{{pkgPath}}", pkgPath, -1) } else { content = strings.Replace(controllerTpl, "{{packageName}}", packageName, -1) } + content = strings.Replace(content, "{{controllerName}}", controllerName, -1) f.WriteString(content) - // gofmt generated source code + + // Run 'gofmt' on the generated source code formatSourceCode(fpath) - fmt.Println("\tcreate\t", fpath) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") } else { - // error creating file ColorLog("[ERRO] Could not create controller file: %s\n", err) os.Exit(2) } diff --git a/g_hproseappcode.go b/g_hproseappcode.go index 7dda6ce..89ae1b2 100644 --- a/g_hproseappcode.go +++ b/g_hproseappcode.go @@ -19,12 +19,12 @@ package main import ( "database/sql" + "fmt" + _ "github.com/go-sql-driver/mysql" + _ "github.com/lib/pq" "os" "path" "strings" - - _ "github.com/go-sql-driver/mysql" - _ "github.com/lib/pq" ) func generateHproseAppcode(driver, connStr, level, tables, currpath string) { @@ -98,6 +98,8 @@ func writeHproseSourceFiles(pkgPath string, tables []*Table, mode byte, paths *M // writeHproseModelFiles generates model files func writeHproseModelFiles(tables []*Table, mPath string, selectedTables map[string]bool) { + w := NewColorWriter(os.Stdout) + for _, tb := range tables { // if selectedTables map is not nil and this table is not selected, ignore it if selectedTables != nil { @@ -110,7 +112,7 @@ func writeHproseModelFiles(tables []*Table, mPath string, selectedTables map[str var f *os.File var err error if isExist(fpath) { - ColorLog("[WARN] %v is exist, do you want to overwrite it? Yes or No?\n", fpath) + ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath) if askForConfirmation() { f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666) if err != nil { @@ -118,7 +120,7 @@ func writeHproseModelFiles(tables []*Table, mPath string, selectedTables map[str continue } } else { - ColorLog("[WARN] skip create file\n") + ColorLog("[WARN] Skipped create file '%s'\n", fpath) continue } } else { @@ -147,11 +149,11 @@ func writeHproseModelFiles(tables []*Table, mPath string, selectedTables map[str fileStr = strings.Replace(fileStr, "{{timePkg}}", timePkg, -1) fileStr = strings.Replace(fileStr, "{{importTimePkg}}", importTimePkg, -1) if _, err := f.WriteString(fileStr); err != nil { - ColorLog("[ERRO] Could not write model file to %s\n", fpath) + ColorLog("[ERRO] Could not write model file to '%s'\n", fpath) os.Exit(2) } - f.Close() - ColorLog("[INFO] model => %s\n", fpath) + CloseFile(f) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") formatSourceCode(fpath) } } diff --git a/g_migration.go b/g_migration.go index d26211c..4135ebe 100644 --- a/g_migration.go +++ b/g_migration.go @@ -23,7 +23,7 @@ import ( ) const ( - MPath = "migrations" + MPath = "migrations" MDateFormat = "20060102_150405" ) @@ -31,6 +31,8 @@ const ( // 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) if _, err := os.Stat(migrationFilePath); os.IsNotExist(err) { // create migrations directory @@ -43,17 +45,16 @@ func generateMigration(mname, upsql, downsql, curpath string) { today := time.Now().Format(MDateFormat) fpath := path.Join(migrationFilePath, fmt.Sprintf("%s_%s.go", today, mname)) if f, err := os.OpenFile(fpath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() + defer CloseFile(f) content := strings.Replace(MigrationTPL, "{{StructName}}", camelCase(mname)+"_"+today, -1) content = strings.Replace(content, "{{CurrTime}}", today, -1) content = strings.Replace(content, "{{UpSQL}}", upsql, -1) content = strings.Replace(content, "{{DownSQL}}", downsql, -1) f.WriteString(content) - // gofmt generated source code + // Run 'gofmt' on the generated source code formatSourceCode(fpath) - fmt.Println("\tcreate\t", fpath) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") } else { - // error creating file ColorLog("[ERRO] Could not create migration file: %s\n", err) os.Exit(2) } diff --git a/g_model.go b/g_model.go index 5c5ce37..9987d47 100644 --- a/g_model.go +++ b/g_model.go @@ -1,3 +1,17 @@ +// Copyright 2013 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. + package main import ( @@ -8,7 +22,9 @@ import ( "strings" ) -func generateModel(mname, fields, crupath string) { +func generateModel(mname, fields, currpath string) { + w := NewColorWriter(os.Stdout) + p, f := path.Split(mname) modelName := strings.Title(f) packageName := "models" @@ -16,24 +32,28 @@ func generateModel(mname, fields, crupath string) { i := strings.LastIndex(p[:len(p)-1], "/") packageName = p[i+1 : len(p)-1] } + modelStruct, hastime, err := getStruct(modelName, fields) if err != nil { - ColorLog("[ERRO] Could not genrate models struct: %s\n", err) + ColorLog("[ERRO] Could not generate the model struct: %s\n", err) os.Exit(2) } + ColorLog("[INFO] Using '%s' as model name\n", modelName) ColorLog("[INFO] Using '%s' as package name\n", packageName) - fp := path.Join(crupath, "models", p) + + fp := path.Join(currpath, "models", p) if _, err := os.Stat(fp); os.IsNotExist(err) { - // create controller directory + // Create the model's directory if err := os.MkdirAll(fp, 0777); err != nil { - ColorLog("[ERRO] Could not create models directory: %s\n", err) + ColorLog("[ERRO] Could not create the model directory: %s\n", err) os.Exit(2) } } + fpath := path.Join(fp, strings.ToLower(modelName)+".go") if f, err := os.OpenFile(fpath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() + defer CloseFile(f) content := strings.Replace(modelTpl, "{{packageName}}", packageName, -1) content = strings.Replace(content, "{{modelName}}", modelName, -1) content = strings.Replace(content, "{{modelStruct}}", modelStruct, -1) @@ -43,11 +63,10 @@ func generateModel(mname, fields, crupath string) { content = strings.Replace(content, "{{timePkg}}", "", -1) } f.WriteString(content) - // gofmt generated source code + // Run 'gofmt' on the generated source code formatSourceCode(fpath) - fmt.Println("\tcreate\t", fpath) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m") } else { - // error creating file ColorLog("[ERRO] Could not create model file: %s\n", err) os.Exit(2) } @@ -55,23 +74,27 @@ func generateModel(mname, fields, crupath string) { func getStruct(structname, fields string) (string, bool, error) { if fields == "" { - return "", false, errors.New("fields can't empty") + return "", false, errors.New("fields cannot be empty") } + hastime := false structStr := "type " + structname + " struct{\n" fds := strings.Split(fields, ",") for i, v := range fds { kv := strings.SplitN(v, ":", 2) if len(kv) != 2 { - return "", false, errors.New("the filds format is wrong. should key:type,key:type " + v) + return "", false, errors.New("the fields format is wrong. Should be key:type,key:type " + v) } + typ, tag, hastimeinner := getType(kv[1]) if typ == "" { - return "", false, errors.New("the filds format is wrong. should key:type,key:type " + v) + return "", false, errors.New("the fields format is wrong. Should be key:type,key:type " + v) } + if i == 0 && strings.ToLower(kv[0]) != "id" { structStr = structStr + "Id int64 `orm:\"auto\"`\n" } + if hastimeinner { hastime = true } diff --git a/g_scaffold.go b/g_scaffold.go index ef9b13e..8222b57 100644 --- a/g_scaffold.go +++ b/g_scaffold.go @@ -5,25 +5,28 @@ import ( "strings" ) -func generateScaffold(sname, fields, crupath, driver, conn string) { - // generate model - ColorLog("[INFO] Do you want to create a %v model? [yes|no]] ", sname) +func generateScaffold(sname, fields, currpath, driver, conn string) { + ColorLog("[INFO] Do you want to create a '%v' model? [Yes|No] ", sname) + + // Generate the model if askForConfirmation() { - generateModel(sname, fields, crupath) + generateModel(sname, fields, currpath) } - // generate controller - ColorLog("[INFO] Do you want to create a %v controller? [yes|no]] ", sname) + // Generate the controller + ColorLog("[INFO] Do you want to create a '%v' controller? [Yes|No] ", sname) if askForConfirmation() { - generateController(sname, crupath) + generateController(sname, currpath) } - // generate view - ColorLog("[INFO] Do you want to create views for this %v resource? [yes|no]] ", sname) + + // Generate the views + ColorLog("[INFO] Do you want to create views for this '%v' resource? [Yes|No] ", sname) if askForConfirmation() { - generateView(sname, crupath) + generateView(sname, currpath) } - // generate migration - ColorLog("[INFO] Do you want to create a %v migration and schema for this resource? [yes|no]] ", sname) + + // Generate a migration + ColorLog("[INFO] Do you want to create a '%v' migration and schema for this resource? [Yes|No] ", sname) if askForConfirmation() { upsql := "" downsql := "" @@ -34,12 +37,13 @@ func generateScaffold(sname, fields, crupath, driver, conn string) { downsql = strings.Replace(downsql, "`", "", -1) } } - generateMigration(sname, upsql, downsql, crupath) + generateMigration(sname, upsql, downsql, currpath) } - // run migration - ColorLog("[INFO] Do you want to migrate the database? [yes|no]] ") + + // Run the migration + ColorLog("[INFO] Do you want to migrate the database? [Yes|No] ") if askForConfirmation() { - migrateUpdate(crupath, driver, conn) + migrateUpdate(currpath, driver, conn) } ColorLog("[INFO] All done! Don't forget to add beego.Router(\"/%v\" ,&controllers.%vController{}) to routers/route.go\n", sname, strings.Title(sname)) } diff --git a/g_views.go b/g_views.go index 47c252c..c078223 100644 --- a/g_views.go +++ b/g_views.go @@ -1,49 +1,74 @@ +// Copyright 2013 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. + package main import ( + "fmt" "os" "path" - "fmt" ) // recipe // admin/recipe -func generateView(vpath, crupath string) { +func generateView(viewpath, currpath string) { + w := NewColorWriter(os.Stdout) + ColorLog("[INFO] Generating view...\n") - absvpath := path.Join(crupath, "views", vpath) - os.MkdirAll(absvpath, os.ModePerm) - cfile := path.Join(absvpath, "index.tpl") + + absViewPath := path.Join(currpath, "views", viewpath) + err := os.MkdirAll(absViewPath, os.ModePerm) + if err != nil { + ColorLog("[ERRO] Could not create '%s' view: %s\n", viewpath, err) + os.Exit(2) + } + + cfile := path.Join(absViewPath, "index.tpl") if f, err := os.OpenFile(cfile, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() + defer CloseFile(f) f.WriteString(cfile) - fmt.Println("\tcreate\t", cfile) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m") } else { ColorLog("[ERRO] Could not create view file: %s\n", err) os.Exit(2) } - cfile = path.Join(absvpath, "show.tpl") + + cfile = path.Join(absViewPath, "show.tpl") if f, err := os.OpenFile(cfile, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() + defer CloseFile(f) f.WriteString(cfile) - fmt.Println("\tcreate\t", cfile) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m") } else { ColorLog("[ERRO] Could not create view file: %s\n", err) os.Exit(2) } - cfile = path.Join(absvpath, "create.tpl") + + cfile = path.Join(absViewPath, "create.tpl") if f, err := os.OpenFile(cfile, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() + defer CloseFile(f) f.WriteString(cfile) - fmt.Println("\tcreate\t", cfile) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m") } else { ColorLog("[ERRO] Could not create view file: %s\n", err) os.Exit(2) } - cfile = path.Join(absvpath, "edit.tpl") + + cfile = path.Join(absViewPath, "edit.tpl") if f, err := os.OpenFile(cfile, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil { - defer f.Close() + defer CloseFile(f) f.WriteString(cfile) - fmt.Println("\tcreate\t", cfile) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m") } else { ColorLog("[ERRO] Could not create view file: %s\n", err) os.Exit(2) diff --git a/hproseapp.go b/hproseapp.go index 8200de6..e6f7e1c 100644 --- a/hproseapp.go +++ b/hproseapp.go @@ -28,7 +28,7 @@ var cmdHproseapp = &Command{ // CustomFlags: true, UsageLine: "hprose [appname]", Short: "create an rpc application use hprose base on beego framework", - Long: ` + Long: ` 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] @@ -37,7 +37,7 @@ bee hprose [appname] [-tables=""] [-driver=mysql] [-conn=root:@tcp(127.0.0.1:330 -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] @@ -257,6 +257,8 @@ func init() { func createhprose(cmd *Command, args []string) int { ShowShortVersionBanner() + w := NewColorWriter(os.Stdout) + curpath, _ := os.Getwd() if len(args) > 1 { cmd.Flag.Parse(args[1:]) @@ -275,10 +277,10 @@ func createhprose(cmd *Command, args []string) int { ColorLog("[INFO] Creating Hprose application...\n") os.MkdirAll(apppath, 0755) - fmt.Println("\tcreate\t", apppath) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath, "\x1b[0m") os.Mkdir(path.Join(apppath, "conf"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "conf")) - fmt.Println("\tcreate\t", path.Join(apppath, "conf", "app.conf")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "conf"), "\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") WriteToFile(path.Join(apppath, "conf", "app.conf"), strings.Replace(hproseconf, "{{.Appname}}", args[0], -1)) @@ -287,7 +289,7 @@ func createhprose(cmd *Command, args []string) int { ColorLog("[INFO] Using '%s' as 'conn'\n", conn) ColorLog("[INFO] Using '%s' as 'tables'\n", tables) generateHproseAppcode(string(driver), string(conn), "1", string(tables), path.Join(curpath, args[0])) - fmt.Println("\tcreate\t", path.Join(apppath, "main.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m") maingoContent := strings.Replace(hproseMainconngo, "{{.Appname}}", packpath, -1) maingoContent = strings.Replace(maingoContent, "{{.DriverName}}", string(driver), -1) maingoContent = strings.Replace(maingoContent, "{{HproseFunctionList}}", strings.Join(hproseAddFunctions, ""), -1) @@ -306,15 +308,15 @@ func createhprose(cmd *Command, args []string) int { ) } else { os.Mkdir(path.Join(apppath, "models"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "models")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models"), "\x1b[0m") - fmt.Println("\tcreate\t", path.Join(apppath, "models", "object.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models", "object.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "models", "object.go"), apiModels) - fmt.Println("\tcreate\t", path.Join(apppath, "models", "user.go")) + 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.Println("\tcreate\t", path.Join(apppath, "main.go")) + 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(hproseMaingo, "{{.Appname}}", packpath, -1)) } diff --git a/migrate.go b/migrate.go index 0661ae1..67f00ac 100644 --- a/migrate.go +++ b/migrate.go @@ -299,7 +299,7 @@ func writeMigrationSourceFile(dir, source, driver, connStr string, latestTime in ColorLog("[ERRO] Could not write to file: %s\n", err) os.Exit(2) } - f.Close() + CloseFile(f) } } diff --git a/new.go b/new.go index 3a7e87c..c395f69 100644 --- a/new.go +++ b/new.go @@ -57,6 +57,8 @@ 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) @@ -75,7 +77,7 @@ func createApp(cmd *Command, args []string) int { if isExist(apppath) { ColorLog("[ERRO] Path (%s) already exists\n", apppath) - ColorLog("[WARN] Do you want to overwrite it? [yes|no]]") + ColorLog("[WARN] Do you want to overwrite it? [Yes|No] ") if !askForConfirmation() { os.Exit(2) } @@ -84,43 +86,43 @@ func createApp(cmd *Command, args []string) int { ColorLog("[INFO] Creating application...\n") os.MkdirAll(apppath, 0755) - fmt.Println("\tcreate\t", apppath + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "conf"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "conf") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "conf")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "controllers"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "controllers") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "controllers")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "models"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "models") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "models")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "routers"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "routers") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "routers")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "tests"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "tests") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "tests")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "static"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "static") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "static")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "static", "js"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "static", "js") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "static", "js")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "static", "css"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "static", "css") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "static", "css")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "static", "img"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "static", "img") + string(path.Separator)) - fmt.Println("\tcreate\t", path.Join(apppath, "views") + string(path.Separator)) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "static", "img")+string(path.Separator), "\x1b[0m") + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "views")+string(path.Separator), "\x1b[0m") os.Mkdir(path.Join(apppath, "views"), 0755) - fmt.Println("\tcreate\t", path.Join(apppath, "conf", "app.conf")) + 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") WriteToFile(path.Join(apppath, "conf", "app.conf"), strings.Replace(appconf, "{{.Appname}}", path.Base(args[0]), -1)) - fmt.Println("\tcreate\t", path.Join(apppath, "controllers", "default.go")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "controllers", "default.go"), "\x1b[0m") WriteToFile(path.Join(apppath, "controllers", "default.go"), controllers) - fmt.Println("\tcreate\t", path.Join(apppath, "views", "index.tpl")) + fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "views", "index.tpl"), "\x1b[0m") WriteToFile(path.Join(apppath, "views", "index.tpl"), indextpl) - fmt.Println("\tcreate\t", path.Join(apppath, "routers", "router.go")) + 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)) - fmt.Println("\tcreate\t", path.Join(apppath, "tests", "default_test.go")) + 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)) - fmt.Println("\tcreate\t", path.Join(apppath, "main.go")) + 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)) ColorLog("[SUCC] New application successfully created!\n") @@ -309,9 +311,10 @@ var indextpl = ` ` +// WriteToFile creates a file and writes content to it func WriteToFile(filename, content string) { f, err := os.Create(filename) - defer f.Close() + defer CloseFile(f) if err != nil { panic(err) } diff --git a/pack.go b/pack.go index db2978c..bdf3581 100644 --- a/pack.go +++ b/pack.go @@ -72,6 +72,7 @@ var ( buildEnvs ListOpts verbose bool format string + w io.Writer ) type ListOpts []string @@ -101,6 +102,7 @@ func init() { fs.BoolVar(&verbose, "v", false, "verbose") cmdPack.Flag = *fs cmdPack.Run = packApp + w = NewColorWriter(os.Stdout) } func exitPrint(con string) { @@ -242,7 +244,7 @@ func (wft *walkFileTree) walkLeaf(fpath string, fi os.FileInfo, err error) error if added, err := wft.wak.compress(name, fpath, fi); added { if verbose { - fmt.Printf("\t+ Compressed: %s\n", name) + fmt.Fprintf(w, "\t%s%scompressed%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", name, "\x1b[0m") } wft.allfiles[name] = true return err @@ -338,7 +340,7 @@ func (wft *tarWalk) compress(name, fpath string, fi os.FileInfo) (bool, error) { if err != nil { return false, err } - defer fr.Close() + defer CloseFile(fr) _, err = io.Copy(tw, fr) if err != nil { return false, err @@ -374,7 +376,7 @@ func (wft *zipWalk) compress(name, fpath string, fi os.FileInfo) (bool, error) { if err != nil { return false, err } - defer fr.Close() + defer CloseFile(fr) _, err = io.Copy(w, fr) if err != nil { return false, err @@ -559,7 +561,7 @@ func packApp(cmd *Command, args []string) int { } if verbose { - fmt.Println("\t+ go", strings.Join(args, " ")) + fmt.Fprintf(w, "\t%s%s+ go %s%s%s\n", "\x1b[32m", "\x1b[1m", strings.Join(args, " "), "\x1b[21m", "\x1b[0m") } execmd := exec.Command("go", args...) diff --git a/util.go b/util.go index 0f314df..43a29c5 100644 --- a/util.go +++ b/util.go @@ -258,3 +258,11 @@ func (s *strFlags) Set(value string) error { *s = append(*s, value) return nil } + +// CloseFile attempts to close the passed file +// or panics with the actual error +func CloseFile(f *os.File) { + if err := f.Close(); err != nil { + panic(err) + } +}