diff --git a/namespace.go b/namespace.go index 722ec0e8..26371af7 100644 --- a/namespace.go +++ b/namespace.go @@ -14,6 +14,8 @@ import ( type namespaceCond func(*beecontext.Context) bool +type innnerNamespace func(*Namespace) + // Namespace is store all the info type Namespace struct { prefix string @@ -21,12 +23,15 @@ type Namespace struct { } // get new Namespace -func NewNamespace(prefix string) *Namespace { - cr := NewControllerRegistor() - return &Namespace{ +func NewNamespace(prefix string, params ...innnerNamespace) *Namespace { + ns := &Namespace{ prefix: prefix, - handlers: cr, + handlers: NewControllerRegistor(), } + for _, p := range params { + p(ns) + } + return ns } // set condtion function @@ -68,14 +73,16 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace { // ctx.Redirect(302, "/login") // } // }) -func (n *Namespace) Filter(action string, filter FilterFunc) *Namespace { +func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace { var a int if action == "before" { a = BeforeRouter } else if action == "after" { a = FinishRouter } - n.handlers.InsertFilter("*", a, filter) + for _, f := range filter { + n.handlers.InsertFilter("*", a, f) + } return n } @@ -163,6 +170,13 @@ func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace { return n } +// add include class +// refer: https://godoc.org/github.com/astaxie/beego#Include +func (n *Namespace) Include(cList ...ControllerInterface) *Namespace { + n.handlers.Include(cList...) + return n +} + // nest Namespace // usage: //ns := beego.NewNamespace(“/v1”). @@ -230,3 +244,116 @@ func AddNamespace(nl ...*Namespace) { } } } + +// Namespace Condition +func NSCond(cond namespaceCond) innnerNamespace { + return func(ns *Namespace) { + ns.Cond(cond) + } +} + +// Namespace BeforeRouter filter +func NSBefore(filiterList ...FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Filter("before", filiterList...) + } +} + +// Namespace FinishRouter filter +func NSAfter(filiterList ...FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Filter("after", filiterList...) + } +} + +// Namespace Include ControllerInterface +func NSInclude(cList ...ControllerInterface) innnerNamespace { + return func(ns *Namespace) { + ns.Include(cList...) + } +} + +// Namespace Router +func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) innnerNamespace { + return func(ns *Namespace) { + ns.Router(rootpath, c, mappingMethods...) + } +} + +// Namespace Get +func NSGet(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Get(rootpath, f) + } +} + +// Namespace Post +func NSPost(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Post(rootpath, f) + } +} + +// Namespace Head +func NSHead(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Head(rootpath, f) + } +} + +// Namespace Put +func NSPut(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Put(rootpath, f) + } +} + +// Namespace Delete +func NSDelete(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Delete(rootpath, f) + } +} + +// Namespace Any +func NSAny(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Any(rootpath, f) + } +} + +// Namespace Options +func NSOptions(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Options(rootpath, f) + } +} + +// Namespace Patch +func NSPatch(rootpath string, f FilterFunc) innnerNamespace { + return func(ns *Namespace) { + ns.Patch(rootpath, f) + } +} + +//Namespace AutoRouter +func NSAutoRouter(c ControllerInterface) innnerNamespace { + return func(ns *Namespace) { + ns.AutoRouter(c) + } +} + +// Namespace AutoPrefix +func NSAutoPrefix(prefix string, c ControllerInterface) innnerNamespace { + return func(ns *Namespace) { + ns.AutoPrefix(prefix, c) + } +} + +// Namespace add sub Namespace +func NSNamespace(prefix string, params ...innnerNamespace) innnerNamespace { + return func(ns *Namespace) { + n := NewNamespace(prefix, params...) + ns.Namespace(n) + } +} diff --git a/namespace_test.go b/namespace_test.go index 2d6df77a..9142d62c 100644 --- a/namespace_test.go +++ b/namespace_test.go @@ -143,3 +143,21 @@ func TestNamespaceCond(t *testing.T) { t.Errorf("TestNamespaceCond can't run get the result " + strconv.Itoa(w.Code)) } } + +func TestNamespaceInside(t *testing.T) { + r, _ := http.NewRequest("GET", "/v3/shop/order/123", nil) + w := httptest.NewRecorder() + ns := NewNamespace("/v3", + NSAutoRouter(&TestController{}), + NSNamespace("/shop", + NSGet("/order/:id", func(ctx *context.Context) { + ctx.Output.Body([]byte(ctx.Input.Param(":id"))) + }), + ), + ) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != "123" { + t.Errorf("TestNamespaceInside can't run, get the response is " + w.Body.String()) + } +} diff --git a/parser.go b/parser.go index e315f9b4..c381c369 100644 --- a/parser.go +++ b/parser.go @@ -6,14 +6,18 @@ package beego import ( + "encoding/json" "errors" "fmt" "go/ast" "go/parser" "go/token" + "io/ioutil" "os" "path" "strings" + + "github.com/astaxie/beego/utils" ) var globalRouterTemplate = `package routers @@ -27,13 +31,22 @@ func init() { } ` -var genInfoList map[string][]ControllerComments +var ( + lastupdateFilename string = "lastupdate.tmp" + pkgLastupdate map[string]int64 + genInfoList map[string][]ControllerComments +) func init() { + pkgLastupdate = make(map[string]int64) genInfoList = make(map[string][]ControllerComments) } func parserPkg(pkgRealpath, pkgpath string) error { + if !compareFile(pkgRealpath) { + Info(pkgRealpath + " don't has updated") + return nil + } fileSet := token.NewFileSet() astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool { name := info.Name() @@ -54,6 +67,7 @@ func parserPkg(pkgRealpath, pkgpath string) error { } } genRouterCode() + savetoFile(pkgRealpath) return nil } @@ -119,8 +133,14 @@ func genRouterCode() { } params = strings.TrimRight(params, ",") + "}" } - globalinfo = globalinfo + fmt.Sprintln(`beego.GlobalControllerRouter["`+k+`"] = append(beego.GlobalControllerRouter["`+k+`"], beego.ControllerComments{"`+ - strings.TrimSpace(c.Method)+`", "`+c.Router+`", `+allmethod+", "+params+"})") + globalinfo = globalinfo + ` + beego.GlobalControllerRouter["` + k + `"] = append(beego.GlobalControllerRouter["` + k + `"], + beego.ControllerComments{ + "` + strings.TrimSpace(c.Method) + `", + "` + c.Router + `", + ` + allmethod + `, + ` + params + `}) +` } } if globalinfo != "" { @@ -132,3 +152,36 @@ func genRouterCode() { f.WriteString(strings.Replace(globalRouterTemplate, "{{.globalinfo}}", globalinfo, -1)) } } + +func compareFile(pkgRealpath string) bool { + if utils.FileExists(path.Join(AppPath, lastupdateFilename)) { + content, err := ioutil.ReadFile(path.Join(AppPath, lastupdateFilename)) + if err != nil { + return true + } + json.Unmarshal(content, &pkgLastupdate) + ft, err := os.Lstat(pkgRealpath) + if err != nil { + return true + } + if v, ok := pkgLastupdate[pkgRealpath]; ok { + if ft.ModTime().UnixNano() > v { + return false + } + } + } + return true +} + +func savetoFile(pkgRealpath string) { + ft, err := os.Lstat(pkgRealpath) + if err != nil { + return + } + pkgLastupdate[pkgRealpath] = ft.ModTime().UnixNano() + d, err := json.Marshal(pkgLastupdate) + if err != nil { + return + } + ioutil.WriteFile(path.Join(AppPath, lastupdateFilename), d, os.ModePerm) +}