From 916e7015809b7cbf08e244e5cc5f5aca07abfd0a Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 19 Aug 2013 10:27:44 +0800 Subject: [PATCH 1/4] fix post data format --- apiapp.go | 506 +++++++++++++++++++++++++++--------------------------- 1 file changed, 253 insertions(+), 253 deletions(-) diff --git a/apiapp.go b/apiapp.go index d04734f..705b1a0 100644 --- a/apiapp.go +++ b/apiapp.go @@ -1,253 +1,253 @@ -package main - -import ( - "fmt" - "os" - path "path/filepath" - "strings" -) - -var cmdApiapp = &Command{ - // CustomFlags: true, - UsageLine: "api [appname]", - Short: "create an api application base on beego framework", - Long: ` -create an api application base on beego framework - -In the current path, will create a folder named [appname] - -In the appname folder has the follow struct: - - ├── conf - │   └── app.conf - ├── controllers - │   └── default.go - ├── main.go - └── models - └── object.go - -`, -} - -var apiconf = ` -appname = {{.Appname}} -httpport = 8080 -runmode = dev -autorender = false -copyrequestbody = true -` -var apiMaingo = `package main - -import ( - "github.com/astaxie/beego" - "{{.Appname}}/controllers" -) - -// Objects - -// URL HTTP Verb Functionality -// /object POST Creating Objects -// /object/ GET Retrieving Objects -// /object/ PUT Updating Objects -// /object GET Queries -// /object/ DELETE Deleting Objects - -func main() { - beego.RESTRouter("/object", &controllers.ObejctController{}) - beego.Run() -} -` -var apiModels = `package models - -import ( - "errors" - "strconv" - "time" -) - -var ( - Objects map[string]*Object -) - -type Object struct { - ObjectId string - Score int64 - PlayerName string -} - -func init() { - Objects = make(map[string]*Object) - Objects["hjkhsbnmn123"] = &Object{"hjkhsbnmn123", 100, "astaxie"} - Objects["mjjkxsxsaa23"] = &Object{"mjjkxsxsaa23", 101, "someone"} -} - -func AddOne(object Object) (ObjectId string) { - object.ObjectId = "astaxie" + strconv.FormatInt(time.Now().UnixNano(), 10) - Objects[object.ObjectId] = &object - return object.ObjectId -} - -func GetOne(ObjectId string) (object *Object, err error) { - if v, ok := Objects[ObjectId]; ok { - return v, nil - } - return nil, errors.New("ObjectId Not Exist") -} - -func GetAll() map[string]*Object { - return Objects -} - -func Update(ObjectId string, Score int64) (err error) { - if v, ok := Objects[ObjectId]; ok { - v.Score = Score - return nil - } - return errors.New("ObjectId Not Exist") -} - -func Delete(ObjectId string) { - delete(Objects, ObjectId) -} -` - -var apiControllers = `package controllers - -import ( - "encoding/json" - "github.com/astaxie/beego" - "{{.Appname}}/models" -) - -type ResponseInfo struct { -} - -type ObejctController struct { - beego.Controller -} - -func (this *ObejctController) Post() { - var ob models.Object - json.Unmarshal(this.Ctx.RequestBody, &ob) - objectid := models.AddOne(ob) - this.Data["json"] = "{\"ObjectId\":\"" + objectid + "\"}" - this.ServeJson() -} - -func (this *ObejctController) Get() { - objectId := this.Ctx.Params[":objectId"] - if objectId != "" { - ob, err := models.GetOne(objectId) - if err != nil { - this.Data["json"] = err - } else { - this.Data["json"] = ob - } - } else { - obs := models.GetAll() - this.Data["json"] = obs - } - this.ServeJson() -} - -func (this *ObejctController) Put() { - objectId := this.Ctx.Params[":objectId"] - var ob models.Object - json.Unmarshal(this.Ctx.RequestBody, &ob) - - err := models.Update(objectId, ob.Score) - if err != nil { - this.Data["json"] = err - } else { - this.Data["json"] = "update success!" - } - this.ServeJson() -} - -func (this *ObejctController) Delete() { - objectId := this.Ctx.Params[":objectId"] - models.Delete(objectId) - this.Data["json"] = "delete success!" - this.ServeJson() -} -` - -func init() { - cmdApiapp.Run = createapi -} - -func createapi(cmd *Command, args []string) { - if len(args) != 1 { - fmt.Println("error args") - os.Exit(2) - } - apppath, packpath, err := checkEnv(args[0]) - if err != nil { - fmt.Println(err) - os.Exit(2) - } - os.MkdirAll(apppath, 0755) - fmt.Println("create app folder:", apppath) - os.Mkdir(path.Join(apppath, "conf"), 0755) - fmt.Println("create conf:", path.Join(apppath, "conf")) - os.Mkdir(path.Join(apppath, "controllers"), 0755) - fmt.Println("create controllers:", path.Join(apppath, "controllers")) - os.Mkdir(path.Join(apppath, "models"), 0755) - fmt.Println("create models:", path.Join(apppath, "models")) - - fmt.Println("create conf app.conf:", path.Join(apppath, "conf", "app.conf")) - writetofile(path.Join(apppath, "conf", "app.conf"), - strings.Replace(apiconf, "{{.Appname}}", args[0], -1)) - - fmt.Println("create controllers default.go:", path.Join(apppath, "controllers", "default.go")) - writetofile(path.Join(apppath, "controllers", "default.go"), - strings.Replace(apiControllers, "{{.Appname}}", packpath, -1)) - - fmt.Println("create models object.go:", path.Join(apppath, "models", "object.go")) - writetofile(path.Join(apppath, "models", "object.go"), apiModels) - - fmt.Println("create main.go:", path.Join(apppath, "main.go")) - writetofile(path.Join(apppath, "main.go"), - strings.Replace(apiMaingo, "{{.Appname}}", packpath, -1)) -} - -func checkEnv(appname string) (apppath, packpath string, err error) { - curpath, err := os.Getwd() - if err != nil { - return - } - - gopath := os.Getenv("GOPATH") - Debugf("gopath:%s", gopath) - if gopath == "" { - err = fmt.Errorf("you should set GOPATH in the env") - return - } - - appsrcpath := "" - haspath := false - wgopath := path.SplitList(gopath) - for _, wg := range wgopath { - wg = path.Join(wg, "src") - - if path.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) { - haspath = true - appsrcpath = wg - break - } - } - - if !haspath { - err = fmt.Errorf("can't create application outside of GOPATH `%s`\n"+ - "you first should `cd $GOPATH%ssrc` then use create\n", gopath, string(path.Separator)) - return - } - apppath = path.Join(curpath, appname) - - if _, e := os.Stat(apppath); os.IsNotExist(e) == false { - err = fmt.Errorf("path `%s` exists, can not create app without remove it\n", apppath) - return - } - packpath = strings.Join(strings.Split(apppath[len(appsrcpath)+1:], string(path.Separator)), "/") - return -} +package main + +import ( + "fmt" + "os" + path "path/filepath" + "strings" +) + +var cmdApiapp = &Command{ + // CustomFlags: true, + UsageLine: "api [appname]", + Short: "create an api application base on beego framework", + Long: ` +create an api application base on beego framework + +In the current path, will create a folder named [appname] + +In the appname folder has the follow struct: + + ├── conf + │ └── app.conf + ├── controllers + │ └── default.go + ├── main.go + └── models + └── object.go + +`, +} + +var apiconf = ` +appname = {{.Appname}} +httpport = 8080 +runmode = dev +autorender = false +copyrequestbody = true +` +var apiMaingo = `package main + +import ( + "github.com/astaxie/beego" + "{{.Appname}}/controllers" +) + +// Objects + +// URL HTTP Verb Functionality +// /object POST Creating Objects +// /object/ GET Retrieving Objects +// /object/ PUT Updating Objects +// /object GET Queries +// /object/ DELETE Deleting Objects + +func main() { + beego.RESTRouter("/object", &controllers.ObejctController{}) + beego.Run() +} +` +var apiModels = `package models + +import ( + "errors" + "strconv" + "time" +) + +var ( + Objects map[string]*Object +) + +type Object struct { + ObjectId string + Score int64 + PlayerName string +} + +func init() { + Objects = make(map[string]*Object) + Objects["hjkhsbnmn123"] = &Object{"hjkhsbnmn123", 100, "astaxie"} + Objects["mjjkxsxsaa23"] = &Object{"mjjkxsxsaa23", 101, "someone"} +} + +func AddOne(object Object) (ObjectId string) { + object.ObjectId = "astaxie" + strconv.FormatInt(time.Now().UnixNano(), 10) + Objects[object.ObjectId] = &object + return object.ObjectId +} + +func GetOne(ObjectId string) (object *Object, err error) { + if v, ok := Objects[ObjectId]; ok { + return v, nil + } + return nil, errors.New("ObjectId Not Exist") +} + +func GetAll() map[string]*Object { + return Objects +} + +func Update(ObjectId string, Score int64) (err error) { + if v, ok := Objects[ObjectId]; ok { + v.Score = Score + return nil + } + return errors.New("ObjectId Not Exist") +} + +func Delete(ObjectId string) { + delete(Objects, ObjectId) +} +` + +var apiControllers = `package controllers + +import ( + "encoding/json" + "github.com/astaxie/beego" + "{{.Appname}}/models" +) + +type ResponseInfo struct { +} + +type ObejctController struct { + beego.Controller +} + +func (this *ObejctController) Post() { + var ob models.Object + json.Unmarshal(this.Ctx.RequestBody, &ob) + objectid := models.AddOne(ob) + this.Data["json"] = map[string]string{"ObjectId": objectid} + this.ServeJson() +} + +func (this *ObejctController) Get() { + objectId := this.Ctx.Params[":objectId"] + if objectId != "" { + ob, err := models.GetOne(objectId) + if err != nil { + this.Data["json"] = err + } else { + this.Data["json"] = ob + } + } else { + obs := models.GetAll() + this.Data["json"] = obs + } + this.ServeJson() +} + +func (this *ObejctController) Put() { + objectId := this.Ctx.Params[":objectId"] + var ob models.Object + json.Unmarshal(this.Ctx.RequestBody, &ob) + + err := models.Update(objectId, ob.Score) + if err != nil { + this.Data["json"] = err + } else { + this.Data["json"] = "update success!" + } + this.ServeJson() +} + +func (this *ObejctController) Delete() { + objectId := this.Ctx.Params[":objectId"] + models.Delete(objectId) + this.Data["json"] = "delete success!" + this.ServeJson() +} +` + +func init() { + cmdApiapp.Run = createapi +} + +func createapi(cmd *Command, args []string) { + if len(args) != 1 { + fmt.Println("error args") + os.Exit(2) + } + apppath, packpath, err := checkEnv(args[0]) + if err != nil { + fmt.Println(err) + os.Exit(2) + } + os.MkdirAll(apppath, 0755) + fmt.Println("create app folder:", apppath) + os.Mkdir(path.Join(apppath, "conf"), 0755) + fmt.Println("create conf:", path.Join(apppath, "conf")) + os.Mkdir(path.Join(apppath, "controllers"), 0755) + fmt.Println("create controllers:", path.Join(apppath, "controllers")) + os.Mkdir(path.Join(apppath, "models"), 0755) + fmt.Println("create models:", path.Join(apppath, "models")) + + fmt.Println("create conf app.conf:", path.Join(apppath, "conf", "app.conf")) + writetofile(path.Join(apppath, "conf", "app.conf"), + strings.Replace(apiconf, "{{.Appname}}", args[0], -1)) + + fmt.Println("create controllers default.go:", path.Join(apppath, "controllers", "default.go")) + writetofile(path.Join(apppath, "controllers", "default.go"), + strings.Replace(apiControllers, "{{.Appname}}", packpath, -1)) + + fmt.Println("create models object.go:", path.Join(apppath, "models", "object.go")) + writetofile(path.Join(apppath, "models", "object.go"), apiModels) + + fmt.Println("create main.go:", path.Join(apppath, "main.go")) + writetofile(path.Join(apppath, "main.go"), + strings.Replace(apiMaingo, "{{.Appname}}", packpath, -1)) +} + +func checkEnv(appname string) (apppath, packpath string, err error) { + curpath, err := os.Getwd() + if err != nil { + return + } + + gopath := os.Getenv("GOPATH") + Debugf("gopath:%s", gopath) + if gopath == "" { + err = fmt.Errorf("you should set GOPATH in the env") + return + } + + appsrcpath := "" + haspath := false + wgopath := path.SplitList(gopath) + for _, wg := range wgopath { + wg = path.Join(wg, "src") + + if path.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) { + haspath = true + appsrcpath = wg + break + } + } + + if !haspath { + err = fmt.Errorf("can't create application outside of GOPATH `%s`\n"+ + "you first should `cd $GOPATH%ssrc` then use create\n", gopath, string(path.Separator)) + return + } + apppath = path.Join(curpath, appname) + + if _, e := os.Stat(apppath); os.IsNotExist(e) == false { + err = fmt.Errorf("path `%s` exists, can not create app without remove it\n", apppath) + return + } + packpath = strings.Join(strings.Split(apppath[len(appsrcpath)+1:], string(path.Separator)), "/") + return +} From 9ba4bbc1bc6ee42c208ddcef09bd37faf868653f Mon Sep 17 00:00:00 2001 From: fanngyuan Date: Thu, 22 Aug 2013 11:03:31 +0800 Subject: [PATCH 2/4] add test --- apiapp.go | 2 ++ test.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 test.go diff --git a/apiapp.go b/apiapp.go index 705b1a0..18b1a91 100644 --- a/apiapp.go +++ b/apiapp.go @@ -194,6 +194,8 @@ func createapi(cmd *Command, args []string) { fmt.Println("create controllers:", path.Join(apppath, "controllers")) os.Mkdir(path.Join(apppath, "models"), 0755) fmt.Println("create models:", path.Join(apppath, "models")) + os.Mkdir(path.Join(apppath, "tests"), 0755) + fmt.Println("create tests:", path.Join(apppath, "tests")) fmt.Println("create conf app.conf:", path.Join(apppath, "conf", "app.conf")) writetofile(path.Join(apppath, "conf", "app.conf"), diff --git a/test.go b/test.go new file mode 100644 index 0000000..56446b4 --- /dev/null +++ b/test.go @@ -0,0 +1,82 @@ +package main + +import ( + "os" + path "path/filepath" + "os/exec" + "time" + "bytes" +) + +var cmdTest = &Command{ + UsageLine: "test [appname]", + Short: "test the app", + Long: ``, +} + +func init() { + cmdTest.Run = testApp +} + +var started= make(chan bool) + +func testApp(cmd *Command, args []string) { + if len(args) != 1 { + colorLog("[ERRO] Cannot start running[ %s ]\n", + "argument 'appname' is missing") + os.Exit(2) + } + crupath, _ := os.Getwd() + Debugf("current path:%s\n", crupath) + + err := loadConfig() + if err != nil { + colorLog("[ERRO] Fail to parse bee.json[ %s ]", err) + } + var paths []string + paths = append(paths, + path.Join(crupath, conf.DirStruct.Controllers), + path.Join(crupath, conf.DirStruct.Models), + path.Join(crupath, "./")) // Current path. + // Because monitor files has some issues, we watch current directory + // and ignore non-go files. + paths = append(paths, conf.DirStruct.Others...) + paths = append(paths, conf.MainFiles.Others...) + + NewWatcher(paths) + appname = args[0] + Autobuild() + for { + select { + case <-started: + runTest() + Kill() + os.Exit(0) + } + } +} + +func runTest(){ + colorLog("[INFO] Start testing...\n") + time.Sleep(time.Second*5) + path, _ := os.Getwd() + os.Chdir(path+"/tests") + + var err error + icmd := exec.Command("go", "test") + var out,errbuffer bytes.Buffer + icmd.Stdout = &out + icmd.Stderr = &errbuffer + colorLog("[INFO] ============== Test Begin ===================\n") + err = icmd.Run() + colorLog(out.String()) + colorLog(errbuffer.String()) + colorLog("[INFO] ============== Test End ===================\n") + + if err != nil { + colorLog("[ERRO] ============== Test failed ===================\n") + colorLog("[ERRO] " ,err) + return + } + colorLog("[SUCC] Test finish\n") +} From d42aec07b4be3a7059209396878bd127c41e074c Mon Sep 17 00:00:00 2001 From: fanngyuan Date: Thu, 22 Aug 2013 12:19:45 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=88=9A=E6=89=8D=E6=BC=8F=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bee.go | 1 + watch.go | 1 + 2 files changed, 2 insertions(+) diff --git a/bee.go b/bee.go index 5450aea..e31c536 100644 --- a/bee.go +++ b/bee.go @@ -76,6 +76,7 @@ var commands = []*Command{ cmdPack, cmdApiapp, cmdRouter, + cmdTest, //cmdReStart, } diff --git a/watch.go b/watch.go index 9f05e53..34cd6a7 100644 --- a/watch.go +++ b/watch.go @@ -147,6 +147,7 @@ func Start(appname string) { cmd.Stderr = os.Stderr go cmd.Run() + started<-true } // checkTMPFile returns true if the event was for TMP files. From 90648d22cda427612025466ce7dc73363aab2f03 Mon Sep 17 00:00:00 2001 From: slene Date: Thu, 22 Aug 2013 14:54:02 +0800 Subject: [PATCH 4/4] avoid panic when len(log) == 0 in colorLog func --- util.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util.go b/util.go index 2846b97..6cafb46 100644 --- a/util.go +++ b/util.go @@ -50,6 +50,10 @@ const ( // Errors have to surrounded by "[ " and " ]"(space). func colorLog(format string, a ...interface{}) { log := fmt.Sprintf(format, a...) + if len(log) == 0 { + return + } + if runtime.GOOS != "windows" { var clog string