diff --git a/.gitignore b/.gitignore index 745dfc8..52db7dc 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ tmp.out # GoLand project files .idea/ *.iml + +/mir diff --git a/Makefile b/Makefile index 11c6a0c..65200c0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ -GO ?= go GOFMT ?= gofmt -s -PACKAGES ?= $(shell GO111MODULE=on $(GO) list ./...) +PACKAGES ?= $(shell go list ./...) GOFILES := $(shell find . -name "*.go" -type f) .PHONY: default @@ -9,9 +8,19 @@ default: ci .PHONY: ci ci: misspell vet test +.PHONY: build +build: fmt + go build -o mir mirc/main.go + +.PHONY: generate +generate: + -rm -f generator/templates_gen.go + go generate generator/templates.go + $(GOFMT) -w generator/templates_gen.go + .PHONY: test test: fmt - hack/test.sh ./ module/echo module/gin module/chi module/httprouter module/iris module/mux + go test . .PHONY: fmt fmt: @@ -28,7 +37,7 @@ fmt-check: .PHONY: vet vet: - hack/vet.sh ./ module/echo module/gin module/chi module/httprouter module/iris module/mux module/example + go vet . .PHONY: lint lint: diff --git a/README.md b/README.md index ee16a9b..a4c3953 100644 --- a/README.md +++ b/README.md @@ -2,66 +2,6 @@ [![Build Status](https://api.travis-ci.com/alimy/mir.svg?branch=master)](https://travis-ci.com/alimy/mir) [![codecov](https://codecov.io/gh/alimy/mir/branch/master/graph/badge.svg)](https://codecov.io/gh/alimy/mir) [![GoDoc](https://godoc.org/github.com/alimy/mir?status.svg)](https://godoc.org/github.com/alimy/mir) -[![Release](https://img.shields.io/github/release/alimy/mir.svg?style=flat-square)](https://github.com/alimy/mir/releases) Mir is used for register handler to http router(eg: [Gin](https://github.com/gin-gonic/gin), [Chi](https://github.com/go-chi/chi), [Echo](https://github.com/labstack/echo), [Iris](https://github.com/kataras/iris), [Macaron](https://github.com/go-macaron/macaron), [Mux](https://github.com/gorilla/mux), [httprouter](https://github.com/julienschmidt/httprouter)) - depends on struct tag string info that defined in logic object's struct type field. - -### Usage (eg: gin backend) -* Get Mir.Gin module first - -```bash -go get github.com/alimy/mir/module/gin@master -``` - -* Then happy in codding enjoy your heart... - -```go -package main - -import( - "github.com/alimy/mir" - "github.com/gin-gonic/gin" - "net/http" - - mirE "github.com/alimy/mir/module/gin" -) - -type site struct { - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(c *gin.Context) { - c.String(http.StatusOK, "get index data") -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/:category/#GetArticles) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (h *site) GetArticles(c *gin.Context) { - c.String(http.StatusOK, "get articles data") -} - -func main() { - //Create a new gin engine - engine := gin.New() - - // Register handler to engine by mir - mirE.Register(engine, &site{Chain: gin.HandlersChain{gin.Logger()}}) - - // Start gin engine serve - engine.Run() -} - -``` - -### Sample code use mir build web application -* [github.com/alimy/mir-music](https://github.com/alimy/mir-music) : use [mir](https://github.com/alimy/mir)+[gin](https://github.com/gin-gonic/gin) build a sample music infomation service app like [spring-music](https://github.com/cloudfoundry-samples/spring-music). -* [github.com/alimy/chi-music](https://github.com/alimy/chi-music) : use [mir](https://github.com/alimy/mir)+[go-chi](https://github.com/go-chi/chi) implement [spring-music](https://github.com/cloudfoundry-samples/spring-music) in golang. + depends on struct tag string info that defined in logic object's struct type field. \ No newline at end of file diff --git a/core.go b/core.go deleted file mode 100644 index 6aa871c..0000000 --- a/core.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mir - -// Group indicator a default group for handler to register to server engine -type Group string - -// Chain indicator a Handler slice used register Middleware to router by group -type Chain interface{} - -// Get indicator a GET method handler used placeholder register info in struct tag -type Get interface{} - -// Put indicator a PUT method handler used placeholder register info in struct tag -type Put interface{} - -// Post indicator a POST method handler used placeholder register info in struct tag -type Post interface{} - -// Delete indicator a DELETE method handler used placeholder register info in struct tag -type Delete interface{} - -// Head indicator a HEAD method handler used placeholder register info in struct tag -type Head interface{} - -// Patch indicator a PATCH method handler used placeholder register info in struct tag -type Patch interface{} - -// Trace indicator a TRACE method handler used placeholder register info in struct tag -type Trace interface{} - -// Connect indicator a CONNECT method handler used placeholder register info in struct tag -type Connect interface{} - -// Options indicator a OPTIONS method handler used placeholder register info in struct tag -type Options interface{} - -// Any indicator a Any method handler used placeholder register info in struct tag. -// This is mean register handler that all http.Method* include(GET, PUT, POST, DELETE, -// HEAD, PATCH, OPTIONS) -type Any interface{} - -// Engine register mir tag info's handler to engine. -// Other http engine router can implement this interface then use mir to register -// handler engine(eg: gin,echo,mux,httprouter) -type Engine interface { - Register([]*TagMir) error -} diff --git a/core/core.go b/core/core.go new file mode 100644 index 0000000..5b0531f --- /dev/null +++ b/core/core.go @@ -0,0 +1,58 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package core + +var ( + // Generators generators list + Generators = make(map[string]Generator, 4) + + // DefParser default parser + DefParser Parser +) + +// Generator list +var ( + EngineGin = "gin" + EngineChi = "chi" + EngineMux = "mux" + EngineHttpRouter = "httprouter" +) + +// GenOpts generator options +type GenOpts struct { + Name string + OutPath string +} + +// TagMir mir tag's info +type TagMir struct { + // TODO +} + +// Parser parse entries +type Parser interface { + Name() string + Parse(entries []interface{}) ([]*TagMir, error) +} + +// Generator generate interface code for engine +type Generator interface { + Name() string + Generate([]*TagMir, *GenOpts) error +} + +// Register generator +func Register(gs ...Generator) { + for _, g := range gs { + if g != nil && g.Name() != "" { + Generators[g.Name()] = g + } + } +} + +// setDefParser set default parser +func SetDefParser(p Parser) { + DefParser = p +} diff --git a/core_test.go b/core_test.go deleted file mode 100644 index 456067a..0000000 --- a/core_test.go +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mir_test - -import ( - . "github.com/alimy/mir" -) - -// entry mux style URN entry -type muxEntry struct { - Chain Chain `mir:"-"` - Group Group `mir:"v1"` - DotHandler Any `mir:"/dot/handler/#."` - get Get `mir:"/get/"` - put Put `mir:"/put/"` - post Post `mir:"/post/"` - delete Delete `mir:"/delete/"` - head Head `mir:"/head/"` - patch Patch `mir:"/patch/"` - trace Trace `mir:"/trace/"` - connect Connect `mir:"/connect/"` - options Options `mir:"/options/"` - any Any `mir:"/any/"` - alias Get `mir:"/alias/#GetAlias"` - chainFunc1 Get `mir:"/chainfunc1/#-ChainFunc"` - chainFunc2 Get `mir:"/chainfunc2/#GetChainFunc2&ChainFunc"` - query Get `mir:"/query/?filter={filter}"` - full Get `mir:"//{subdomain}.domain.com:8013/full/{other}/{id:[0-9]+}?filter={filter}&foo=bar&index={index:[0-9]+}#GetFull"` -} - -// ginEntry gin,echo,httrouter style URN entry -type ginEntry struct { - Chain Chain `mir:"-"` - DotHandler Any `mir:"/dot/handler/#."` - group Group `mir:"v1"` - get Get `mir:"/get/"` - put Put `mir:"/put/"` - post Post `mir:"/post/"` - delete Delete `mir:"/delete/"` - head Head `mir:"/head/"` - patch Patch `mir:"/patch/"` - trace Trace `mir:"/trace/"` - connect Connect `mir:"/connect/"` - options Options `mir:"/options/"` - any Any `mir:"/any/"` - alias Get `mir:"/alias/#GetAlias"` - chainFunc1 Get `mir:"/chainfunc1/#-ChainFunc"` - chainFunc2 Get `mir:"/chainfunc2/#GetChainFunc2&ChainFunc"` - full Get `mir:"/full/:other/:name#GetFull"` -} - -// irisEntry iris style URN entry -type irisEntry struct { - Chain Chain `mir:"-"` - DotHandler Any `mir:"/dot/handler/#."` - group Group `mir:"v1"` - get Get `mir:"/get/"` - put Put `mir:"/put/"` - post Post `mir:"/post/"` - delete Delete `mir:"/delete/"` - head Head `mir:"/head/"` - patch Patch `mir:"/patch/"` - trace Trace `mir:"/trace/"` - connect Connect `mir:"/connect/"` - options Options `mir:"/options/"` - any Any `mir:"/any/"` - alias Get `mir:"/alias/#GetAlias"` - chainFunc1 Get `mir:"/chainfunc1/#-ChainFunc"` - chainFunc2 Get `mir:"/chainfunc2/#GetChainFunc2&ChainFunc"` - full Get `mir:"/full/{other:string}/{name:string range(1,200) else 400}#GetFull"` -} - -// urbanEntry used to test custom mir tag name entry -type urbanEntry struct { - group Group `urban:"v1"` - get Get `urban:"/get/"` -} - -// errGroupEntry used to test direct assign group info to no exported group filed occurs error -type errGroupEntry struct { - group Group `mir:"-"` - get Get `mir:"/get/"` -} - -// errChainEntry used to test assign exported chain field occurs error -type errChainEntry struct { - chain Chain `mir:"-"` - get Get `mir:"/get/"` -} - -// errNoMethodEntry used to test no method define occurs error -type errNoMethodEntry struct { - get Get `mir:"/get/"` -} - -// handlerFunc fake handler function -type handlerFunc func() string - -// chains fake chain of middleware -type chains []func() string - -func (*muxEntry) Get() string { - return "/get/" -} - -func (*muxEntry) Put() string { - return "/put/" -} - -func (*muxEntry) Post() string { - return "/post/" -} - -func (*muxEntry) Delete() string { - return "/delete/" -} - -func (*muxEntry) Head() string { - return "/head/" -} - -func (*muxEntry) Patch() string { - return "/patch/" -} - -func (*muxEntry) Trace() string { - return "/trace/" -} - -func (*muxEntry) Connect() string { - return "/connect/" -} - -func (*muxEntry) Options() string { - return "/options/" -} - -func (*muxEntry) Any() string { - return "/any/" -} - -func (*muxEntry) GetAlias() string { - return "/alias/" -} - -func (*muxEntry) ChainFunc1() string { - return "/chainfunc1/" -} - -func (*muxEntry) GetChainFunc2() string { - return "/chainfunc2/" -} - -func (*muxEntry) ChainFunc() string { - return "chainFunc" -} - -func (*muxEntry) Query() string { - return "/query/" -} - -func (*muxEntry) GetFull() string { - return "/full/{other}/{id:[0-9]+}" -} - -func (*ginEntry) Get() string { - return "/get/" -} - -func (*ginEntry) Put() string { - return "/put/" -} - -func (*ginEntry) Post() string { - return "/post/" -} - -func (*ginEntry) Delete() string { - return "/delete/" -} - -func (*ginEntry) Head() string { - return "/head/" -} - -func (*ginEntry) Patch() string { - return "/patch/" -} - -func (*ginEntry) Trace() string { - return "/trace/" -} - -func (*ginEntry) Connect() string { - return "/connect/" -} - -func (*ginEntry) Options() string { - return "/options/" -} - -func (*ginEntry) Any() string { - return "/any/" -} - -func (*ginEntry) GetAlias() string { - return "/alias/" -} - -func (*ginEntry) ChainFunc1() string { - return "/chainfunc1/" -} - -func (*ginEntry) GetChainFunc2() string { - return "/chainfunc2/" -} - -func (*ginEntry) ChainFunc() string { - return "chainFunc" -} - -func (*ginEntry) Query() string { - return "/query" -} - -func (*ginEntry) GetFull() string { - return "/full/:other/:name" -} - -func (*irisEntry) Get() string { - return "/get/" -} - -func (*irisEntry) Put() string { - return "/put/" -} - -func (*irisEntry) Post() string { - return "/post/" -} - -func (*irisEntry) Delete() string { - return "/delete/" -} - -func (*irisEntry) Head() string { - return "/head/" -} - -func (*irisEntry) Patch() string { - return "/patch/" -} - -func (*irisEntry) Trace() string { - return "/trace/" -} - -func (*irisEntry) Connect() string { - return "/connect/" -} - -func (*irisEntry) Options() string { - return "/options/" -} - -func (*irisEntry) Any() string { - return "/any/" -} - -func (*irisEntry) GetAlias() string { - return "/alias/" -} - -func (*irisEntry) ChainFunc1() string { - return "/chainfunc1/" -} - -func (*irisEntry) GetChainFunc2() string { - return "/chainfunc2/" -} - -func (*irisEntry) ChainFunc() string { - return "chainFunc" -} - -func (*irisEntry) Query() string { - return "/query" -} - -func (*irisEntry) GetFull() string { - return "/full/{other:string}/{name:string range(1,200) else 400}" -} - -func (*urbanEntry) Get() string { - return "/get/" -} - -func (*errChainEntry) Get() string { - return "/get/" -} - -func (*errGroupEntry) Get() string { - return "/get/" -} - -func DotHandler() string { - return "/dot/handler/" -} - -func pingChain() string { - return "pingChain" -} - -func pongChain() string { - return "pongChain" -} - -func mirChains() chains { - return chains{ - pingChain, - pongChain, - } -} diff --git a/doc.go b/doc.go deleted file mode 100644 index 3e25ec7..0000000 --- a/doc.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -/* -Package mir provider yet another style to write http handler used register to router. - -Define handler in struct type like below: - - type entry struct { - count uint32 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"//{subdomain}.example.com/articles/{category}/{id:[0-9]+}?filter={filter}&foo=bar&num={num:[0-9]+}#GetArticles"` - } - - // Index handler of the index field that in site struct, the struct tag indicate - // this handler will register to path "/index/" and method is http.MethodGet. - func (e *entry) Index(c Index(rw http.ResponseWriter, r *http.Request) { - e.count++ - rw.WriteHeader(200) - rw.Write([]byte("Index")) - } - - // GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. - func (e *entry) GetArticles(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - result := strings.Join([]string{ - "GetArticles", - vars["subdomain"], - vars["category"], - vars["id"], - vars["filter"], - vars["num"], - }, ":") - rw.WriteHeader(200) - rw.Write([]byte(result)) - } - - // GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. - // Host info is the first segment start with '//'(eg:{subdomain}.domain.com) - // Path info is the second or first(if no host info) segment start with '/'(eg: /articles/{category}/{id:[0-9]+}?{filter}) - // Queries info is the third info start with '?' and delimiter by '&'(eg: {filter}&{pages}) - // Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will - // use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will - // is Articles) - func (h *site) GetArticles(c gin.Context) { - c.String(http.StatusOK, "get articles data") - } - - // mirChain chain used to register to engine - func mirChain() []mux.MiddlewareFunc { - return []mux.MiddlewareFunc{ - simpleMiddleware, - simpleMiddleware, - } - } - - func simpleMiddleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Do nothing just for test - h.ServeHTTP(w, r) - }) - } - -Then register entry such use mux router: - - import ( - "github.com/alimy/mir" - "github.com/gorilla/mux" - "net/http" - "log" - - mirE "github.com/alimy/mir/module/mux" - ) - - func main() { - // Create a new mux router instance - r := mux.NewRouter() - - // Register handler to engine by mir - mirE.Register(r, &entry{Chain: mirChain()}) - - // Bind to a port and pass our router in - log.Fatal(http.ListenAndServe(":8000", r)) - } - -*/ -package mir diff --git a/engine/engine.go b/engine/engine.go new file mode 100644 index 0000000..4554889 --- /dev/null +++ b/engine/engine.go @@ -0,0 +1,34 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package engine + +import ( + "errors" + "fmt" + + "github.com/alimy/mir/v2/core" + + _ "github.com/alimy/mir/v2/generator" + _ "github.com/alimy/mir/v2/parser" +) + +// Generate generate interface code +func Generate(entries []interface{}, opts *core.GenOpts) error { + if opts == nil { + return errors.New("options is nil") + } + g, exist := core.Generators[opts.Name] + if !exist { + return fmt.Errorf("unknow generators that name %s", opts.Name) + } + if core.DefParser == nil { + return errors.New("parser is nil") + } + mirTags, err := core.DefParser.Parse(entries) + if err != nil { + return g.Generate(mirTags, opts) + } + return err +} diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..742988d --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,15 @@ +GOFMT ?= gofmt -s -w +GOFILES := $(shell find . -name "*.go" -type f) + +.PHONY: build +build: fmt + go build . + +.PHONY: generate +generate: + -rm -rf mirc/gen + go generate mirc/main.go + +.PHONY: fmt +fmt: + $(GOFMT) $(GOFILES) diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..4745e7f --- /dev/null +++ b/examples/README.md @@ -0,0 +1,8 @@ +## mir-examples +just a simple mir's examples for explain how to use mir in your project. + +#### Usage +```bash +% go generate ./mirc #will generate code to mirc/gen directory +% go run main.go +``` diff --git a/examples/go.mod b/examples/go.mod new file mode 100644 index 0000000..641f1ea --- /dev/null +++ b/examples/go.mod @@ -0,0 +1,5 @@ +module github.com/alimy/mir/v2/examples + +go 1.12 + +require github.com/gin-gonic/gin v1.4.0 diff --git a/examples/go.sum b/examples/go.sum new file mode 100644 index 0000000..59e8d3b --- /dev/null +++ b/examples/go.sum @@ -0,0 +1,21 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/examples/main.go b/examples/main.go new file mode 100644 index 0000000..699d1a6 --- /dev/null +++ b/examples/main.go @@ -0,0 +1,39 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package main + +import ( + "log" + + "github.com/gin-gonic/gin" + + "github.com/alimy/mir/v2/examples/mirc/gen/api" + "github.com/alimy/mir/v2/examples/mirc/gen/api/v1" + "github.com/alimy/mir/v2/examples/mirc/gen/api/v2" + "github.com/alimy/mir/v2/examples/servants" +) + +func main() { + e := gin.New() + + // register servants to engine + registerServants(e) + + // start servant service + if err := e.Run(); err != nil { + log.Fatal(err) + } +} + +func registerServants(e *gin.Engine) { + // register default group routes + api.RegisterSiteServant(e, servants.EmptySiteWithNoGroup{}) + + // register routes for group v1 + v1.RegisterSiteServant(e, servants.EmptySiteV1{}) + + // register routes for group v2 + v2.RegisterSiteServant(e, servants.EmptySiteV2{}) +} diff --git a/examples/mirc/gen/api/mir.go b/examples/mirc/gen/api/mir.go new file mode 100644 index 0000000..ada8534 --- /dev/null +++ b/examples/mirc/gen/api/mir.go @@ -0,0 +1,11 @@ +// Code generated by go-mir. DO NOT EDIT. + +package api + +import ( + "github.com/gin-gonic/gin" +) + +func RegisterSiteServant(e *gin.Engine, site Site) { + // TODO: code will generated by go-mir +} diff --git a/examples/mirc/gen/api/site.go b/examples/mirc/gen/api/site.go new file mode 100644 index 0000000..f3c6ebf --- /dev/null +++ b/examples/mirc/gen/api/site.go @@ -0,0 +1,12 @@ +// Code generated by go-mir. DO NOT EDIT. + +package api + +import ( + "github.com/gin-gonic/gin" +) + +type Site interface { + Index(c *gin.Context) + Articles(c *gin.Context) +} diff --git a/examples/mirc/gen/api/v1/mir.go b/examples/mirc/gen/api/v1/mir.go new file mode 100644 index 0000000..dc0b2a7 --- /dev/null +++ b/examples/mirc/gen/api/v1/mir.go @@ -0,0 +1,11 @@ +// Code generated by go-mir. DO NOT EDIT. + +package v1 + +import ( + "github.com/gin-gonic/gin" +) + +func RegisterSiteServant(e *gin.Engine, site Site) { + // TODO: code will generated by go-mir +} diff --git a/examples/mirc/gen/api/v1/site.go b/examples/mirc/gen/api/v1/site.go new file mode 100644 index 0000000..27ffc21 --- /dev/null +++ b/examples/mirc/gen/api/v1/site.go @@ -0,0 +1,12 @@ +// Code generated by go-mir. DO NOT EDIT. + +package v1 + +import ( + "github.com/gin-gonic/gin" +) + +type Site interface { + Index(c *gin.Context) + Articles(c *gin.Context) +} diff --git a/examples/mirc/gen/api/v2/mir.go b/examples/mirc/gen/api/v2/mir.go new file mode 100644 index 0000000..96b05a5 --- /dev/null +++ b/examples/mirc/gen/api/v2/mir.go @@ -0,0 +1,11 @@ +// Code generated by go-mir. DO NOT EDIT. + +package v2 + +import ( + "github.com/gin-gonic/gin" +) + +func RegisterSiteServant(e *gin.Engine, site Site) { + // TODO: code will generated by go-mir +} diff --git a/examples/mirc/gen/api/v2/site.go b/examples/mirc/gen/api/v2/site.go new file mode 100644 index 0000000..32e1afe --- /dev/null +++ b/examples/mirc/gen/api/v2/site.go @@ -0,0 +1,13 @@ +// Code generated by go-mir. DO NOT EDIT. + +package v2 + +import ( + "github.com/gin-gonic/gin" +) + +type Site interface { + Index(c *gin.Context) + Articles(c *gin.Context) + Category(c *gin.Context) +} diff --git a/examples/mirc/main.go b/examples/mirc/main.go new file mode 100644 index 0000000..067bda8 --- /dev/null +++ b/examples/mirc/main.go @@ -0,0 +1,33 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package main + +import ( + "log" + + "github.com/alimy/mir/v2/core" + "github.com/alimy/mir/v2/engine" + "github.com/alimy/mir/v2/examples/mirc/routes" + "github.com/alimy/mir/v2/examples/mirc/routes/v1" + "github.com/alimy/mir/v2/examples/mirc/routes/v2" + "github.com/gin-gonic/gin" +) + +//go:generate go run main.go + +func main() { + log.Println("generate code start") + entries := mirEntries() + _ = engine.Generate(entries, &core.GenOpts{Name: core.GeneratorGin, OutPath: "./gen"}) + log.Println("generate code finish") +} + +func mirEntries() []interface{} { + return []interface{}{ + &routes.Site{Chain: gin.HandlersChain{gin.Logger()}}, + &v1.Site{Chain: gin.HandlersChain{gin.Logger()}}, + &v2.Site{Chain: gin.HandlersChain{gin.Logger()}}, + } +} diff --git a/examples/mirc/routes/site.go b/examples/mirc/routes/site.go new file mode 100644 index 0000000..0146952 --- /dev/null +++ b/examples/mirc/routes/site.go @@ -0,0 +1,14 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package routes + +import "github.com/alimy/mir/v2" + +// Site mir's struct tag define +type Site struct { + Chain mir.Chain `mir:"-"` + Index mir.Get `mir:"/index/"` + Articles mir.Get `mir:"/articles/:category/"` +} diff --git a/examples/mirc/routes/v1/site.go b/examples/mirc/routes/v1/site.go new file mode 100644 index 0000000..2fd5a33 --- /dev/null +++ b/examples/mirc/routes/v1/site.go @@ -0,0 +1,15 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package v1 + +import "github.com/alimy/mir/v2" + +// Site mir's struct tag define +type Site struct { + Chain mir.Chain `mir:"-"` + Group mir.Group `mir:"v1"` + Index mir.Get `mir:"/index/"` + Articles mir.Get `mir:"/articles/:category/"` +} diff --git a/examples/mirc/routes/v2/site.go b/examples/mirc/routes/v2/site.go new file mode 100644 index 0000000..734a1cf --- /dev/null +++ b/examples/mirc/routes/v2/site.go @@ -0,0 +1,16 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package v2 + +import "github.com/alimy/mir/v2" + +// Site mir's struct tag define +type Site struct { + Chain mir.Chain `mir:"-"` + Group mir.Group `mir:"v2"` + Index mir.Get `mir:"/index/"` + Articles mir.Get `mir:"/articles/:category/"` + Category mir.Get `mir:"/category/"` +} diff --git a/examples/servants/site.go b/examples/servants/site.go new file mode 100644 index 0000000..1fce825 --- /dev/null +++ b/examples/servants/site.go @@ -0,0 +1,25 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package servants + +import ( + "net/http" + + "github.com/alimy/mir/v2/examples/mirc/gen/api" + "github.com/gin-gonic/gin" +) + +var _ api.Site = EmptySiteWithNoGroup{} + +// EmptySiteWithNoGroup implement api.Site interface +type EmptySiteWithNoGroup struct{} + +func (EmptySiteWithNoGroup) Index(c *gin.Context) { + c.String(http.StatusOK, "get index data (v1)") +} + +func (EmptySiteWithNoGroup) Articles(c *gin.Context) { + c.String(http.StatusOK, "get articles data (v1)") +} diff --git a/examples/servants/site_v1.go b/examples/servants/site_v1.go new file mode 100644 index 0000000..02a81ee --- /dev/null +++ b/examples/servants/site_v1.go @@ -0,0 +1,26 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package servants + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + api "github.com/alimy/mir/v2/examples/mirc/gen/api/v1" +) + +var _ api.Site = EmptySiteV1{} + +// EmptySiteV1 implement api.Site interface +type EmptySiteV1 struct{} + +func (EmptySiteV1) Index(c *gin.Context) { + c.String(http.StatusOK, "get index data (v1)") +} + +func (EmptySiteV1) Articles(c *gin.Context) { + c.String(http.StatusOK, "get articles data (v1)") +} diff --git a/examples/servants/site_v2.go b/examples/servants/site_v2.go new file mode 100644 index 0000000..0c07630 --- /dev/null +++ b/examples/servants/site_v2.go @@ -0,0 +1,30 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package servants + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + api "github.com/alimy/mir/v2/examples/mirc/gen/api/v2" +) + +var _ api.Site = EmptySiteV2{} + +// EmptySiteV2 implement api.Site interface +type EmptySiteV2 struct{} + +func (EmptySiteV2) Index(c *gin.Context) { + c.String(http.StatusOK, "get index data (v2)") +} + +func (EmptySiteV2) Articles(c *gin.Context) { + c.String(http.StatusOK, "get articles data (v2)") +} + +func (EmptySiteV2) Category(c *gin.Context) { + c.String(http.StatusOK, "get Category data (v2)") +} diff --git a/fields_test.go b/fields_test.go deleted file mode 100644 index 5fbf848..0000000 --- a/fields_test.go +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mir_test - -import ( - . "github.com/alimy/mir" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Fields", func() { - var ( - tagMirs []*TagMir - tagMir *TagMir - err error - commonPaths []string - ) - - BeforeEach(func() { - commonPaths = []string{ - "/get/", - "/put/", - "/post/", - "/delete/", - "/head/", - "/patch/", - "/trace/", - "/connect/", - "/options/", - "/any/", - "/alias/", - } - }) - - Context("mux style URN tag string", func() { - BeforeEach(func() { - tagMirs, err = TagMirFrom(&muxEntry{Chain: mirChains(), DotHandler: DotHandler}) - if err == nil && len(tagMirs) > 0 { - tagMir = tagMirs[0] - } - commonPaths = append(commonPaths, "/query/", "/full/{other}/{id:[0-9]+}") - }) - - It("only one item", func() { - Expect(tagMirs).Should(HaveLen(1)) - }) - - It("tagMir not null", func() { - Expect(tagMir).ShouldNot(BeNil()) - }) - - It("not error", func() { - Expect(err).Should(BeNil()) - }) - - It("had 16 fields", func() { - Expect(tagMir.Fields).Should(HaveLen(16)) - }) - - It("check group", func() { - Expect(tagMir.Group).To(Equal("v1")) - }) - - It("check chain", func() { - chains, ok := tagMir.Chain.(chains) - Expect(ok).Should(BeTrue()) - Expect(chains).Should(HaveLen(2)) - }) - - It("check fields", func() { - fields := assertTagFields(tagMir.Fields) - for _, path := range commonPaths { - Expect(fields).Should(HaveKey(path)) - } - }) - }) - - Context("gin style URN tag string", func() { - BeforeEach(func() { - tagMirs, err = TagMirFrom(&ginEntry{Chain: mirChains(), DotHandler: DotHandler}) - if err == nil && len(tagMirs) > 0 { - tagMir = tagMirs[0] - } - commonPaths = append(commonPaths, "/full/:other/:name") - }) - - It("only one item", func() { - Expect(tagMirs).Should(HaveLen(1)) - }) - - It("tagMir not null", func() { - Expect(tagMir).ShouldNot(BeNil()) - }) - - It("not error", func() { - Expect(err).Should(BeNil()) - }) - - It("had 15 fields", func() { - Expect(tagMir.Fields).Should(HaveLen(15)) - }) - - It("check group", func() { - Expect(tagMir.Group).To(Equal("v1")) - }) - - It("check chain", func() { - chains, ok := tagMir.Chain.(chains) - Expect(ok).Should(BeTrue()) - Expect(chains).Should(HaveLen(2)) - }) - - It("check fields", func() { - fields := assertTagFields(tagMir.Fields) - for _, path := range commonPaths { - Expect(fields).Should(HaveKey(path)) - } - }) - }) - - Context("iris style URN tag string", func() { - BeforeEach(func() { - tagMirs, err = TagMirFrom(&irisEntry{Chain: mirChains(), DotHandler: DotHandler}) - if err == nil && len(tagMirs) > 0 { - tagMir = tagMirs[0] - } - commonPaths = append(commonPaths, "/full/{other:string}/{name:string range(1,200) else 400}") - }) - - It("only one item", func() { - Expect(tagMirs).Should(HaveLen(1)) - }) - - It("tagMir not null", func() { - Expect(tagMir).ShouldNot(BeNil()) - }) - - It("not error", func() { - Expect(err).Should(BeNil()) - }) - - It("had 15 fields", func() { - Expect(tagMir.Fields).Should(HaveLen(15)) - }) - - It("check group", func() { - Expect(tagMir.Group).To(Equal("v1")) - }) - - It("check chain", func() { - chains, ok := tagMir.Chain.(chains) - Expect(ok).Should(BeTrue()) - Expect(chains).Should(HaveLen(2)) - }) - - It("check fields", func() { - fields := assertTagFields(tagMir.Fields) - for _, path := range commonPaths { - Expect(fields).Should(HaveKey(path)) - } - }) - }) - - Context("tagMirs from 3 entries", func() { - BeforeEach(func() { - entries := []interface{}{ - &muxEntry{Group: "v2"}, - &ginEntry{Chain: mirChains()}, - &irisEntry{}, - } - tagMirs, err = TagMirFrom(entries...) - }) - - It("not error", func() { - Expect(err).Should(BeNil()) - }) - - It("want 2 item", func() { - Expect(tagMirs).Should(HaveLen(2)) - }) - - It("check group", func() { - haveV2Group := false - for _, item := range tagMirs { - if item.Group == "v2" { - haveV2Group = true - Expect(item.Fields).Should(HaveLen(16)) - } else if item.Group == "v1" { - Expect(item.Fields).Should(HaveLen(30)) - } - } - Expect(haveV2Group).Should(BeTrue()) - }) - }) - - Context("check error group", func() { - It("should error", func() { - defer GinkgoRecover() - - if mirs, e := TagMirFrom(&errGroupEntry{group: "v3"}); e == nil { - tagMirs = mirs - err = nil - } else { - err = e - } - Expect(err).Should(BeNil()) - }) - }) - - Context("check error no method", func() { - It("should error", func() { - if mirs, e := TagMirFrom(&errNoMethodEntry{}); e == nil { - tagMirs = mirs - err = nil - } else { - err = e - } - Expect(err).ShouldNot(BeNil()) - }) - }) -}) - -func assertTagFields(fields []*TagField) map[string]*TagField { - pathFields := make(map[string]*TagField, len(fields)) - for _, field := range fields { - pathFields[field.Path] = field - handler, ok := field.Handler.(func() string) - Expect(ok).Should(BeTrue()) - result := handler() - Expect(result).To(Equal(field.Path)) - if field.ChainFunc != nil { - chainFunc, ok := field.ChainFunc.(func() string) - Expect(ok).Should(BeTrue()) - res := chainFunc() - Expect(res).To(Equal("chainFunc")) - } - switch field.Path { - case "/query/": - Expect(field.Queries).Should(HaveLen(1)) - case "/full/{other}/{id:[0-9]+}": - Expect(field.Host).To(Equal("{subdomain}.domain.com:8013")) - Expect(field.Queries).Should(HaveLen(3)) - } - } - return pathFields -} diff --git a/module/mux/mux_suite_test.go b/generator/generator.go similarity index 53% rename from module/mux/mux_suite_test.go rename to generator/generator.go index 9fbb31f..4aaa86d 100644 --- a/module/mux/mux_suite_test.go +++ b/generator/generator.go @@ -2,16 +2,15 @@ // Use of this source code is governed by Apache License 2.0 that // can be found in the LICENSE file. -package mux_test +package generator import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + "github.com/alimy/mir/v2/core" ) -func TestMux(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Mux Suite") +func init() { + core.Register(generatorGin{}, + generatorChi{}, + generatorMux{}, + generatorHttpRouter{}) } diff --git a/generator/generator_chi.go b/generator/generator_chi.go new file mode 100644 index 0000000..351d376 --- /dev/null +++ b/generator/generator_chi.go @@ -0,0 +1,28 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package generator + +import ( + "errors" + + "github.com/alimy/mir/v2/core" +) + +// generatorChi generator for go-chi +type generatorChi struct{} + +// Name name of generator +func (generatorChi) Name() string { + return core.EngineChi +} + +// Generate generate interface code +func (generatorChi) Generate(entries []*core.TagMir, opts *core.GenOpts) error { + // TODO + return errors.New("not ready") +} diff --git a/generator/generator_gin.go b/generator/generator_gin.go new file mode 100644 index 0000000..a83d190 --- /dev/null +++ b/generator/generator_gin.go @@ -0,0 +1,25 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package generator + +import ( + "errors" + + "github.com/alimy/mir/v2/core" +) + +// generatorGin generator for Gin +type generatorGin struct{} + +// Name name of generator +func (generatorGin) Name() string { + return core.EngineGin +} + +// Generate generate interface code +func (generatorGin) Generate(entries []*core.TagMir, opts *core.GenOpts) error { + // TODO + return errors.New("not ready") +} diff --git a/generator/generator_httprouter.go b/generator/generator_httprouter.go new file mode 100644 index 0000000..06b3d94 --- /dev/null +++ b/generator/generator_httprouter.go @@ -0,0 +1,28 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package generator + +import ( + "errors" + + "github.com/alimy/mir/v2/core" +) + +// generatorHttpRouter generator for HttpRouter +type generatorHttpRouter struct{} + +// Name name of generator +func (generatorHttpRouter) Name() string { + return core.EngineHttpRouter +} + +// Generate generate interface code +func (generatorHttpRouter) Generate(entries []*core.TagMir, opts *core.GenOpts) error { + // TODO + return errors.New("not ready") +} diff --git a/generator/generator_mux.go b/generator/generator_mux.go new file mode 100644 index 0000000..f863d1d --- /dev/null +++ b/generator/generator_mux.go @@ -0,0 +1,28 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package generator + +import ( + "errors" + + "github.com/alimy/mir/v2/core" +) + +// generatorMux generator for Mux +type generatorMux struct{} + +// Name name of generator +func (generatorMux) Name() string { + return core.EngineMux +} + +// Generate generate interface code +func (generatorMux) Generate(entries []*core.TagMir, opts *core.GenOpts) error { + // TODO + return errors.New("not ready") +} diff --git a/generator/templates.go b/generator/templates.go new file mode 100644 index 0000000..b78636b --- /dev/null +++ b/generator/templates.go @@ -0,0 +1,3 @@ +package generator + +//go:generate go-bindata -nomemcopy -pkg=${GOPACKAGE} -ignore=README.md -prefix=templates -debug=false -o=templates_gen.go templates/... diff --git a/generator/templates/README.md b/generator/templates/README.md new file mode 100644 index 0000000..e69de29 diff --git a/generator/templates/gin_iface.tmpl b/generator/templates/gin_iface.tmpl new file mode 100644 index 0000000..e69de29 diff --git a/generator/templates/gin_mir.tmpl b/generator/templates/gin_mir.tmpl new file mode 100644 index 0000000..38cdfe4 --- /dev/null +++ b/generator/templates/gin_mir.tmpl @@ -0,0 +1 @@ +package template diff --git a/generator/templates_gen.go b/generator/templates_gen.go new file mode 100644 index 0000000..f86a7ac --- /dev/null +++ b/generator/templates_gen.go @@ -0,0 +1,295 @@ +// Code generated by go-bindata. DO NOT EDIT. +// sources: +// templates/gin_iface.tmpl (0) +// templates/gin_mir.tmpl (17B) + +package generator + +import ( + "bytes" + "compress/gzip" + "crypto/sha256" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data, name string) ([]byte, error) { + gz, err := gzip.NewReader(strings.NewReader(data)) + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + + clErr := gz.Close() + if clErr != nil { + return nil, clErr + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo + digest [sha256.Size]byte +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _gin_ifaceTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00" + +func gin_ifaceTmplBytes() ([]byte, error) { + return bindataRead( + _gin_ifaceTmpl, + "gin_iface.tmpl", + ) +} + +func gin_ifaceTmpl() (*asset, error) { + bytes, err := gin_ifaceTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_iface.tmpl", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1583125664, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} + return a, nil +} + +var _gin_mirTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2a\x48\x4c\xce\x4e\x4c\x4f\x55\x28\x49\xcd\x2d\xc8\x49\x2c\x49\xe5\x02\x04\x00\x00\xff\xff\xc8\xa7\x5d\xeb\x11\x00\x00\x00" + +func gin_mirTmplBytes() ([]byte, error) { + return bindataRead( + _gin_mirTmpl, + "gin_mir.tmpl", + ) +} + +func gin_mirTmpl() (*asset, error) { + bytes, err := gin_mirTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_mir.tmpl", size: 17, mode: os.FileMode(0644), modTime: time.Unix(1583125664, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x90, 0xd7, 0x4c, 0x80, 0x9e, 0xb7, 0xcd, 0x3d, 0x28, 0x4d, 0xb7, 0x20, 0x53, 0xe4, 0x5d, 0x73, 0x82, 0x4d, 0x62, 0x3b, 0x34, 0x71, 0x19, 0x19, 0xb, 0x41, 0xdd, 0xb3, 0x21, 0x68, 0x16, 0x0}} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetString returns the asset contents as a string (instead of a []byte). +func AssetString(name string) (string, error) { + data, err := Asset(name) + return string(data), err +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// MustAssetString is like AssetString but panics when Asset would return an +// error. It simplifies safe initialization of global variables. +func MustAssetString(name string) string { + return string(MustAsset(name)) +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetDigest returns the digest of the file with the given name. It returns an +// error if the asset could not be found or the digest could not be loaded. +func AssetDigest(name string) ([sha256.Size]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) + } + return a.digest, nil + } + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) +} + +// Digests returns a map of all known files and their checksums. +func Digests() (map[string][sha256.Size]byte, error) { + mp := make(map[string][sha256.Size]byte, len(_bindata)) + for name := range _bindata { + a, err := _bindata[name]() + if err != nil { + return nil, err + } + mp[name] = a.digest + } + return mp, nil +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "gin_iface.tmpl": gin_ifaceTmpl, + "gin_mir.tmpl": gin_mirTmpl, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"}, +// AssetDir("data/img") would return []string{"a.png", "b.png"}, +// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "gin_iface.tmpl": {gin_ifaceTmpl, map[string]*bintree{}}, + "gin_mir.tmpl": {gin_mirTmpl, map[string]*bintree{}}, +}} + +// RestoreAsset restores an asset under the given directory. +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) +} + +// RestoreAssets restores an asset under the given directory recursively. +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) +} diff --git a/go.mod b/go.mod index 00d6041..f3ae79c 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,3 @@ -module github.com/alimy/mir +module github.com/alimy/mir/v2 -go 1.11 - -require ( - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 -) +go 1.12 diff --git a/go.sum b/go.sum deleted file mode 100644 index 182c786..0000000 --- a/go.sum +++ /dev/null @@ -1,23 +0,0 @@ -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/hack/test.sh b/hack/test.sh deleted file mode 100755 index 46ead14..0000000 --- a/hack/test.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2019 Michael Li . All rights reserved. -# Use of this source code is governed by Apache License 2.0 that -# can be found in the LICENSE file. - -set -o errexit -set -o nounset -set -o pipefail - -root_dir=$(pwd) -echo "mode: count" > coverage.out -for module_dir in $@; do - cd ${module_dir} - GO111MODULE=on go test -v -race -covermode=atomic -coverprofile=profile.out ./... > tmp.out - cat tmp.out - if grep -q "^--- FAIL" tmp.out; then - rm tmp.out - exit 1 - elif grep -q "build failed" tmp.out; then - rm tmp.out - exit - fi - if [ -f profile.out ]; then - cat profile.out | grep -v "mode:" >> ${root_dir}/coverage.out - rm tmp.out - rm profile.out - fi - cd - -done \ No newline at end of file diff --git a/hack/vet.sh b/hack/vet.sh deleted file mode 100755 index accc5bb..0000000 --- a/hack/vet.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2019 Michael Li . All rights reserved. -# Use of this source code is governed by Apache License 2.0 that -# can be found in the LICENSE file. - -set -o errexit -set -o nounset -set -o pipefail - -function vetModule() { - for module_dir in $@; do - cd ${module_dir} - GO111MODULE=on go vet ./... - cd - - done -} - -vetModule $@ \ No newline at end of file diff --git a/mir.go b/mir.go index 94b2a45..9f8c72a 100644 --- a/mir.go +++ b/mir.go @@ -4,44 +4,40 @@ package mir -import "fmt" - -var ( - engine Engine -) - -// SetTag set custom mir's struct tag name(eg: mir) -func SetTag(name string) { - if name != "" { - tagName = name - } -} - -// SetDefault set default engine for register handler. -func SetDefault(e Engine) { - if engine != nil { - panic("mir: Setup called twice for engine") - } - engine = e -} - -// RegisterDefault use entries's info to register handler to default engine. -// You must call SetDefault(...) setup a default engine first or return error. -func RegisterDefault(entries ...interface{}) error { - if engine == nil { - return fmt.Errorf("setup a default engine instance first then call this function") - } - return Register(engine, entries...) -} - -// Register use entries's info to register handler to give engine. -func Register(e Engine, entries ...interface{}) error { - if e == nil { - return fmt.Errorf("register entiries to a nil engine") - } - tagMirs, err := TagMirFrom(entries...) - if err != nil { - return err - } - return e.Register(tagMirs) -} +// Group indicator a default group for handler to register to server engine +type Group string + +// Chain indicator a Handler slice used register Middleware to router by group +type Chain interface{} + +// Get indicator a GET method handler used placeholder register info in struct tag +type Get interface{} + +// Put indicator a PUT method handler used placeholder register info in struct tag +type Put interface{} + +// Post indicator a POST method handler used placeholder register info in struct tag +type Post interface{} + +// Delete indicator a DELETE method handler used placeholder register info in struct tag +type Delete interface{} + +// Head indicator a HEAD method handler used placeholder register info in struct tag +type Head interface{} + +// Patch indicator a PATCH method handler used placeholder register info in struct tag +type Patch interface{} + +// Trace indicator a TRACE method handler used placeholder register info in struct tag +type Trace interface{} + +// Connect indicator a CONNECT method handler used placeholder register info in struct tag +type Connect interface{} + +// Options indicator a OPTIONS method handler used placeholder register info in struct tag +type Options interface{} + +// Any indicator a Any method handler used placeholder register info in struct tag. +// This is mean register handler that all http.Method* include(GET, PUT, POST, DELETE, +// HEAD, PATCH, OPTIONS) +type Any interface{} diff --git a/mir_suite_test.go b/mir_suite_test.go deleted file mode 100644 index 976294b..0000000 --- a/mir_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mir_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestMir(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Mir Suite") -} diff --git a/mir_test.go b/mir_test.go deleted file mode 100644 index 01a9421..0000000 --- a/mir_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mir_test - -import ( - . "github.com/alimy/mir" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Fields", func() { - var ( - tagMirs []*TagMir - tagMir *TagMir - err error - ) - - Context("check mir custom tag name", func() { - BeforeEach(func() { - SetTag("urban") - tagMirs, err = TagMirFrom(&urbanEntry{}) - if err == nil && len(tagMirs) > 0 { - tagMir = tagMirs[0] - } - SetTag(DefaultTag) - }) - - It("only one item", func() { - Expect(tagMirs).Should(HaveLen(1)) - }) - - It("tagMir not null", func() { - Expect(tagMir).ShouldNot(BeNil()) - }) - - It("not error", func() { - Expect(err).Should(BeNil()) - }) - - It("had 1 fields", func() { - Expect(tagMir.Fields).Should(HaveLen(1)) - }) - - It("check group", func() { - Expect(tagMir.Group).To(Equal("v1")) - }) - - It("check fields", func() { - assertTagFields(tagMir.Fields) - }) - }) -}) diff --git a/mirc/.gitignore b/mirc/.gitignore new file mode 100644 index 0000000..2698ada --- /dev/null +++ b/mirc/.gitignore @@ -0,0 +1 @@ +/mir diff --git a/mirc/Makefile b/mirc/Makefile new file mode 100644 index 0000000..9e896e7 --- /dev/null +++ b/mirc/Makefile @@ -0,0 +1,18 @@ +GOFILES := $(shell find . -name "*.go" -type f) + +LDFLAGS += -X "gitbus.com/exlab/zim-ss/version.BuildTime=$(shell date -u '+%Y-%m-%d %I:%M:%S %Z')" +LDFLAGS += -X "gitbus.com/exlab/zim-ss/version.GitHash=$(shell git rev-parse HEAD)" + +.PHONY: build +build: fmt + go build -ldflags '$(LDFLAGS)' -o mir main.go + +.PHONY: generate +generate: + -rm -f cmd/templates_gen.go + go generate cmd/templates.go + $(GOFMT) -w cmd/templates_gen.go + +.PHONY: fmt +fmt: + $(GOFMT) -w $(GOFILES) diff --git a/mirc/README.md b/mirc/README.md new file mode 100644 index 0000000..34f3b9b --- /dev/null +++ b/mirc/README.md @@ -0,0 +1,7 @@ +## Mirc +Mir's help toolkit + +### Release +```bash +% hub release create -m "mirc/{tag eg:v2.0.1} release" mirc/{tag eg:v2.0.1} +``` \ No newline at end of file diff --git a/mirc/cmd/new.go b/mirc/cmd/new.go new file mode 100644 index 0000000..97716ab --- /dev/null +++ b/mirc/cmd/new.go @@ -0,0 +1,83 @@ +package cmd + +import ( + "log" + "os" + "path/filepath" + + "github.com/spf13/cobra" +) + +var ( + dstPath string + style string +) + +func init() { + newCmd := &cobra.Command{ + Use: "new", + Short: "create template project", + Long: "create template project", + Run: newRun, + } + + // parse flags for agentCmd + newCmd.Flags().StringVarP(&dstPath, "dst", "d", ".", "genereted destination target directory") + newCmd.Flags().StringVarP(&style, "type", "t", "gin", "generated engine type style(eg: gin,chi,mux,httprout)") + + // register agentCmd as sub-command + register(newCmd) +} + +// newRun run new command +func newRun(_cmd *cobra.Command, _args []string) { + path, err := filepath.EvalSymlinks(dstPath) + if err != nil { + if os.IsNotExist(err) { + if !filepath.IsAbs(dstPath) { + cwd, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + path = filepath.Join(cwd, dstPath) + } else { + path = dstPath + } + } else { + log.Fatal(err) + } + } + + tmpls, exist := tmplFiles[style] + if !exist { + log.Fatal("not exist style engine") + } + + if err = genProject(path, tmpls); err != nil { + log.Fatal(err) + } +} + +func genProject(dstPath string, tmpls map[string]string) error { + var ( + err error + filePath, dirPath string + file *os.File + ) + + for fileName, assetName := range tmpls { + filePath = filepath.Join(dstPath, fileName) + dirPath = filepath.Dir(filePath) + if err = os.MkdirAll(dirPath, 0755); err != nil { + break + } + file, err = os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + break + } + if _, err = file.Write(MustAsset(assetName)); err != nil { + break + } + } + return err +} diff --git a/mirc/cmd/root.go b/mirc/cmd/root.go new file mode 100644 index 0000000..b6f83f3 --- /dev/null +++ b/mirc/cmd/root.go @@ -0,0 +1,30 @@ +package cmd + +import "github.com/spf13/cobra" + +var ( + rootCmd = &cobra.Command{ + Use: "mir", + Short: "mir help toolkit", + Long: `mir help toolkit`, + } +) + +// Setup set root command name,short-describe, long-describe +// return &cobra.Command to custom other options +func Setup(use, short, long string) *cobra.Command { + rootCmd.Use = use + rootCmd.Short = short + rootCmd.Long = long + return rootCmd +} + +// register add sub-command +func register(cmd *cobra.Command) { + rootCmd.AddCommand(cmd) +} + +// Execute start application +func Execute() { + rootCmd.Execute() +} diff --git a/mirc/cmd/templates.go b/mirc/cmd/templates.go new file mode 100644 index 0000000..3756283 --- /dev/null +++ b/mirc/cmd/templates.go @@ -0,0 +1,16 @@ +package cmd + +//go:generate go-bindata -nomemcopy -pkg=${GOPACKAGE} -ignore=README.md -prefix=templates -debug=false -o=templates_gen.go templates/... + +var tmplFiles = map[string]map[string]string{ + "gin": { + "Makefile": "makefile.tmpl", + "README.md": "readme.tmpl", + "go.mod": "gin_go_mod.tmpl", + "main.go": "gin_main.tmpl", + "mirc/main.go": "gin_mirc_main.tmpl", + "mirc/routes/site.go": "gin_mirc_routes_site.tmpl", + "mirc/routes/v1/site.go": "gin_mirc_routes_site_v1.tmpl", + "mirc/routes/v2/site.go": "gin_mirc_routes_site_v2.tmpl", + }, +} diff --git a/mirc/cmd/templates/README.md b/mirc/cmd/templates/README.md new file mode 100644 index 0000000..dd572e3 --- /dev/null +++ b/mirc/cmd/templates/README.md @@ -0,0 +1 @@ +## template files for generate a example project \ No newline at end of file diff --git a/mirc/cmd/templates/gin_go_mod.tmpl b/mirc/cmd/templates/gin_go_mod.tmpl new file mode 100644 index 0000000..ca50bdd --- /dev/null +++ b/mirc/cmd/templates/gin_go_mod.tmpl @@ -0,0 +1,8 @@ +module github.com/alimy/mir-examples + +go 1.12 + +require ( + github.com/gin-gonic/gin v1.4.0 + github.com/alimy/mir/v2 v2.0.0 +) \ No newline at end of file diff --git a/mirc/cmd/templates/gin_main.tmpl b/mirc/cmd/templates/gin_main.tmpl new file mode 100644 index 0000000..5458493 --- /dev/null +++ b/mirc/cmd/templates/gin_main.tmpl @@ -0,0 +1,27 @@ +package main + +import ( + "log" + + "github.com/gin-gonic/gin" + + "github.com/alimy/mir-examples/mirc/gen/api" + "github.com/alimy/mir-examples/mirc/gen/api/v1" + "github.com/alimy/mir-examples/mirc/gen/api/v2" +) + +func main() { + e := gin.New() + + // register servants to engine + registerServants(e) + + // start servant service + if err := e.Run(); err != nil { + log.Fatal(err) + } +} + +func registerServants(e *gin.Engine) { + // TODO: register routes to *gin.Engine +} \ No newline at end of file diff --git a/mirc/cmd/templates/gin_mirc_main.tmpl b/mirc/cmd/templates/gin_mirc_main.tmpl new file mode 100644 index 0000000..ed4cfed --- /dev/null +++ b/mirc/cmd/templates/gin_mirc_main.tmpl @@ -0,0 +1,29 @@ +package main + +import ( + "log" + + "github.com/gin-gonic/gin" + + "github.com/alimy/mir/v2/core" + "github.com/alimy/mir/v2/engine" + "github.com/alimy/mir-examples/mirc/routes" + "github.com/alimy/mir-examples/mirc/routes/v1" + "github.com/alimy/mir-examples/mirc/routes/v2" +) + +//go:generate go run main.go +func main() { + log.Println("generate code start") + entries := mirEntries() + engine.Generate(entries, &core.GenOpts{Name: core.GeneratorGin, OutPath: "./gen"}) + log.Println("generate code finish") +} + +func mirEntries() []interface{} { + return []interface{}{ + &routes.Site{Chain: gin.HandlersChain{gin.Logger()}}, + &v1.Site{Chain: gin.HandlersChain{gin.Logger()}}, + &v2.Site{Chain: gin.HandlersChain{gin.Logger()}}, + } +} \ No newline at end of file diff --git a/mirc/cmd/templates/gin_mirc_routes_site.tmpl b/mirc/cmd/templates/gin_mirc_routes_site.tmpl new file mode 100644 index 0000000..c575ae5 --- /dev/null +++ b/mirc/cmd/templates/gin_mirc_routes_site.tmpl @@ -0,0 +1,12 @@ +package routes + +import ( + mir "github.com/alimy/mir/v2" +) + +// Site mir's struct tag define +type Site struct { + Chain mir.Chain `mir:"-"` + Index mir.Get `mir:"/index/"` + Articles mir.Get `mir:"/articles/:category/"` +} \ No newline at end of file diff --git a/mirc/cmd/templates/gin_mirc_routes_site_v1.tmpl b/mirc/cmd/templates/gin_mirc_routes_site_v1.tmpl new file mode 100644 index 0000000..f8ea7b9 --- /dev/null +++ b/mirc/cmd/templates/gin_mirc_routes_site_v1.tmpl @@ -0,0 +1,13 @@ +package v1 + +import ( + mir "github.com/alimy/mir/v2" +) + +// Site mir's struct tag define +type Site struct { + Chain mir.Chain `mir:"-"` + Group mir.Group `mir:"v1"` + Index mir.Get `mir:"/index/"` + Articles mir.Get `mir:"/articles/:category/"` +} \ No newline at end of file diff --git a/mirc/cmd/templates/gin_mirc_routes_site_v2.tmpl b/mirc/cmd/templates/gin_mirc_routes_site_v2.tmpl new file mode 100644 index 0000000..84a6fe1 --- /dev/null +++ b/mirc/cmd/templates/gin_mirc_routes_site_v2.tmpl @@ -0,0 +1,14 @@ +package v2 + +import ( + mir "github.com/alimy/mir/v2" +) + +// Site mir's struct tag define +type Site struct { + Chain mir.Chain `mir:"-"` + Group mir.Group `mir:"v2"` + Index mir.Get `mir:"/index/"` + Articles mir.Get `mir:"/articles/:category/"` + Category mir.Get `mir:"/category/"` +} diff --git a/mirc/cmd/templates/makefile.tmpl b/mirc/cmd/templates/makefile.tmpl new file mode 100644 index 0000000..742988d --- /dev/null +++ b/mirc/cmd/templates/makefile.tmpl @@ -0,0 +1,15 @@ +GOFMT ?= gofmt -s -w +GOFILES := $(shell find . -name "*.go" -type f) + +.PHONY: build +build: fmt + go build . + +.PHONY: generate +generate: + -rm -rf mirc/gen + go generate mirc/main.go + +.PHONY: fmt +fmt: + $(GOFMT) $(GOFILES) diff --git a/mirc/cmd/templates/readme.tmpl b/mirc/cmd/templates/readme.tmpl new file mode 100644 index 0000000..b530593 --- /dev/null +++ b/mirc/cmd/templates/readme.tmpl @@ -0,0 +1,8 @@ +## mir-examples +just a simple mir's examples for explain how to use mir in your project. + +#### Usage +```bash +% make generate +% make build +``` \ No newline at end of file diff --git a/mirc/cmd/templates_gen.go b/mirc/cmd/templates_gen.go new file mode 100644 index 0000000..7ac819c --- /dev/null +++ b/mirc/cmd/templates_gen.go @@ -0,0 +1,433 @@ +// Code generated by go-bindata. DO NOT EDIT. +// sources: +// templates/gin_go_mod.tmpl (129B) +// templates/gin_main.tmpl (497B) +// templates/gin_mirc_main.tmpl (776B) +// templates/gin_mirc_routes_site.tmpl (238B) +// templates/gin_mirc_routes_site_v1.tmpl (268B) +// templates/gin_mirc_routes_site_v2.tmpl (311B) +// templates/makefile.tmpl (218B) +// templates/readme.tmpl (141B) + +package cmd + +import ( + "bytes" + "compress/gzip" + "crypto/sha256" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data, name string) ([]byte, error) { + gz, err := gzip.NewReader(strings.NewReader(data)) + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + + clErr := gz.Close() + if clErr != nil { + return nil, clErr + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo + digest [sha256.Size]byte +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _gin_go_modTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8c\x3b\x0e\x02\x31\x0c\x05\x7b\x9f\xe2\x95\x50\xac\xf3\x11\x17\x5a\x16\x2b\x58\x8a\x63\x08\x24\x82\xdb\x23\x1a\x84\xb6\x9b\x62\x66\xcc\x2f\xa3\x0a\x8a\x3e\xaf\xe3\xcc\x9b\x5b\x58\xab\xda\x3b\x98\xf6\x45\x5e\xab\xdd\xaa\x3c\x88\x8a\x23\x71\xca\x44\x5d\xee\x43\xbb\xe0\x40\x00\xfe\xab\xa2\x6d\x29\xde\x74\xfb\x12\x66\xe2\x13\xc7\xbd\xf3\x3b\x87\x99\x31\x33\x47\x8e\x74\xfc\x04\x00\x00\xff\xff\x2f\xa5\xe1\x57\x81\x00\x00\x00" + +func gin_go_modTmplBytes() ([]byte, error) { + return bindataRead( + _gin_go_modTmpl, + "gin_go_mod.tmpl", + ) +} + +func gin_go_modTmpl() (*asset, error) { + bytes, err := gin_go_modTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_go_mod.tmpl", size: 129, mode: os.FileMode(0644), modTime: time.Unix(1582798761, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6d, 0x60, 0x56, 0x3e, 0x8d, 0x7b, 0x39, 0x6b, 0x82, 0xe9, 0x24, 0x98, 0x94, 0x1a, 0xfd, 0xfa, 0xf1, 0x56, 0xa9, 0xb3, 0x3e, 0xea, 0x6b, 0x8d, 0x71, 0x76, 0xde, 0xc9, 0x7f, 0x49, 0x3, 0xd}} + return a, nil +} + +var _gin_mainTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x8f\xc1\x4e\xc3\x30\x0c\x86\xef\x79\x0a\xd3\x53\x8a\xb4\x46\x70\x1c\xda\x0d\x38\x32\x09\x78\x81\x10\x79\xc1\x22\x71\x2a\x37\x1d\x20\xd4\x77\x47\x49\x5b\x0d\x09\x2e\x2c\x97\xd8\xf9\xfd\xc7\xff\xd7\x5b\xf7\x66\x3d\x42\xb4\xc4\x4a\x51\xec\x93\x64\xd0\x0a\x00\xa0\x09\xc9\x37\x6a\x2e\x3d\xe5\xd7\xf1\xa5\x73\x29\x1a\x4f\xbc\xf1\x89\xc9\x95\xea\x0f\xdd\x06\x8a\x9f\x26\x92\x6c\xf0\xc3\xc6\x3e\xe0\x50\x1a\x67\x3c\xb2\xb1\x3d\x35\xff\x35\x98\xe3\xd5\x19\x9e\xeb\x46\xb5\x4a\x1d\x46\x76\x15\x4d\xb7\xf0\x55\x3f\x41\xd8\xee\xc0\x13\x77\x0f\xf8\xae\xdb\x39\xbd\x31\x20\xe8\x69\xc8\x28\x30\xa0\x1c\x2d\xe7\x01\x72\x02\x64\x4f\x8c\x75\x64\xd5\x9f\x16\x59\xe3\xc9\x3b\x64\x2b\x79\x35\xd6\x9b\xdc\xec\xa2\x03\xa0\x48\xd9\x88\xdd\xe3\xc8\xba\xbd\xa9\xfd\xc5\x0e\x98\xc2\x12\xa8\x9c\x90\x7c\x77\x6f\xb3\x0d\x1a\x45\xda\xfa\x3c\xa9\x69\x89\xff\x7b\x35\x5c\x16\x80\xbb\x9a\x6e\xe5\x32\x06\x9e\xf7\xb7\xfb\xed\x89\x44\xd2\x98\xb1\x72\xfc\x18\x57\xd3\x77\x00\x00\x00\xff\xff\x2c\x92\x48\x8a\xf1\x01\x00\x00" + +func gin_mainTmplBytes() ([]byte, error) { + return bindataRead( + _gin_mainTmpl, + "gin_main.tmpl", + ) +} + +func gin_mainTmpl() (*asset, error) { + bytes, err := gin_mainTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_main.tmpl", size: 497, mode: os.FileMode(0644), modTime: time.Unix(1582797820, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xed, 0xf2, 0xec, 0xec, 0x44, 0xaf, 0x20, 0xff, 0x2d, 0x24, 0x2d, 0x5b, 0x2b, 0x5b, 0x34, 0xcc, 0xd5, 0x5, 0x38, 0x8, 0x83, 0xbf, 0x26, 0x5b, 0x11, 0xf4, 0x9a, 0x4e, 0x1f, 0x33, 0xfe, 0x9}} + return a, nil +} + +var _gin_mirc_mainTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x50\xbd\x0a\xdb\x30\x10\xde\xf5\x14\x87\x86\x60\x43\x62\x91\x8c\x86\x4e\xa5\xa4\x43\x69\x02\x1d\x4b\x07\x55\xb9\xc8\x47\xad\x93\x39\xcb\xa1\xc5\xf8\xdd\x8b\x6c\xa7\x3f\x50\x52\x12\x4d\xf7\xfd\xa1\xbb\xaf\xb3\xee\x9b\xf5\x08\xc1\x12\x2b\x45\xa1\x8b\x92\xa0\x50\x00\x00\xba\x8d\x5e\xab\x65\xf4\x94\x9a\xe1\x6b\xe5\x62\x30\x9e\x78\xe7\x23\x93\xcb\xd3\x3f\x74\xdb\x52\xf8\x61\x02\x89\xb9\x1d\x8c\x8b\x82\xfa\xb1\x05\xd9\x13\x3f\x32\xed\xf0\xbb\x0d\x5d\x8b\x7d\x06\xce\x48\x1c\x12\xf6\xcf\xfa\xcd\x6d\xff\x7c\xe4\xa0\x55\xa9\x94\x31\x3e\xd6\x1e\x19\xc5\x26\x04\x1f\x41\x06\x9e\xfb\xaa\x7c\x54\xd7\x81\xdd\x0c\x8a\x12\xc6\xf9\x83\x36\xfa\xea\x2c\xc4\xa9\xe5\x42\xff\x8a\xb9\x78\x41\xe8\x93\x95\xa4\xcb\xd9\x86\x9c\x84\xb0\x87\xfa\x0d\x04\x92\x77\x0b\x2a\xee\x5a\xae\xa4\x3a\xae\xe1\x62\xf5\x6e\x61\x93\xfb\xcc\xfc\xa9\x4b\xfd\xf8\xd1\x06\xac\xe1\x4e\x65\x6b\x94\x23\xf1\x16\x4e\x43\x3a\xdb\xd4\xd4\xa0\x2b\xe3\x91\xf5\x54\xfe\x6f\xb3\x2b\x31\xf5\x8d\x2e\xd5\xa4\xd6\x93\xfe\xd8\x09\x3e\x7f\x21\x4e\x28\x57\xeb\x70\x9c\xd6\x33\x05\xd3\x20\xfc\xb7\xb4\x28\xf9\x6d\x96\x0a\xab\x4f\x94\x70\x7c\xdb\x58\xe2\x1a\x3c\x71\xf5\xde\xf2\xa5\x45\xe9\x67\x6a\xcc\xcc\x87\xe8\x3d\x4a\x51\x4e\xd3\xf6\x77\xfa\xb6\x7f\x39\x79\x78\x21\x39\xa9\xe9\x67\x00\x00\x00\xff\xff\x7e\x8b\x5b\x35\x08\x03\x00\x00" + +func gin_mirc_mainTmplBytes() ([]byte, error) { + return bindataRead( + _gin_mirc_mainTmpl, + "gin_mirc_main.tmpl", + ) +} + +func gin_mirc_mainTmpl() (*asset, error) { + bytes, err := gin_mirc_mainTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_mirc_main.tmpl", size: 776, mode: os.FileMode(0644), modTime: time.Unix(1582788776, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc1, 0x95, 0x9e, 0x3a, 0x50, 0xba, 0x71, 0xd8, 0xc8, 0x24, 0x4f, 0xac, 0x32, 0xc3, 0x2c, 0x56, 0x45, 0x7, 0x7, 0x59, 0x13, 0xa, 0x7f, 0x4a, 0xd7, 0x1b, 0x27, 0xd0, 0xa1, 0x1d, 0x5e, 0x5c}} + return a, nil +} + +var _gin_mirc_routes_siteTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\xcd\xb1\x8e\xc2\x30\x0c\x80\xe1\x3d\x4f\x61\x65\xb9\xbb\xe1\x6a\x89\xb1\x1b\x62\x40\xcc\xbc\x40\x43\x6a\x52\x8b\xa6\xa9\x1c\x17\x51\x21\xde\x1d\xb5\x0d\x13\xa3\xf5\x7f\xb6\x47\xe7\x6f\x2e\x10\x48\x9a\x94\xb2\x31\x1c\xc7\x24\x0a\xbf\x06\x00\x20\xb2\x80\x0d\xac\xdd\x74\xa9\x7c\x8a\xe8\x7a\x8e\x33\x46\x16\xbc\xef\xac\xf9\x33\x06\x11\xce\xac\xb4\xc0\x9f\x0c\x59\x65\xf2\x0a\xea\x02\xb4\x74\xe5\x81\x8c\xce\x23\x6d\xa2\xb4\xe7\x7a\xf7\xd0\x39\x1e\xca\x83\x6a\x1b\x9a\xc8\x52\xdb\x7f\xdb\xac\xe0\x34\xb4\xf4\xf8\x80\x23\x29\x40\x01\xc8\x4b\xc1\xc2\xf6\xa2\xec\x7b\xca\xdf\xcc\x95\x82\xb5\x77\x4a\x21\xc9\xbc\xec\xbc\xde\x01\x00\x00\xff\xff\x70\x65\x95\x92\xee\x00\x00\x00" + +func gin_mirc_routes_siteTmplBytes() ([]byte, error) { + return bindataRead( + _gin_mirc_routes_siteTmpl, + "gin_mirc_routes_site.tmpl", + ) +} + +func gin_mirc_routes_siteTmpl() (*asset, error) { + bytes, err := gin_mirc_routes_siteTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_mirc_routes_site.tmpl", size: 238, mode: os.FileMode(0644), modTime: time.Unix(1582788776, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x97, 0x78, 0xd2, 0x66, 0x82, 0xef, 0x79, 0x34, 0xf6, 0xcc, 0x4b, 0xa0, 0x17, 0x1c, 0x2c, 0x2c, 0x1b, 0x64, 0x8a, 0x3c, 0x92, 0x3e, 0x8f, 0x8c, 0x30, 0x93, 0x3b, 0x72, 0xc5, 0x91, 0x81, 0x6b}} + return a, nil +} + +var _gin_mirc_routes_site_v1Tmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\xcd\xb1\x4e\xc4\x30\x0c\xc6\xf1\x3d\x4f\x61\x65\x01\x06\x6a\x95\xb1\x1b\x62\x40\xcc\xbc\x40\x43\x6a\x52\x8b\xa6\x89\x5c\xb7\xa2\x42\xbc\xfb\xa9\x4d\xee\x96\x1b\x3f\xfd\x7f\x89\xb3\xf3\x3f\x2e\x10\x6c\xad\x31\x1c\x73\x12\x85\x47\x03\x00\x10\x59\xc0\x06\xd6\x71\xfd\x6a\x7c\x8a\xe8\x26\x8e\x3b\x46\x16\xdc\x5e\xac\x79\x32\x06\x11\x3e\x59\xe9\x80\x0f\x0b\x2c\x2a\xab\x57\x50\x17\x60\xa0\x6f\x9e\xc9\xe8\x9e\xa9\x88\xda\xfe\xce\x7f\xdf\x46\xc7\x73\x3d\xd0\x94\xd1\x47\x96\xce\x3e\xdb\xfe\x04\xef\x92\xd6\x7c\x05\x65\x14\xb0\xb5\x55\x7c\xcc\x03\xfd\xde\x04\x29\x40\x15\xc8\x47\xc1\xca\x5e\x45\xd9\x4f\xb4\xdc\x33\x57\x0b\x76\xde\x29\x85\x24\xfb\xf1\xe6\xff\x12\x00\x00\xff\xff\xe6\xe7\xea\xf7\x0c\x01\x00\x00" + +func gin_mirc_routes_site_v1TmplBytes() ([]byte, error) { + return bindataRead( + _gin_mirc_routes_site_v1Tmpl, + "gin_mirc_routes_site_v1.tmpl", + ) +} + +func gin_mirc_routes_site_v1Tmpl() (*asset, error) { + bytes, err := gin_mirc_routes_site_v1TmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_mirc_routes_site_v1.tmpl", size: 268, mode: os.FileMode(0644), modTime: time.Unix(1582788776, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1d, 0xb8, 0x80, 0x3f, 0x7d, 0x23, 0xdc, 0x3a, 0x6e, 0x88, 0x33, 0x44, 0x5, 0xb4, 0x81, 0x92, 0x5d, 0x1d, 0x4d, 0xc2, 0xb0, 0x8d, 0x2, 0xb6, 0xe6, 0xff, 0x2a, 0x6c, 0xc8, 0x7b, 0x5b, 0x94}} + return a, nil +} + +var _gin_mirc_routes_site_v2Tmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\xcd\xb1\x4e\xc4\x30\x0c\x06\xe0\xdd\x4f\x61\x65\x01\x06\xce\x52\xc7\xdb\xd0\x0d\x88\x99\x17\xb8\x90\x33\x39\x8b\x4b\x13\xb9\x6e\x45\x85\x78\x77\xd4\x26\x45\x27\x75\xfc\xf5\x7f\xbf\x5d\x7c\xf8\xf2\x91\x71\xea\x00\x24\x95\xac\x86\x8f\x80\x88\x98\x44\xd1\x45\xb1\xeb\xf8\x71\x08\x39\x91\xbf\x49\x9a\x29\x89\xd2\xd4\x39\x78\x02\x20\xc2\x77\x31\x5e\xe0\xc3\x80\x83\xe9\x18\x0c\xcd\x47\xbc\xf0\xa7\xf4\x0c\x36\x17\xae\xa2\x75\x3f\xeb\xdd\xd3\xd5\x4b\xdf\x1e\x1c\x6a\x38\x27\xd1\xa3\x7b\x76\xe7\x15\xbc\x6a\x1e\xcb\x06\x6a\xa8\x60\xea\x9a\x78\xeb\x2f\xfc\xfd\x2f\xd8\x10\x9b\x20\x59\x1a\x6a\xec\x45\x4d\xc2\x8d\x87\x3d\xf3\xad\xa1\x63\xf0\xc6\x31\xeb\xbc\x6d\x4e\x2d\xef\x37\xf7\xf2\x17\xfe\x02\x00\x00\xff\xff\x60\x81\x5c\x84\x37\x01\x00\x00" + +func gin_mirc_routes_site_v2TmplBytes() ([]byte, error) { + return bindataRead( + _gin_mirc_routes_site_v2Tmpl, + "gin_mirc_routes_site_v2.tmpl", + ) +} + +func gin_mirc_routes_site_v2Tmpl() (*asset, error) { + bytes, err := gin_mirc_routes_site_v2TmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "gin_mirc_routes_site_v2.tmpl", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1582788776, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x54, 0x4d, 0xc8, 0x75, 0x54, 0x7a, 0xc1, 0x51, 0x62, 0x7c, 0x53, 0xdd, 0xf4, 0x36, 0x67, 0xa8, 0xf, 0xd9, 0xb8, 0x73, 0x25, 0xef, 0x29, 0x4c, 0x7f, 0x5a, 0xd4, 0xb2, 0x7f, 0x0, 0x2a, 0x48}} + return a, nil +} + +var _makefileTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x44\x8f\xcd\x8a\x83\x30\x14\x46\xd7\xde\xa7\xf8\x10\x17\x3a\x90\xcc\x3e\x20\xb3\x1a\x9d\x81\xb6\x16\xda\x4d\x97\xb6\x26\x69\xc0\x24\x25\xa6\x94\xbe\x7d\x31\x22\x6e\x2e\x87\x73\xff\xdb\xae\xd9\x9f\xf1\x53\x43\x7b\x65\x23\xd8\x04\xf6\xa2\xb6\x6b\xfe\x77\xbf\x27\x88\x1a\x45\x39\xdd\xe5\x38\x42\x19\x37\x80\x83\xb9\xde\x4a\xe4\x5f\x5c\xfb\x1c\x2c\xbe\x1f\x12\xaa\x22\xe2\xc7\xbf\xee\x70\x11\xb8\x3e\xcd\x38\x50\x8a\x02\xca\x46\xca\xb4\x5f\x24\xf8\x56\xa5\xa5\x93\xa1\x8f\x92\x56\x10\x94\xb1\x60\xc1\x82\x82\x35\xe1\xf6\xad\xa5\x4b\x9d\x6b\x7e\xb1\xb6\x37\x8e\x6b\xbf\xcd\x99\x17\x28\x1b\x05\x65\x45\x99\xfe\xa8\x90\x60\xbe\xbd\xa2\x4f\x00\x00\x00\xff\xff\xbf\x2a\x49\x7b\xda\x00\x00\x00" + +func makefileTmplBytes() ([]byte, error) { + return bindataRead( + _makefileTmpl, + "makefile.tmpl", + ) +} + +func makefileTmpl() (*asset, error) { + bytes, err := makefileTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "makefile.tmpl", size: 218, mode: os.FileMode(0644), modTime: time.Unix(1582798290, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa0, 0x28, 0xd7, 0x24, 0x95, 0x27, 0x95, 0x47, 0xd, 0x62, 0x93, 0x69, 0xa2, 0x9c, 0x6c, 0x96, 0x6a, 0x20, 0x13, 0xde, 0x26, 0x3c, 0x83, 0x22, 0x64, 0x88, 0x18, 0xaa, 0x84, 0x24, 0xae, 0xa2}} + return a, nil +} + +var _readmeTmpl = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\xca\x41\x8e\xc2\x30\x0c\x46\xe1\x7d\x4e\xf1\x4b\xd6\x68\x56\x70\x1b\xf6\x71\xc1\xb4\x29\x49\x1c\xd9\x89\x28\xb7\x47\x41\xea\xf2\xe9\x7d\x44\x28\xc9\x2e\x72\x70\x69\x59\x3c\xec\xc3\x3b\x18\x9e\x66\xce\xf5\xef\x38\x27\x9e\x6a\x90\xa3\x65\x4e\x15\x9b\xbe\xd1\x15\xc3\x7f\x0a\xa9\xe2\xa3\xc3\xd0\x4c\x77\xb9\xf7\x6b\x08\x44\x44\xb8\x39\xaf\x12\x62\x8c\x0b\xfb\x16\xfe\x50\xf8\x25\x58\xa5\x8a\x71\x97\xb3\x97\x91\xf2\x63\xa2\x6f\x00\x00\x00\xff\xff\xe6\xd9\x54\xfa\x8d\x00\x00\x00" + +func readmeTmplBytes() ([]byte, error) { + return bindataRead( + _readmeTmpl, + "readme.tmpl", + ) +} + +func readmeTmpl() (*asset, error) { + bytes, err := readmeTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "readme.tmpl", size: 141, mode: os.FileMode(0644), modTime: time.Unix(1582788776, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2e, 0x7a, 0x6, 0x3f, 0x8d, 0x29, 0x52, 0xb7, 0x7, 0x87, 0xae, 0x68, 0x3f, 0x5f, 0xa, 0xda, 0x30, 0x80, 0x59, 0x33, 0xe6, 0xb9, 0xea, 0xc8, 0xdc, 0xef, 0x8, 0x50, 0x4b, 0x4e, 0xb5, 0xcf}} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetString returns the asset contents as a string (instead of a []byte). +func AssetString(name string) (string, error) { + data, err := Asset(name) + return string(data), err +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// MustAssetString is like AssetString but panics when Asset would return an +// error. It simplifies safe initialization of global variables. +func MustAssetString(name string) string { + return string(MustAsset(name)) +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetDigest returns the digest of the file with the given name. It returns an +// error if the asset could not be found or the digest could not be loaded. +func AssetDigest(name string) ([sha256.Size]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) + } + return a.digest, nil + } + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) +} + +// Digests returns a map of all known files and their checksums. +func Digests() (map[string][sha256.Size]byte, error) { + mp := make(map[string][sha256.Size]byte, len(_bindata)) + for name := range _bindata { + a, err := _bindata[name]() + if err != nil { + return nil, err + } + mp[name] = a.digest + } + return mp, nil +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "gin_go_mod.tmpl": gin_go_modTmpl, + "gin_main.tmpl": gin_mainTmpl, + "gin_mirc_main.tmpl": gin_mirc_mainTmpl, + "gin_mirc_routes_site.tmpl": gin_mirc_routes_siteTmpl, + "gin_mirc_routes_site_v1.tmpl": gin_mirc_routes_site_v1Tmpl, + "gin_mirc_routes_site_v2.tmpl": gin_mirc_routes_site_v2Tmpl, + "makefile.tmpl": makefileTmpl, + "readme.tmpl": readmeTmpl, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"}, +// AssetDir("data/img") would return []string{"a.png", "b.png"}, +// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "gin_go_mod.tmpl": {gin_go_modTmpl, map[string]*bintree{}}, + "gin_main.tmpl": {gin_mainTmpl, map[string]*bintree{}}, + "gin_mirc_main.tmpl": {gin_mirc_mainTmpl, map[string]*bintree{}}, + "gin_mirc_routes_site.tmpl": {gin_mirc_routes_siteTmpl, map[string]*bintree{}}, + "gin_mirc_routes_site_v1.tmpl": {gin_mirc_routes_site_v1Tmpl, map[string]*bintree{}}, + "gin_mirc_routes_site_v2.tmpl": {gin_mirc_routes_site_v2Tmpl, map[string]*bintree{}}, + "makefile.tmpl": {makefileTmpl, map[string]*bintree{}}, + "readme.tmpl": {readmeTmpl, map[string]*bintree{}}, +}} + +// RestoreAsset restores an asset under the given directory. +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) +} + +// RestoreAssets restores an asset under the given directory recursively. +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) +} diff --git a/mirc/cmd/version.go b/mirc/cmd/version.go new file mode 100644 index 0000000..6f9ffcc --- /dev/null +++ b/mirc/cmd/version.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "fmt" + + "github.com/alimy/mir/mirc/v2/version" + "github.com/spf13/cobra" +) + +func init() { + versionCmd := &cobra.Command{ + Use: "version", + Short: "show version information", + Long: "show version information", + Run: versionRun, + } + register(versionCmd) +} + +func versionRun(_cmd *cobra.Command, _args []string) { + fmt.Printf("v%s\nBuildTime:%s\nBuildGitSHA:%s\n", + version.MircVer, version.BuildTime, version.GitHash) +} diff --git a/mirc/go.mod b/mirc/go.mod new file mode 100644 index 0000000..99936de --- /dev/null +++ b/mirc/go.mod @@ -0,0 +1,8 @@ +module github.com/alimy/mir/mirc/v2 + +go 1.12 + +require ( + github.com/spf13/cobra v0.0.6 + github.com/coreos/go-semver v0.3.0 +) \ No newline at end of file diff --git a/mirc/go.sum b/mirc/go.sum new file mode 100644 index 0000000..bf5c6fc --- /dev/null +++ b/mirc/go.sum @@ -0,0 +1,125 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/mirc/main.go b/mirc/main.go new file mode 100644 index 0000000..6f24ab9 --- /dev/null +++ b/mirc/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/alimy/mir/mirc/v2/cmd" +) + +func main() { + // setup root cli command of application + cmd.Setup( + "mir", // command name + "mir help toolkit", // command short describe + "mir help tookit", // command long describe + ) + + // execute start application + cmd.Execute() +} \ No newline at end of file diff --git a/mirc/version/version.go b/mirc/version/version.go new file mode 100644 index 0000000..7864fbe --- /dev/null +++ b/mirc/version/version.go @@ -0,0 +1,17 @@ +package version + +import "github.com/coreos/go-semver/semver" + +var ( + // GitHash Value will be set during build + GitHash = "Not provided" + // BuildTime Value will be set during build + BuildTime = "Not provided" +) + +// MircVer version of Mirc +var MircVer = semver.Version{ + Major: 0, + Minor: 1, + Patch: 0, +} diff --git a/module/README.md b/module/README.md deleted file mode 100644 index b3c0e4b..0000000 --- a/module/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Submodules of Mir - -* [Mir.Gin](gin): Provide mir.Engine implement backend by [Gin](https://github.com/gin-gonic/gin). -* [Mir.Chi](chi): Provide mir.Engine implement backend by [Chi](https://github.com/go-chi/chi). -* [Mir.Echo](echo): Provide mir.Engine implement backend by [Echo](https://github.com/labstack/echo). -* [Mir.Iris](iris): Provide mir.Engine implement backend by [Iris](https://github.com/kataras/iris). -* [Mir.Macaron](macaron): Provide mir.Engine implement backend by [Macaron](https://github.com/go-macaron/macaron). -* [Mir.Mux](mux): Provide mir.Engine implement backend by [Mux](https://github.com/gorilla/mux). -* [Mir.httprouter](httprouter): Provide mir.Engine implement backend by [httprouter](github.com/julienschmidt/httprouter). -* [Mir.Example](example): Simple code explain how to use Mir. diff --git a/module/chi/README.md b/module/chi/README.md deleted file mode 100644 index cba60a8..0000000 --- a/module/chi/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# Mir.Chi -Mir.Chi module provide mir.Engine implement backend by [Chi](https://github.com/go-chi/chi). - -### Usage -```go -package main - -import( - "github.com/alimy/mir" - "github.com/go-chi/chi" - "log" - "net/http" - - mirE "github.com/alimy/mir/module/chi" -) - -type site struct { - count uint32 - - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/{category}/{id:[0-9]+}#GetArticles"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(rw http.ResponseWriter, r *http.Request) { - h.count++ - rw.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/{category}/{id:[0-9]+}/ -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles). -// if no handler info will use field name capital first char as default handler name(eg: if articles had -// no #GetArticles then the handler name will is Articles) -func (h *site) GetArticles(rw http.ResponseWriter, r *http.Request) { - rw.Write([]byte("GetArticles")) -} - -func main() { - // Create a new mux router instance - r := chi.NewRouter() - - // Instance a mir engine to register handler for mux router by mir - mirE.Register(r, &site{}) - - // Bind to a port and pass our router in - log.Fatal(http.ListenAndServe(":8013", r)) -} - -``` \ No newline at end of file diff --git a/module/chi/chi.go b/module/chi/chi.go deleted file mode 100644 index c462bba..0000000 --- a/module/chi/chi.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package chi - -import ( - "github.com/alimy/mir" - "github.com/go-chi/chi" -) - -// Mir return mir.Engine interface implements instance. -// Used to register routes to Chi router with struct tag string's information. -func Mir(r chi.Router) mir.Engine { - return &mirEngine{engine: r} -} - -// Register use entries's info to register handler to Chi router. -func Register(r chi.Router, entries ...interface{}) error { - mirE := Mir(r) - return mir.Register(mirE, entries...) -} diff --git a/module/chi/chi_suite_test.go b/module/chi/chi_suite_test.go deleted file mode 100644 index 71a73c8..0000000 --- a/module/chi/chi_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package chi_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestMux(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Chi Suite") -} diff --git a/module/chi/chi_test.go b/module/chi/chi_test.go deleted file mode 100644 index 3137081..0000000 --- a/module/chi/chi_test.go +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package chi_test - -import ( - "bytes" - - "github.com/alimy/mir" - "github.com/go-chi/chi" - "net/http/httptest" - - . "github.com/alimy/mir/module/chi" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Core", func() { - var ( - router chi.Router - w *httptest.ResponseRecorder - err error - ) - - JustBeforeEach(func() { - w = httptest.NewRecorder() - }) - - Context("check Mir function", func() { - BeforeEach(func() { - router = chi.NewRouter() - mirE := Mir(router) - err = mir.Register(mirE, &entry{Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/10086", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang:10086")) - }) - - It("handle chain func1", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/chainfunc1", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("ChainFunc1")) - }) - - It("handle chain func2", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/chainfunc2", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetChainFunc2")) - }) - }) - - Context("check Register function", func() { - BeforeEach(func() { - router = chi.NewRouter() - err = Register(router, &entry{Group: "/v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/10086", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang:10086")) - }) - - It("handle chain func1", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/chainfunc1", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("ChainFunc1")) - }) - - It("handle chain func2", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/chainfunc2", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetChainFunc2")) - }) - }) - - Context("check Register entries", func() { - BeforeEach(func() { - router = chi.NewRouter() - err = Register(router, &entry{}, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle v1 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v1 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v1 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/10086", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang:10086")) - }) - - It("handle v1 chain func1", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/chainfunc1", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("ChainFunc1")) - }) - - It("handle v1 chain func2", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/chainfunc2", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetChainFunc2")) - }) - - It("handle v2 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v2 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v2 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/10086", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang:10086")) - }) - - It("handle v2 chain func1", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/chainfunc1", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("ChainFunc1")) - }) - - It("handle v2 chain func2", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/chainfunc2", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetChainFunc2")) - }) - }) -}) diff --git a/module/chi/core.go b/module/chi/core.go deleted file mode 100644 index 8706dd1..0000000 --- a/module/chi/core.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package chi - -import ( - "fmt" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/go-chi/chi" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine chi.Router -} - -// Register register entries to chi engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - var router chi.Router - if entry.Group == "" || entry.Group == "/" { - router = e.engine - } else { - pathPrefix := entry.Group - if !strings.HasPrefix(entry.Group, "/") { - pathPrefix = "/" + entry.Group - } - router = chi.NewRouter() - e.engine.Mount(pathPrefix, router) - } - if err := handlerChainTo(router, entry.Chain); err != nil { - return err - } - // Notice just return if catch a error or continue next entry register - if err := registerWith(router, entry.Fields); err != nil { - return err - } - } - return nil -} - -// registerWith register fields to give router -func registerWith(router chi.Router, fields []*mir.TagField) error { - for _, field := range fields { - fixedRouter := router - if field.ChainFunc != nil { - if chainFunc, ok := field.ChainFunc.(func() chi.Middlewares); ok { - if middlewares := chainFunc(); len(middlewares) > 0 { - fixedRouter = router.With(middlewares...) - } - } else { - return fmt.Errorf("chainFunc not func() chi.Middlewares function") - } - } - if handlerFunc, ok := field.Handler.(func(http.ResponseWriter, *http.Request)); ok { - if field.Method == mir.MethodAny { - fixedRouter.Connect(field.Path, handlerFunc) - fixedRouter.Delete(field.Path, handlerFunc) - fixedRouter.Get(field.Path, handlerFunc) - fixedRouter.Head(field.Path, handlerFunc) - fixedRouter.Options(field.Path, handlerFunc) - fixedRouter.Patch(field.Path, handlerFunc) - fixedRouter.Post(field.Path, handlerFunc) - fixedRouter.Put(field.Path, handlerFunc) - fixedRouter.Trace(field.Path, handlerFunc) - } else { - fixedRouter.MethodFunc(field.Method, field.Path, handlerFunc) - } - } else { - return fmt.Errorf("handler not func(http.ResponseWriter, *http.Request) function") - } - } - return nil -} - -// handlerChainTo setup handlers to router that grouped -func handlerChainTo(router chi.Router, chain mir.Chain) error { - // just return if empty chain - if chain == nil { - return nil - } - if middlewares, ok := chain.(chi.Middlewares); ok { - router.Use(middlewares...) - } else { - return fmt.Errorf("chain type not chi.Middlewares") - } - return nil -} diff --git a/module/chi/core_test.go b/module/chi/core_test.go deleted file mode 100644 index 7216c93..0000000 --- a/module/chi/core_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package chi_test - -import ( - "io" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/go-chi/chi" -) - -type entry struct { - count uint32 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - add mir.Post `mir:"/add/{id}/"` - index mir.Any `mir:"/index/"` - articles mir.Get `mir:"/articles/{category}/{id:[0-9]+}#GetArticles"` - chainFunc1 mir.Get `mir:"/chainfunc1#-ChainFunc"` - chainFunc2 mir.Get `mir:"/chainfunc2#GetChainFunc2&ChainFunc"` -} - -// Add handler of "/add/{id}" -func (e *entry) Add(rw http.ResponseWriter, r *http.Request) { - body, err := e.bytesFromBody(r) - if err != nil { - body = []byte("") - } - result := strings.Join([]string{ - "Add", - chi.URLParam(r, "id"), - string(body), - }, ":") - rw.WriteHeader(200) - rw.Write([]byte(result)) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(rw http.ResponseWriter, r *http.Request) { - e.count++ - rw.WriteHeader(200) - rw.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(rw http.ResponseWriter, r *http.Request) { - result := strings.Join([]string{ - "GetArticles", - chi.URLParam(r, "category"), - chi.URLParam(r, "id"), - }, ":") - rw.WriteHeader(200) - rw.Write([]byte(result)) -} - -// ChainFunc1 handler with chain func info. -func (e *entry) ChainFunc1(rw http.ResponseWriter, r *http.Request) { - rw.WriteHeader(200) - rw.Write([]byte("ChainFunc1")) -} - -// GetChainFunc2 handler with chain func info. -func (e *entry) GetChainFunc2(rw http.ResponseWriter, r *http.Request) { - rw.WriteHeader(200) - rw.Write([]byte("GetChainFunc2")) -} - -// ChainFunc return field's online middleware -func (e *entry) ChainFunc() chi.Middlewares { - return chi.Middlewares{ - simpleMiddleware, - simpleMiddleware, - } -} - -// bytesFromBody get contents from request's body -func (e *entry) bytesFromBody(r *http.Request) ([]byte, error) { - defer r.Body.Close() - - buf := [256]byte{} - result := make([]byte, 0) - if size, err := r.Body.Read(buf[:]); err == nil { - result = append(result, buf[:size]...) - } else if err != io.EOF { - return nil, err - } - return result, nil -} - -// mirChain chain used to register to engine -func mirChain() chi.Middlewares { - return chi.Middlewares{ - simpleMiddleware, - simpleMiddleware, - } -} - -func simpleMiddleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Do nothing just for test - h.ServeHTTP(w, r) - }) -} diff --git a/module/chi/doc.go b/module/chi/doc.go deleted file mode 100644 index 1fe56c0..0000000 --- a/module/chi/doc.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -/* -Package mir provider mir.Engine implement backend [Chi](https://github.com/go-chi/chi). - -Define handler in struct type like below: - - type site struct { - count uint32 - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"//localhost:8013/articles/{category}/{id:[0-9]+}#GetArticles"` - chainFunc1 mir.Get `mir:"/chainfunc1#-ChainFunc"` - chainFunc2 mir.Get `mir:"/chainfunc2#GetChainFunc2&ChainFunc"` - } - - // Index handler of the index field that in site struct, the struct tag indicate - // this handler will register to path "/index/" and method is http.MethodGet. - func (h *site) Index(rw http.ResponseWriter, r *http.Request) { - h.count++ - rw.Write([]byte("Index")) - } - - // GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. - // Path info is the second or first(if no host info) segment start with '/'(eg: /articles/{category}/{id:[0-9]+}) - // Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will - // use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will - // is Articles) - func (h *site) GetArticles(rw http.ResponseWriter, r *http.Request) { - rw.Write([]byte("GetArticles")) - } - - // ChainFunc1 handler with chain func info. - // Field online middleware info defined in field's tag string (eg: /chainfunc1#-ChainFunc) - func (e *entry) ChainFunc1(rw http.ResponseWriter, r *http.Request) { - rw.WriteHeader(200) - rw.Write([]byte("ChainFunc1")) - } - - // GetChainFunc2 handler with chain func info. - // Field online middleware info defined in field's tag string (eg: /chainfunc2#GetChainFunc2&ChainFunc) - func (e *entry) GetChainFunc2(rw http.ResponseWriter, r *http.Request) { - rw.WriteHeader(200) - rw.Write([]byte("GetChainFunc2")) - } - - // ChainFunc return field's online middleware - func (e *entry) ChainFunc() chi.Middlewares { - return chi.Middlewares{ - simpleMiddleware, - simpleMiddleware, - } - } - -Then register entry such use gin engine: - - func main() { - r := chi.NewRouter() - - // Instance a mir engine to register handler for mux router by mir - mirE := muxE.Mir(r) - mir.Register(mirE, &site{}) - - // Bind to a port and pass our router in - log.Fatal(http.ListenAndServe(":8013", r)) - } - -*/ -package chi diff --git a/module/chi/go.mod b/module/chi/go.mod deleted file mode 100644 index 191d658..0000000 --- a/module/chi/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/alimy/mir/module/chi - -go 1.11 - -require ( - github.com/alimy/mir v1.0.2 - github.com/go-chi/chi v4.0.2+incompatible - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 -) diff --git a/module/chi/go.sum b/module/chi/go.sum deleted file mode 100644 index 8d69410..0000000 --- a/module/chi/go.sum +++ /dev/null @@ -1,27 +0,0 @@ -github.com/alimy/mir v1.0.2 h1:q1jr/+iWqPQ1w3qkXt/3aAXi6npPhgtSV40udv/drRs= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs= -github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/echo/README.md b/module/echo/README.md deleted file mode 100644 index becbe98..0000000 --- a/module/echo/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# Mir.Echo -Mir.Echo module provide mir.Engine implement backend by [Echo](https://github.com/labstack/echo). - -### Usage -```go -package main - -import( - "github.com/alimy/mir" - "github.com/labstack/echo" - "github.com/labstack/echo/middleware" - "net/http" - - - mirE "github.com/alimy/mir/module/echo" -) - -type site struct { - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -type blog struct { - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - articles mir.Get `mir:"/articles/:category"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(c echo.Context) error { - return c.String(http.StatusOK, "get index data") -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/:category) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (h *site) GetArticles(c echo.Context) error { - return c.String(http.StatusOK, "get articles data") -} - -// Articles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (b *blog) Articles(c echo.Context) error { - return c.String(http.StatusOK, "get articles data") -} - -func main() { - // Create a new echo engine instance - e := echo.New() - - // Register handler to engine by mir - entries := mirEntries() - mirE.Register(e, entries...) - - // Start echo engine serve - e.Start(":8013") -} - -// get all entries to register -func mirEntries()[]interface{} { - return []interface{} { - &site{}, - &blog{ - Group: "v2", // direct custom group to v2 override default v1 in mir tag defined - Chain: []echo.MiddlewareFunc { - middleware.Logger(), - middleware.Recover(), - }}, - } -} -``` \ No newline at end of file diff --git a/module/echo/core.go b/module/echo/core.go deleted file mode 100644 index de33644..0000000 --- a/module/echo/core.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package echo - -import ( - "fmt" - - "github.com/alimy/mir" - "github.com/labstack/echo/v4" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine *echo.Echo -} - -// Register register entries to echo engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - g := e.engine.Group(entry.Group) - if err := handlerChainTo(g, entry.Chain); err != nil { - return err - } - // Notice just return if catch a error or continue next entry register - if err := registerWith(g, entry.Fields); err != nil { - return err - } - } - return nil -} - -// registerWith register fields to give router -func registerWith(g *echo.Group, fields []*mir.TagField) error { - for _, field := range fields { - if handlerFunc, ok := field.Handler.(func(echo.Context) error); ok { - if field.Method == mir.MethodAny { - g.Any(field.Path, handlerFunc) - } else { - g.Add(field.Method, field.Path, handlerFunc) - } - } else { - return fmt.Errorf("handler not function of func(echo.Context) error") - } - } - return nil -} - -// handlerChainTo setup handlers to router that grouped -func handlerChainTo(g *echo.Group, chain mir.Chain) error { - // just return if empty chain - if chain == nil { - return nil - } - if handlerChain, ok := chain.([]echo.MiddlewareFunc); ok { - g.Use(handlerChain...) - } else { - return fmt.Errorf("chain type not []echo.MiddlewareFunc") - } - return nil -} diff --git a/module/echo/core_test.go b/module/echo/core_test.go deleted file mode 100644 index 95201b4..0000000 --- a/module/echo/core_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package echo_test - -import ( - "io" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" -) - -type entry struct { - count uint64 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - add mir.Post `mir:"/add/:id/"` - index mir.Any `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Add handler of "/add/:id" -func (e *entry) Add(c echo.Context) error { - body, err := e.bytesFromBody(c.Request()) - if err != nil { - body = []byte("") - } - result := strings.Join([]string{ - "Add", - c.Param("id"), - string(body), - }, ":") - return c.String(http.StatusOK, result) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(c echo.Context) error { - e.count++ - return c.String(http.StatusOK, "Index") -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(c echo.Context) error { - return c.String(http.StatusOK, "GetArticles:"+c.Param("category")) -} - -// bytesFromBody get contents from request's body -func (e *entry) bytesFromBody(r *http.Request) ([]byte, error) { - defer r.Body.Close() - - buf := [256]byte{} - result := make([]byte, 0) - if size, err := r.Body.Read(buf[:]); err == nil { - result = append(result, buf[:size]...) - } else if err != io.EOF { - return nil, err - } - return result, nil -} - -// mirChain chain used to register to engine -func mirChain() []echo.MiddlewareFunc { - return []echo.MiddlewareFunc{ - middleware.Logger(), - middleware.Recover(), - } -} diff --git a/module/echo/echo.go b/module/echo/echo.go deleted file mode 100644 index 71c09e1..0000000 --- a/module/echo/echo.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package echo - -import ( - "github.com/alimy/mir" - "github.com/labstack/echo/v4" -) - -// Mir return mir.Engine interface implements instance.Used to register routes -// to echo engine with struct tag string's information. -func Mir(e *echo.Echo) mir.Engine { - return &mirEngine{engine: e} -} - -// Register use entries's info to register handler to echo engine. -func Register(e *echo.Echo, entries ...interface{}) error { - mirE := Mir(e) - return mir.Register(mirE, entries...) -} diff --git a/module/echo/echo_suite_test.go b/module/echo/echo_suite_test.go deleted file mode 100644 index a6e3590..0000000 --- a/module/echo/echo_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package echo_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestEcho(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Echo Suite") -} diff --git a/module/echo/echo_test.go b/module/echo/echo_test.go deleted file mode 100644 index 0c1ea49..0000000 --- a/module/echo/echo_test.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package echo_test - -import ( - "bytes" - - "github.com/alimy/mir" - "github.com/labstack/echo/v4" - "net/http/httptest" - - . "github.com/alimy/mir/module/echo" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Core", func() { - var ( - e *echo.Echo - w *httptest.ResponseRecorder - err error - ) - - JustBeforeEach(func() { - w = httptest.NewRecorder() - }) - - Context("check Mir function", func() { - BeforeEach(func() { - e = echo.New() - mirE := Mir(e) - err = mir.Register(mirE, &entry{Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(e).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register function", func() { - BeforeEach(func() { - e = echo.New() - err = Register(e, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(e).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register entries", func() { - BeforeEach(func() { - e = echo.New() - err = Register(e, &entry{}, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(e).ShouldNot(BeNil()) - }) - - It("handle v1 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v1 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v1 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - - It("handle v2 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v2 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v2 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/", nil) - e.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) -}) diff --git a/module/echo/go.mod b/module/echo/go.mod deleted file mode 100644 index 5db1d71..0000000 --- a/module/echo/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module github.com/alimy/mir/module/echo - -go 1.11 - -require ( - github.com/alimy/mir v1.0.2 - github.com/labstack/echo v3.3.10+incompatible - github.com/labstack/echo/v4 v4.1.11 - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 -) diff --git a/module/echo/go.sum b/module/echo/go.sum deleted file mode 100644 index 6caecfc..0000000 --- a/module/echo/go.sum +++ /dev/null @@ -1,55 +0,0 @@ -github.com/alimy/mir v1.0.2 h1:q1jr/+iWqPQ1w3qkXt/3aAXi6npPhgtSV40udv/drRs= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= -github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= -github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/example/README.md b/module/example/README.md deleted file mode 100644 index 2e3f0cf..0000000 --- a/module/example/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Mir.example -Mir.exameple module contains simple code explain how to use Mir. - -### Usage -```bash -$ git clone https://github.com/alimy/mir -$ cd mir/module/example -$ go run . # in browser visit http://localhost:8080/v1/index/ - -``` \ No newline at end of file diff --git a/module/example/go.mod b/module/example/go.mod deleted file mode 100644 index a855ea0..0000000 --- a/module/example/go.mod +++ /dev/null @@ -1,9 +0,0 @@ -module github.com/alimy/mir/module/example - -go 1.11 - -require ( - github.com/alimy/mir v1.0.1 - github.com/alimy/mir/module/gin v0.0.0-20191028094509-2634347ef225 - github.com/gin-gonic/gin v1.4.0 -) diff --git a/module/example/go.sum b/module/example/go.sum deleted file mode 100644 index 06e21be..0000000 --- a/module/example/go.sum +++ /dev/null @@ -1,48 +0,0 @@ -github.com/alimy/mir v1.0.1 h1:hZrwACEjeT9W5zI6kErPAxMvqMjODHaSlDl422kyK/w= -github.com/alimy/mir v1.0.1/go.mod h1:FwCzRdePweEwe1vb5FLYGy5YYokGlEnJJMkqCml9+qk= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/alimy/mir/module/gin v0.0.0-20191028094509-2634347ef225 h1:fegPBsjQeuT1/BOvt8FMlGKGdUOiONLXwUje71nda0g= -github.com/alimy/mir/module/gin v0.0.0-20191028094509-2634347ef225/go.mod h1:QlT7kcqDJobofvMGCRYmRutbktY87P0u/lAyfqce8eU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/example/main.go b/module/example/main.go deleted file mode 100644 index ce732a8..0000000 --- a/module/example/main.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package main - -import ( - "github.com/alimy/mir" - "github.com/gin-gonic/gin" - "net/http" - - mirE "github.com/alimy/mir/module/gin" -) - -type site struct { - Chain mir.Chain `mir:"-"` - v1 mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (s *site) Index(c *gin.Context) { - c.String(http.StatusOK, "Index") -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (s *site) GetArticles(c *gin.Context) { - c.String(http.StatusOK, "GetArticles:"+c.Param("category")) -} - -func main() { - e := gin.New() - - // Register handler to engine by mir - handlersChain := gin.HandlersChain{gin.Logger(), gin.Recovery()} - if err := mirE.Register(e, &site{Chain: handlersChain}); err != nil { - panic(err) - } - - // Start gin engine serve - e.Run() -} diff --git a/module/gin/README.md b/module/gin/README.md deleted file mode 100644 index e5f4de6..0000000 --- a/module/gin/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# Mir.Gin -Mir.Gin module provide mir.Engine implement backend by [Gin](https://github.com/gin-gonic/gin). - -### Usage -```go -package main - -import( - "github.com/alimy/mir" - "github.com/gin-gonic/gin" - "net/http" - - mirE "github.com/alimy/mir/module/gin" -) - -type site struct { - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -type blog struct { - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - articles mir.Get `mir:"/articles/:category"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(c *gin.Context) { - c.String(http.StatusOK, "get index data") -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/:category) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (h *site) GetArticles(c *gin.Context) { - c.String(http.StatusOK, "get articles data") -} - -// Articles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (b *blog) Articles(c *gin.Context) { - c.String(http.StatusOK, "get articles data") -} - -func main() { - // Default gin engine - engine := gin.New() - - // Register handler to engine by mir - entries := mirEntries() - mirE.Register(engine, entries...) - - // Start gin engine serve - engine.Run() -} - -// get all entries to register -func mirEntries()[]interface{} { - return []interface{} { - &site{}, - &blog{ - Group: "v2", // direct custom group to v2 override default v1 in mir tag defined - Chain: gin.HandlersChain { - gin.Logger(), - gin.Recovery(), - }}, - } -} -``` \ No newline at end of file diff --git a/module/gin/core.go b/module/gin/core.go deleted file mode 100644 index 653df4a..0000000 --- a/module/gin/core.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package gin - -import ( - "fmt" - - "github.com/alimy/mir" - "github.com/gin-gonic/gin" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine *gin.Engine -} - -// Register register entries to gin engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - var router gin.IRouter - if entry.Group == "" || entry.Group == "/" { - router = e.engine - } else { - router = e.engine.Group(entry.Group) - } - if err := handlerChainTo(router, entry.Chain); err != nil { - return err - } - // Notice just return if catch a error or continue next entry register - if err := registerWith(router, entry.Fields); err != nil { - return err - } - } - return nil -} - -// registerWith register fields to give router -func registerWith(router gin.IRouter, fields []*mir.TagField) error { - for _, field := range fields { - if handlerFunc, ok := field.Handler.(func(*gin.Context)); ok { - if field.Method == mir.MethodAny { - router.Any(field.Path, handlerFunc) - } else { - router.Handle(field.Method, field.Path, handlerFunc) - } - } else { - return fmt.Errorf("handler not func(*gin.Context) function") - } - } - return nil -} - -// handlerChainTo setup handlers to router that grouped -func handlerChainTo(router gin.IRouter, chain mir.Chain) error { - // just return if empty chain - if chain == nil { - return nil - } - if handlerChain, ok := chain.(gin.HandlersChain); ok { - router.Use(handlerChain...) - } else { - return fmt.Errorf("chain type not gin.HandlersChain") - } - return nil -} diff --git a/module/gin/core_test.go b/module/gin/core_test.go deleted file mode 100644 index 20cd896..0000000 --- a/module/gin/core_test.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package gin_test - -import ( - "io" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/gin-gonic/gin" -) - -type entry struct { - count uint64 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - add mir.Post `mir:"/add/:id/"` - index mir.Any `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Add handler of "/add/:id" -func (e *entry) Add(c *gin.Context) { - body, err := e.bytesFromBody(c.Request) - if err != nil { - body = []byte("") - } - result := strings.Join([]string{ - "Add", - c.Params.ByName("id"), - string(body), - }, ":") - c.String(http.StatusOK, result) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(c *gin.Context) { - e.count++ - c.String(http.StatusOK, "Index") -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(c *gin.Context) { - c.String(http.StatusOK, "GetArticles:"+c.Params.ByName("category")) -} - -// bytesFromBody get contents from request's body -func (e *entry) bytesFromBody(r *http.Request) ([]byte, error) { - defer r.Body.Close() - - buf := [256]byte{} - result := make([]byte, 0) - if size, err := r.Body.Read(buf[:]); err == nil { - result = append(result, buf[:size]...) - } else if err != io.EOF { - return nil, err - } - return result, nil -} - -// mirChain chain used to register to engine -func mirChain() gin.HandlersChain { - return gin.HandlersChain{ - gin.Logger(), - gin.Recovery(), - } -} diff --git a/module/gin/gin.go b/module/gin/gin.go deleted file mode 100644 index df04c28..0000000 --- a/module/gin/gin.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package gin - -import ( - "github.com/alimy/mir" - "github.com/gin-gonic/gin" -) - -// Mir return mir.Engine interface implements instance.Used to register routes -// to gin engine with struct tag string's information. -func Mir(e *gin.Engine) mir.Engine { - return &mirEngine{engine: e} -} - -// Register use entries's info to register handler to gin engine. -func Register(e *gin.Engine, entries ...interface{}) error { - mirE := Mir(e) - return mir.Register(mirE, entries...) -} diff --git a/module/gin/gin_suite_test.go b/module/gin/gin_suite_test.go deleted file mode 100644 index 4e0f0b0..0000000 --- a/module/gin/gin_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package gin_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestGin(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Gin Suite") -} diff --git a/module/gin/gin_test.go b/module/gin/gin_test.go deleted file mode 100644 index a4d1900..0000000 --- a/module/gin/gin_test.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package gin_test - -import ( - "bytes" - - "github.com/alimy/mir" - "github.com/gin-gonic/gin" - "net/http/httptest" - - . "github.com/alimy/mir/module/gin" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Core", func() { - var ( - engine *gin.Engine - w *httptest.ResponseRecorder - err error - ) - - JustBeforeEach(func() { - w = httptest.NewRecorder() - - }) - - Context("check Mir function", func() { - BeforeEach(func() { - engine = gin.New() - mirE := Mir(engine) - err = mir.Register(mirE, &entry{Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(engine).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register function", func() { - BeforeEach(func() { - engine = gin.New() - err = Register(engine, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(engine).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register entries", func() { - BeforeEach(func() { - engine = gin.New() - err = Register(engine, &entry{}, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(engine).ShouldNot(BeNil()) - }) - - It("handle v1 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v1 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v1 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - - It("handle v2 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v2 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v2 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/", nil) - engine.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) -}) diff --git a/module/gin/go.mod b/module/gin/go.mod deleted file mode 100644 index 5114ca4..0000000 --- a/module/gin/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/alimy/mir/module/gin - -go 1.11 - -require ( - github.com/alimy/mir v1.0.2 - github.com/gin-gonic/gin v1.4.0 - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 -) diff --git a/module/gin/go.sum b/module/gin/go.sum deleted file mode 100644 index 1c0d9c3..0000000 --- a/module/gin/go.sum +++ /dev/null @@ -1,50 +0,0 @@ -github.com/alimy/mir v1.0.2 h1:q1jr/+iWqPQ1w3qkXt/3aAXi6npPhgtSV40udv/drRs= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/httprouter/README.md b/module/httprouter/README.md deleted file mode 100644 index f9efefc..0000000 --- a/module/httprouter/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# Mir.httprouter -Mir.httprouter module provide mir.Engine implement backend by [httprouter](github.com/julienschmidt/httprouter). - -### Usage -```go -package main - -import( - "github.com/alimy/mir" - "github.com/julienschmidt/httprouter" - "log" - "net/http" - - mirE "github.com/alimy/mir/module/httprouter" -) - -type site struct { - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(rw http.ResponseWriter, r *http.Request, p httprouter.Params) { - rw.WriteHeader(http.StatusOK) - rw.Header().Add("Content-Type", "text/plain; charset=utf-8") - rw.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/:category) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (h *site) GetArticles(rw http.ResponseWriter, r *http.Request, p httprouter.Params) { - rw.WriteHeader(http.StatusOK) - rw.Header().Add("Content-Type", "text/plain; charset=utf-8") - rw.Write([]byte("GetArticles")) -} - -func main() { - // Create a new httprouter instance - r := httprouter.New() - - // Register handler to engine by mir - mirE.Register(r, &site{}) - - // Start http serve - log.Fatal(http.ListenAndServe(":8080", r)) -} - -``` \ No newline at end of file diff --git a/module/httprouter/core.go b/module/httprouter/core.go deleted file mode 100644 index 4004da1..0000000 --- a/module/httprouter/core.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package httprouter - -import ( - "fmt" - "net/http" - - "github.com/alimy/mir" - "github.com/julienschmidt/httprouter" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine *httprouter.Router -} - -// Register register entries to echo engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - for _, field := range entry.Fields { - if handlerFunc, ok := field.Handler.(func(http.ResponseWriter, *http.Request, httprouter.Params)); ok { - if field.Method == mir.MethodAny { - e.engine.Handle(mir.MethodGet, field.Path, handlerFunc) - e.engine.Handle(mir.MethodPut, field.Path, handlerFunc) - e.engine.Handle(mir.MethodPost, field.Path, handlerFunc) - e.engine.Handle(mir.MethodDelete, field.Path, handlerFunc) - e.engine.Handle(mir.MethodHead, field.Path, handlerFunc) - e.engine.Handle(mir.MethodPatch, field.Path, handlerFunc) - e.engine.Handle(mir.MethodOptions, field.Path, handlerFunc) - e.engine.Handle(mir.MethodConnect, field.Path, handlerFunc) - e.engine.Handle(mir.MethodTrace, field.Path, handlerFunc) - - } else { - e.engine.Handle(field.Method, field.Path, handlerFunc) - } - } else { - return fmt.Errorf("handler not function of func(http.ResponseWriter, *http.Request, httprouter.Params)") - } - } - } - return nil -} diff --git a/module/httprouter/core_test.go b/module/httprouter/core_test.go deleted file mode 100644 index 1a5aa18..0000000 --- a/module/httprouter/core_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package httprouter_test - -import ( - "io" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/julienschmidt/httprouter" -) - -type entry struct { - count uint64 - - add mir.Post `mir:"/add/:id/"` - index mir.Any `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Add handler of "/add/:id" -func (e *entry) Add(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - body, err := e.bytesFromBody(r) - if err != nil { - body = []byte("") - } - result := strings.Join([]string{ - "Add", - p.ByName("id"), - string(body), - }, ":") - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "text/plain; charset=utf-8") - w.Write([]byte(result)) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "text/plain; charset=utf-8") - w.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "text/plain; charset=utf-8") - w.Write([]byte("GetArticles:" + p.ByName("category"))) -} - -// bytesFromBody get contents from request's body -func (e *entry) bytesFromBody(r *http.Request) ([]byte, error) { - defer r.Body.Close() - - buf := [256]byte{} - result := make([]byte, 0) - if size, err := r.Body.Read(buf[:]); err == nil { - result = append(result, buf[:size]...) - } else if err != io.EOF { - return nil, err - } - return result, nil -} diff --git a/module/httprouter/go.mod b/module/httprouter/go.mod deleted file mode 100644 index ab016c1..0000000 --- a/module/httprouter/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/alimy/mir/module/httprouter - -go 1.11 - -require ( - github.com/alimy/mir v1.0.2 - github.com/julienschmidt/httprouter v1.3.0 - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 -) diff --git a/module/httprouter/go.sum b/module/httprouter/go.sum deleted file mode 100644 index 3446812..0000000 --- a/module/httprouter/go.sum +++ /dev/null @@ -1,27 +0,0 @@ -github.com/alimy/mir v1.0.2 h1:q1jr/+iWqPQ1w3qkXt/3aAXi6npPhgtSV40udv/drRs= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/httprouter/httprouter.go b/module/httprouter/httprouter.go deleted file mode 100644 index ca2d356..0000000 --- a/module/httprouter/httprouter.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package httprouter - -import ( - "github.com/alimy/mir" - "github.com/julienschmidt/httprouter" -) - -// Mir return mir.Engine interface implements instance.Used to register routes -// to httprouter with struct tag string's information. -func Mir(r *httprouter.Router) mir.Engine { - return &mirEngine{engine: r} -} - -// Register use entries's info to register handler to httprouter router. -func Register(r *httprouter.Router, entries ...interface{}) error { - mirE := Mir(r) - return mir.Register(mirE, entries...) -} diff --git a/module/httprouter/httprouter_suite_test.go b/module/httprouter/httprouter_suite_test.go deleted file mode 100644 index bca0ad0..0000000 --- a/module/httprouter/httprouter_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package httprouter_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestHttprouter(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Httprouter Suite") -} diff --git a/module/httprouter/httprouter_test.go b/module/httprouter/httprouter_test.go deleted file mode 100644 index eb075c1..0000000 --- a/module/httprouter/httprouter_test.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package httprouter_test - -import ( - "bytes" - "net/http" - "net/http/httptest" - - "github.com/alimy/mir" - "github.com/julienschmidt/httprouter" - - . "github.com/alimy/mir/module/httprouter" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Core", func() { - var ( - router *httprouter.Router - w *httptest.ResponseRecorder - err error - ) - - JustBeforeEach(func() { - w = httptest.NewRecorder() - - }) - - Context("check Mir function", func() { - BeforeEach(func() { - router = httprouter.New() - mirE := Mir(router) - err = mir.Register(mirE, &entry{}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(http.StatusOK)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(http.StatusOK)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/articles/golang/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(http.StatusOK)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register function", func() { - BeforeEach(func() { - router = httprouter.New() - err = Register(router, &entry{}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(http.StatusOK)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(http.StatusOK)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/articles/golang/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(http.StatusOK)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) -}) diff --git a/module/iris/README.md b/module/iris/README.md deleted file mode 100644 index d63f62b..0000000 --- a/module/iris/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Mir.Iris -Mir.Iris module provide mir.Engine implement backend by [Iris](https://github.com/kataras/iris). - -### Usage -```go -package main - -import( - "github.com/alimy/mir" - "github.com/kataras/iris" - "github.com/kataras/iris/context" - "github.com/kataras/iris/middleware/logger" - "github.com/kataras/iris/middleware/recover" - "net/http" - - mirE "github.com/alimy/mir/module/iris" -) - -type site struct { - count uint64 - v1 mir.Group `mir:"v1"` - add mir.Post `mir:"/add/{id:uint64}"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/{category:string}/#GetArticles"` -} - -type blog struct { - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - articles mir.Get `mir:"/articles/{name:string range(1,200) else 400}"` -} - -// Add handler of "/add/:id" -func (h *site) Add(c context.Context) { - c.Write([]byte("Add")) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(c context.Context) { - h.count++ - c.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/:category) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (h *site) GetArticles(c context.Context) { - c.Write([]byte("GetArticles")) -} - -// Articles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (b *blog) Articles(c context.Context) { - c.Write([]byte("Articles")) -} - -func main() { - // Create a new iris.Application instance - app := iris.New() - - // Register handler to engine by mir - entries := mirEntries() - mirE.Register(app, entries...) - - // Start iris application - app.Run(iris.Addr(":8013")) -} - -/// get all entries to register - func mirEntries() []interface{} { - return []interface{}{ - &site{}, - &blog{ - Group: "v2", // direct custom group to v2 override default v1 in mir tag defined - Chain: context.Handlers{ - recover.New(), - logger.New(), - }, - }, - } - } -``` \ No newline at end of file diff --git a/module/iris/core.go b/module/iris/core.go deleted file mode 100644 index aafe17f..0000000 --- a/module/iris/core.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package iris - -import ( - "fmt" - - "github.com/alimy/mir" - "github.com/kataras/iris/v12" - "github.com/kataras/iris/v12/context" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine *iris.Application -} - -// Register register entries to echo engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - var party iris.Party - if entry.Group == "" || entry.Group == "/" { - party = e.engine - } else { - party = e.engine.Party(entry.Group) - } - if err := handlerChainTo(party, entry.Chain); err != nil { - return err - } - // Notice just return if catch a error or continue next entry register - if err := registerWith(party, entry.Fields); err != nil { - return err - } - } - return nil -} - -// registerWith register fields to give router -func registerWith(party iris.Party, fields []*mir.TagField) error { - for _, field := range fields { - if handlerFunc, ok := field.Handler.(func(context.Context)); ok { - if field.Method == mir.MethodAny { - party.Any(field.Path, handlerFunc) - } else { - party.Handle(field.Method, field.Path, handlerFunc) - } - } else { - return fmt.Errorf("handler not function of func(context.Context)") - } - } - return nil -} - -// handlerChainTo setup handlers to router that grouped -func handlerChainTo(party iris.Party, chain mir.Chain) error { - // just return if empty chain - if chain == nil { - return nil - } - if handlerChain, ok := chain.(context.Handlers); ok { - party.Use(handlerChain...) - } else { - return fmt.Errorf("chain type not context.Handlers") - } - return nil -} diff --git a/module/iris/core_test.go b/module/iris/core_test.go deleted file mode 100644 index 50c9462..0000000 --- a/module/iris/core_test.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package iris_test - -import ( - "io" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/kataras/iris/v12/context" - "github.com/kataras/iris/v12/middleware/logger" - "github.com/kataras/iris/v12/middleware/recover" -) - -type entry struct { - count uint64 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - add mir.Post `mir:"/add/{id:string}"` - index mir.Any `mir:"/index"` - articles mir.Get `mir:"/articles/{category:string range(1,200) else 400}#GetArticles"` -} - -// Add handler of "/add/:id" -func (e *entry) Add(c context.Context) { - body, err := e.bytesFromBody(c.Request()) - if err != nil { - body = []byte("") - } - result := strings.Join([]string{ - "Add", - c.Params().GetString("id"), - string(body), - }, ":") - - c.StatusCode(http.StatusOK) - c.Header("Content-Type", "text/plain; charset=utf-8") - c.Write([]byte(result)) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(c context.Context) { - e.count++ - c.StatusCode(200) - c.Header("Content-Type", "text/plain; charset=utf-8") - c.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(c context.Context) { - c.StatusCode(200) - c.Header("Content-Type", "text/plain; charset=utf-8") - c.Write([]byte("GetArticles:" + c.Params().GetString("category"))) -} - -// bytesFromBody get contents from request's body -func (e *entry) bytesFromBody(r *http.Request) ([]byte, error) { - defer r.Body.Close() - - buf := [256]byte{} - result := make([]byte, 0) - if size, err := r.Body.Read(buf[:]); err == nil { - result = append(result, buf[:size]...) - } else if err != io.EOF { - return nil, err - } - return result, nil -} - -// mirChain chain used to register to engine -func mirChain() context.Handlers { - return context.Handlers{ - recover.New(), - logger.New(), - } -} diff --git a/module/iris/go.mod b/module/iris/go.mod deleted file mode 100644 index 2697ce3..0000000 --- a/module/iris/go.mod +++ /dev/null @@ -1,19 +0,0 @@ -module github.com/alimy/mir/module/iris - -go 1.13 - -require ( - github.com/ajg/form v1.5.1 // indirect - github.com/alimy/mir v1.0.2 - github.com/gavv/httpexpect v2.0.0+incompatible - github.com/google/go-querystring v1.0.0 // indirect - github.com/imkira/go-interpol v1.1.0 // indirect - github.com/kataras/iris/v12 v12.0.1 - github.com/moul/http2curl v1.0.0 // indirect - github.com/sergi/go-diff v1.0.0 // indirect - github.com/valyala/fasthttp v1.6.0 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect - github.com/yudai/gojsondiff v1.0.0 // indirect - github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect -) diff --git a/module/iris/go.sum b/module/iris/go.sum deleted file mode 100644 index f4d8c29..0000000 --- a/module/iris/go.sum +++ /dev/null @@ -1,167 +0,0 @@ -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a h1:3SgJcK9l5uPdBC/X17wanyJAMxM33+4ZhEIV96MIH8U= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible h1:rZgFj+Gtf3NMi/U5FvCvhzaxzW/TaPYgUYx3bAPz9DE= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7 h1:mreN1m/5VJ/Zc3b4pzj9qU6D9SRQ6Vm+3KfI328t3S8= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxGWFh4aMxFFC28wwGp5pEuoTtvA4q/qQ4= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/alimy/mir v1.0.2 h1:q1jr/+iWqPQ1w3qkXt/3aAXi6npPhgtSV40udv/drRs= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible h1:Ppm0npCCsmuR9oQaBtRuZcmILVE74aXE+AmrJj8L2ns= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 h1:GY1+t5Dr9OKADM64SYnQjw/w99HMYvQ0A8/JoUkxVmc= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/iris-contrib/blackfriday v2.0.0+incompatible h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+yaDA= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/kataras/golog v0.0.9 h1:J7Dl82843nbKQDrQM/abbNJZvQjS6PfmkkffhOTXEpM= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/iris/v12 v12.0.1 h1:Wo5S7GMWv5OAzJmvFTvss/C4TS1W0uo6LkDlSymT4rM= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d h1:V5Rs9ztEWdp58oayPq/ulmlqJJZeJP6pP79uP3qjcao= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0 h1:GhthINjveNZAdFUD8QoQYfjxnOONZgztK/Yr6M23UTY= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/iris/iris.go b/module/iris/iris.go deleted file mode 100644 index 4b77c45..0000000 --- a/module/iris/iris.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package iris - -import ( - "github.com/alimy/mir" - "github.com/kataras/iris/v12" -) - -// Mir return mir.Engine interface implements instance.Used to register routes -// to iris application with struct tag string's information. -func Mir(app *iris.Application) mir.Engine { - return &mirEngine{engine: app} -} - -// Register use entries's info to register handler to iris application. -func Register(app *iris.Application, entries ...interface{}) error { - mirE := Mir(app) - return mir.Register(mirE, entries...) -} diff --git a/module/iris/iris_test.go b/module/iris/iris_test.go deleted file mode 100644 index 45c25f1..0000000 --- a/module/iris/iris_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package iris_test - -import ( - "testing" - - "github.com/alimy/mir" - "github.com/gavv/httpexpect" - "github.com/kataras/iris/v12" - "github.com/kataras/iris/v12/httptest" - - . "github.com/alimy/mir/module/iris" -) - -func TestRegister(t *testing.T) { - app := iris.New() - Register(app, &entry{Chain: mirChain()}, &entry{Group: "v2"}) - expect := httptest.New(t, app, httptest.Debug(false)) - testEntry(expect) -} - -func TestMir(t *testing.T) { - app := iris.New() - mirE := Mir(app) - mir.Register(mirE, &entry{Chain: mirChain()}, &entry{Group: "v2"}) - expect := httptest.New(t, app, httptest.Debug(false)) - testEntry(expect) -} - -func testEntry(expect *httpexpect.Expect) { - for _, test := range []struct { - method string - path string - body []byte - status int - result string - }{ - { - method: mir.MethodPost, - path: "/v1/add/10086", - body: []byte("hello"), - status: httptest.StatusOK, - result: "Add:10086:hello", - }, - { - method: mir.MethodGet, - path: "/v1/index", - body: []byte(""), - status: httptest.StatusOK, - result: "Index", - }, - { - method: mir.MethodGet, - path: "/v1/articles/golang", - status: httptest.StatusOK, - result: "GetArticles:golang", - }, - { - method: mir.MethodPost, - path: "/v2/add/10086", - body: []byte("hello"), - status: httptest.StatusOK, - result: "Add:10086:hello", - }, - { - method: mir.MethodGet, - path: "/v2/index", - body: []byte(""), - status: httptest.StatusOK, - result: "Index", - }, - { - method: mir.MethodGet, - path: "/v2/articles/golang", - status: httptest.StatusOK, - result: "GetArticles:golang", - }, - } { - expect. - Request(test.method, test.path). - WithBytes(test.body). - Expect(). - Status(test.status). - Text().Equal(test.result) - } -} diff --git a/module/macaron/README.md b/module/macaron/README.md deleted file mode 100644 index 94e4046..0000000 --- a/module/macaron/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Mir.Macaron -Mir.Macaron module provide mir.Engine implement backend by [Macaron](https://github.com/go-macaron/macaron). - -### Usage -* Get module first -```bash -$ go get github.com/alimy/mir/module/macaron@master -``` - -* Then happy in your heart to codding... - -```go -package main - -import( - "github.com/alimy/mir" - "github.com/go-macaron/macaron" - "net/http" - - mirE "github.com/alimy/mir/module/macaron" -) - -type site struct { - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -type blog struct { - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - articles mir.Get `mir:"/articles/:category"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (s *site) Index(c *macaron.Context) { - c.Resp.WriteHeader(http.StatusOK) - c.Resp.Header().Add("Content-Type", "text/plain; charset=utf-8") - c.Resp.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/:category) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (s *site) GetArticles(c *macaron.Context) { - c.Resp.WriteHeader(http.StatusOK) - c.Resp.Header().Add("Content-Type", "text/plain; charset=utf-8") - c.Resp.Write([]byte("GetArticles")) -} - -// Articles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (b *blog) Articles(c *macaron.Context) { - c.Resp.WriteHeader(http.StatusOK) - c.Resp.Header().Add("Content-Type", "text/plain; charset=utf-8") - c.Resp.Write([]byte("Articles")) -} - -func main() { - // Default gin engine - m := macaron.New() - - // Register handler to engine by mir - entries := mirEntries() - mirE.Register(m, entries...) - - // Start gin engine serve - m.Run() -} - -// get all entries to register -func mirEntries()[]interface{} { - return []interface{} { - &site{}, - &blog{ - Group: "v2", // direct custom group to v2 override default v1 in mir tag defined - Chain: []macaron.Handler { - macaron.Logger(), - macaron.Recovery(), - }, - }, - } -} -``` diff --git a/module/macaron/core.go b/module/macaron/core.go deleted file mode 100644 index 3643dde..0000000 --- a/module/macaron/core.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package macaron - -import ( - "fmt" - - "github.com/alimy/mir" - "gopkg.in/macaron.v1" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine *macaron.Macaron -} - -// Register register entries to Macaron engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - if entry.Group == "" || entry.Group == "/" { - handlers, err := e.handlerChain(entry.Chain) - if err != nil { - return err - } - for _, handler := range handlers { - e.engine.Use(handler) - } - e.registerWith(entry.Fields) - } else { - if err := e.registerGroup(entry); err != nil { - return err - } - } - } - return nil -} - -// registerGroup register entry by group -func (e *mirEngine) registerGroup(entry *mir.TagMir) error { - handlers, err := e.handlerChain(entry.Chain) - if err != nil { - return err - } - e.engine.Group(entry.Group, func() { - e.registerWith(entry.Fields) - }, handlers...) - return nil -} - -// registerWith register fields engine -func (e *mirEngine) registerWith(fields []*mir.TagField) { - for _, field := range fields { - if field.Method == mir.MethodAny { - e.engine.Any(field.Path, []macaron.Handler{field.Handler}...) - } else { - e.engine.Handle(field.Method, field.Path, []macaron.Handler{field.Handler}) - } - } -} - -// handlerChain get handlers to router that grouped -func (e *mirEngine) handlerChain(chain mir.Chain) ([]macaron.Handler, error) { - // just return if empty chain - if chain == nil { - return []macaron.Handler{}, nil - } - if handlerChain, ok := chain.([]macaron.Handler); ok { - return handlerChain, nil - } - return []macaron.Handler{}, fmt.Errorf("chain type not macaron.Handler") -} diff --git a/module/macaron/core_test.go b/module/macaron/core_test.go deleted file mode 100644 index f1628ca..0000000 --- a/module/macaron/core_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package macaron_test - -import ( - "net/http" - "strings" - - "github.com/alimy/mir" - "gopkg.in/macaron.v1" -) - -type entry struct { - count uint64 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - add mir.Post `mir:"/add/:id/"` - index mir.Any `mir:"/index/"` - articles mir.Get `mir:"/articles/:category/#GetArticles"` -} - -// Add handler of "/add/:id" -func (e *entry) Add(c *macaron.Context) { - body, _ := c.Req.Body().String() - result := strings.Join([]string{ - "Add", - c.Params("id"), - body, - }, ":") - c.Resp.WriteHeader(http.StatusOK) - c.Resp.Header().Add("Content-Type", "text/plain; charset=utf-8") - c.Resp.Write([]byte(result)) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(c *macaron.Context) { - e.count++ - c.Resp.WriteHeader(http.StatusOK) - c.Resp.Header().Add("Content-Type", "text/plain; charset=utf-8") - c.Resp.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(c *macaron.Context) { - c.Resp.WriteHeader(http.StatusOK) - c.Resp.Header().Add("Content-Type", "text/plain; charset=utf-8") - c.Resp.Write([]byte("GetArticles:" + c.Params("category"))) -} - -// mirChain chain used to register to engine -func mirChain() []macaron.Handler { - return []macaron.Handler{ - macaron.Logger(), - macaron.Recovery(), - } -} diff --git a/module/macaron/go.mod b/module/macaron/go.mod deleted file mode 100644 index 31a682d..0000000 --- a/module/macaron/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/alimy/mir/module/macaron - -go 1.11 - -require ( - github.com/alimy/mir v1.0.2 - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 - gopkg.in/macaron.v1 v1.3.4 -) diff --git a/module/macaron/go.sum b/module/macaron/go.sum deleted file mode 100644 index 5efbb30..0000000 --- a/module/macaron/go.sum +++ /dev/null @@ -1,43 +0,0 @@ -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/macaron/macaron.go b/module/macaron/macaron.go deleted file mode 100644 index ea5de3f..0000000 --- a/module/macaron/macaron.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package macaron - -import ( - "github.com/alimy/mir" - "gopkg.in/macaron.v1" -) - -// Mir return mir.Engine interface implements instance.Used to register routes -// to Macaron engine with struct tag string's information. -func Mir(m *macaron.Macaron) mir.Engine { - return &mirEngine{engine: m} -} - -// Register use entries's info to register handler to Macaron engine. -func Register(m *macaron.Macaron, entries ...interface{}) error { - mirE := Mir(m) - return mir.Register(mirE, entries...) -} diff --git a/module/macaron/macaron_suite_test.go b/module/macaron/macaron_suite_test.go deleted file mode 100644 index 3ebe171..0000000 --- a/module/macaron/macaron_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package macaron_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestMacaron(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Macaron Suite") -} diff --git a/module/macaron/macaron_test.go b/module/macaron/macaron_test.go deleted file mode 100644 index 770128e..0000000 --- a/module/macaron/macaron_test.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package macaron_test - -import ( - "bytes" - - "github.com/alimy/mir" - "gopkg.in/macaron.v1" - "net/http/httptest" - - . "github.com/alimy/mir/module/macaron" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Core", func() { - var ( - m *macaron.Macaron - w *httptest.ResponseRecorder - err error - ) - - JustBeforeEach(func() { - w = httptest.NewRecorder() - - }) - - Context("check Mir function", func() { - BeforeEach(func() { - m = macaron.New() - mirE := Mir(m) - err = mir.Register(mirE, &entry{Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(m).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register function", func() { - BeforeEach(func() { - m = macaron.New() - err = Register(m, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(m).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) - - Context("check Register entries", func() { - BeforeEach(func() { - m = macaron.New() - err = Register(m, &entry{}, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(m).ShouldNot(BeNil()) - }) - - It("handle v1 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v1 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v1 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - - It("handle v2 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v2 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v2 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/", nil) - m.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:golang")) - }) - }) -}) diff --git a/module/mux/README.md b/module/mux/README.md deleted file mode 100644 index 2c12441..0000000 --- a/module/mux/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Mir.Mux -Mir.Mux module provide mir.Engine implement backend by [Mux](https://github.com/gorilla/mux). - -### Usage -```go -package main - -import( - "github.com/alimy/mir" - "github.com/gorilla/mux" - "log" - "net/http" - - mirE "github.com/alimy/mir/module/mux" -) - -type site struct { - count uint32 - - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"//{subdomain}.example.com/articles/{category}/{id:[0-9]+}?filter={filter}&foo=bar&id={id:[0-9]+}#GetArticles"` -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (h *site) Index(rw http.ResponseWriter, r *http.Request) { - h.count++ - rw.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -// Host info is the first segment start with '//'(eg:{subdomain}.domain.com) -// Path info is the second or first(if no host info) segment start with '/'(eg: /articles/{category}/{id:[0-9]+}?{filter}) -// Queries info is the third info start with '?' and delimiter by '&'(eg: {filter}&{pages}) -// Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will -// use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will -// is Articles) -func (h *site) GetArticles(rw http.ResponseWriter, r *http.Request) { - rw.Write([]byte("GetArticles")) -} - -func main() { - // Create a new mux router instance - r := mux.NewRouter() - - // Instance a mir engine to register handler for mux router by mir - mirE.Register(r, &site{}) - - // Bind to a port and pass our router in - log.Fatal(http.ListenAndServe(":8013", r)) -} - -``` \ No newline at end of file diff --git a/module/mux/core.go b/module/mux/core.go deleted file mode 100644 index caf68e2..0000000 --- a/module/mux/core.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mux - -import ( - "fmt" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/gorilla/mux" -) - -var _ mir.Engine = &mirEngine{} - -// mirEngine used to implements mir.Engine interface -type mirEngine struct { - engine *mux.Router -} - -// Register register entries to gin engine -func (e *mirEngine) Register(entries []*mir.TagMir) error { - for _, entry := range entries { - var router *mux.Router - if entry.Group == "" || entry.Group == "/" { - router = e.engine - } else { - pathPrefix := entry.Group - if !strings.HasPrefix(entry.Group, "/") { - pathPrefix = "/" + entry.Group - } - router = e.engine.PathPrefix(pathPrefix).Subrouter() - } - if err := handlerChainTo(router, entry.Chain); err != nil { - return err - } - // Notice just return if catch a error or continue next entry register - if err := registerWith(router, entry.Fields); err != nil { - return err - } - } - return nil -} - -// registerWith register fields to give router -func registerWith(router *mux.Router, fields []*mir.TagField) error { - for _, field := range fields { - if handlerFunc, ok := field.Handler.(func(http.ResponseWriter, *http.Request)); ok { - route := router.HandleFunc(field.Path, handlerFunc) - if field.Method == mir.MethodAny { - route.Methods([]string{ - mir.MethodGet, - mir.MethodPut, - mir.MethodPost, - mir.MethodDelete, - mir.MethodHead, - mir.MethodPatch, - mir.MethodOptions, - mir.MethodConnect, - mir.MethodTrace, - }...) - } else { - route.Methods(field.Method) - } - if err := inflateQueries(route, field.Queries); err != nil { - return err - } - if field.Host != "" { - route.Host(field.Host) - } - } else { - return fmt.Errorf("handler not func(http.ResponseWriter, *http.Request) function") - } - } - return nil -} - -// handlerChainTo setup handlers to router that grouped -func handlerChainTo(router *mux.Router, chain mir.Chain) error { - // just return if empty chain - if chain == nil { - return nil - } - if handlerChain, ok := chain.([]mux.MiddlewareFunc); ok { - router.Use(handlerChain...) - } else { - return fmt.Errorf("chain type not []mux.MiddlewareFunc") - } - return nil -} - -// inflateQueries setup queries to route -func inflateQueries(route *mux.Route, queries []string) error { - if len(queries) == 0 { - return nil - } - - // length will x2 of queries - fixedQueries := make([]string, 0, len(queries)*2) - - // start inflate queries - for _, query := range queries { - kv := strings.Split(query, "=") - if len(kv) != 2 { - return fmt.Errorf("mir.mux: query must like ?filter={filter}&foo=bar") - } - fixedQueries = append(fixedQueries, kv...) - } - - // setup fixed queries to route - route.Queries(fixedQueries...) - return nil -} diff --git a/module/mux/core_test.go b/module/mux/core_test.go deleted file mode 100644 index 6f9bb89..0000000 --- a/module/mux/core_test.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mux_test - -import ( - "io" - "net/http" - "strings" - - "github.com/alimy/mir" - "github.com/gorilla/mux" -) - -type entry struct { - count uint32 - - Chain mir.Chain `mir:"-"` - Group mir.Group `mir:"v1"` - add mir.Post `mir:"/add/{id}/"` - index mir.Any `mir:"/index/"` - articles mir.Get `mir:"//{subdomain:[a-z]+}.example.com/articles/{category}/{id:[0-9]+}?filter={filter}&foo=bar&num={num:[0-9]+}#GetArticles"` -} - -// Add handler of "/add/{id}" -func (e *entry) Add(rw http.ResponseWriter, r *http.Request) { - body, err := e.bytesFromBody(r) - if err != nil { - body = []byte("") - } - vars := mux.Vars(r) - result := strings.Join([]string{ - "Add", - vars["id"], - string(body), - }, ":") - rw.WriteHeader(200) - rw.Write([]byte(result)) -} - -// Index handler of the index field that in site struct, the struct tag indicate -// this handler will register to path "/index/" and method is http.MethodGet. -func (e *entry) Index(rw http.ResponseWriter, r *http.Request) { - e.count++ - rw.WriteHeader(200) - rw.Write([]byte("Index")) -} - -// GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. -func (e *entry) GetArticles(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - result := strings.Join([]string{ - "GetArticles", - vars["subdomain"], - vars["category"], - vars["id"], - vars["filter"], - vars["num"], - }, ":") - rw.WriteHeader(200) - rw.Write([]byte(result)) -} - -// bytesFromBody get contents from request's body -func (e *entry) bytesFromBody(r *http.Request) ([]byte, error) { - defer r.Body.Close() - - buf := [256]byte{} - result := make([]byte, 0) - if size, err := r.Body.Read(buf[:]); err == nil { - result = append(result, buf[:size]...) - } else if err != io.EOF { - return nil, err - } - return result, nil -} - -// mirChain chain used to register to engine -func mirChain() []mux.MiddlewareFunc { - return []mux.MiddlewareFunc{ - simpleMiddleware, - simpleMiddleware, - } -} - -func simpleMiddleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Do nothing just for test - h.ServeHTTP(w, r) - }) -} diff --git a/module/mux/doc.go b/module/mux/doc.go deleted file mode 100644 index d11044e..0000000 --- a/module/mux/doc.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -/* -Package mir provider mir.Engine implement backend [Mux](https://github.com/gorilla/mux). - -Define handler in struct type like below: - - type site struct { - count uint32 - Group mir.Group `mir:"v1"` - index mir.Get `mir:"/index/"` - articles mir.Get `mir:"//localhost:8013/articles/{category}/{id:[0-9]+}?filter={filter}&foo=bar&id={id:[0-9]+}#GetArticles"` - } - - // Index handler of the index field that in site struct, the struct tag indicate - // this handler will register to path "/index/" and method is http.MethodGet. - func (h *site) Index(rw http.ResponseWriter, r *http.Request) { - h.count++ - rw.Write([]byte("Index")) - } - - // GetArticles handler of articles indicator that contains Host/Path/Queries/Handler info. - // Host info is the first segment start with '//'(eg:{subdomain}.domain.com) - // Path info is the second or first(if no host info) segment start with '/'(eg: /articles/{category}/{id:[0-9]+}?{filter}) - // Queries info is the third info start with '?' and delimiter by '&'(eg: {filter}&{pages}) - // Handler info is forth info start with '#' that indicate real handler method name(eg: GetArticles).if no handler info will - // use field name capital first char as default handler name(eg: if articles had no #GetArticles then the handler name will - // is Articles) - func (h *site) GetArticles(rw http.ResponseWriter, r *http.Request) { - rw.Write([]byte("GetArticles")) - } - -Then register entry such use gin engine: - - func main() { - r := mux.NewRouter() - - // Instance a mir engine to register handler for mux router by mir - mirE := muxE.Mir(r) - mir.Register(mirE, &site{}) - - // Bind to a port and pass our router in - log.Fatal(http.ListenAndServe(":8000", r)) - } - -*/ -package mux diff --git a/module/mux/go.mod b/module/mux/go.mod deleted file mode 100644 index 5548580..0000000 --- a/module/mux/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/alimy/mir/module/mux - -go 1.11 - -require ( - github.com/alimy/mir v1.0.2 - github.com/gorilla/mux v1.7.3 - github.com/onsi/ginkgo v1.10.2 - github.com/onsi/gomega v1.7.0 -) diff --git a/module/mux/go.sum b/module/mux/go.sum deleted file mode 100644 index b4041d6..0000000 --- a/module/mux/go.sum +++ /dev/null @@ -1,27 +0,0 @@ -github.com/alimy/mir v1.0.2 h1:q1jr/+iWqPQ1w3qkXt/3aAXi6npPhgtSV40udv/drRs= -github.com/alimy/mir v1.0.2/go.mod h1:3dq+89PEa8gAdQV5OIoxsMCHS/1d96p2SvWuHz87n9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/module/mux/mux.go b/module/mux/mux.go deleted file mode 100644 index d10e8a5..0000000 --- a/module/mux/mux.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mux - -import ( - "github.com/alimy/mir" - "github.com/gorilla/mux" -) - -// Mir return mir.Engine interface implements instance. -// Used to register routes to mux router with struct tag string's information. -func Mir(r *mux.Router) mir.Engine { - return &mirEngine{engine: r} -} - -// Register use entries's info to register handler to mux router. -func Register(r *mux.Router, entries ...interface{}) error { - mirE := Mir(r) - return mir.Register(mirE, entries...) -} diff --git a/module/mux/mux_test.go b/module/mux/mux_test.go deleted file mode 100644 index 8263517..0000000 --- a/module/mux/mux_test.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2019 Michael Li . All rights reserved. -// Use of this source code is governed by Apache License 2.0 that -// can be found in the LICENSE file. - -package mux_test - -import ( - "bytes" - "net/http/httptest" - - "github.com/alimy/mir" - "github.com/gorilla/mux" - - . "github.com/alimy/mir/module/mux" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Core", func() { - var ( - router *mux.Router - w *httptest.ResponseRecorder - err error - ) - - JustBeforeEach(func() { - w = httptest.NewRecorder() - }) - - Context("check Mir function", func() { - BeforeEach(func() { - router = mux.NewRouter() - mirE := Mir(router) - err = mir.Register(mirE, &entry{Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v1/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v1/articles/golang/10086?filter=module&foo=bar&num=5", nil) - r.Host = "alimy.example.com" - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:alimy:golang:10086:module:5")) - }) - }) - - Context("check Register function", func() { - BeforeEach(func() { - router = mux.NewRouter() - err = Register(router, &entry{Group: "/v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/10086?filter=module&foo=bar&num=5", nil) - r.Host = "alimy.example.com" - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:alimy:golang:10086:module:5")) - }) - }) - - Context("check Register entries", func() { - BeforeEach(func() { - router = mux.NewRouter() - err = Register(router, &entry{}, &entry{Group: "v2", Chain: mirChain()}) - }) - - It("no error", func() { - Expect(err).Should(BeNil()) - }) - - It("no nil", func() { - Expect(router).ShouldNot(BeNil()) - }) - - It("handle v1 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v1 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v1 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/10086?filter=module&foo=bar&num=5", nil) - r.Host = "alimy.example.com" - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:alimy:golang:10086:module:5")) - }) - - It("handle v2 add", func() { - body := bytes.NewReader([]byte("hello")) - r := httptest.NewRequest(mir.MethodPost, "/v2/add/10086/", body) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Add:10086:hello")) - }) - - It("handler v2 index", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/index/", nil) - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("Index")) - }) - - It("handle v2 articles", func() { - r := httptest.NewRequest(mir.MethodGet, "/v2/articles/golang/10086?filter=module&foo=bar&num=5", nil) - r.Host = "alimy.example.com" - router.ServeHTTP(w, r) - - Expect(w.Code).To(Equal(200)) - Expect(w.Body.String()).To(Equal("GetArticles:alimy:golang:10086:module:5")) - }) - }) -}) diff --git a/fields.go b/parser/fields.go similarity index 96% rename from fields.go rename to parser/fields.go index 2fc63ac..bdd41e3 100644 --- a/fields.go +++ b/parser/fields.go @@ -2,7 +2,7 @@ // Use of this source code is governed by Apache License 2.0 that // can be found in the LICENSE file. -package mir +package parser import ( "fmt" @@ -10,6 +10,8 @@ import ( "strings" "unicode" "unicode/utf8" + + "github.com/alimy/mir/v2" ) const ( @@ -66,7 +68,7 @@ type TagField struct { // TagMir contains TagFields by group type TagMir struct { Group string - Chain Chain + Chain mir.Chain Fields []*TagField } @@ -244,23 +246,23 @@ func tagInfoFrom(field reflect.StructField) (*tagInfo, error) { info.group = tag return info, nil case "Get": - info.Method = MethodGet + info.Method = mir.MethodGet case "Put": - info.Method = MethodPut + info.Method = mir.MethodPut case "Post": - info.Method = MethodPost + info.Method = mir.MethodPost case "Delete": - info.Method = MethodDelete + info.Method = mir.MethodDelete case "Head": - info.Method = MethodHead + info.Method = mir.MethodHead case "Options": - info.Method = MethodOptions + info.Method = mir.MethodOptions case "Patch": - info.Method = MethodPatch + info.Method = mir.MethodPatch case "Trace": - info.Method = MethodTrace + info.Method = mir.MethodTrace case "Connect": - info.Method = MethodConnect + info.Method = mir.MethodConnect case "Any": info.Method = "ANY" } diff --git a/parser/parser.go b/parser/parser.go new file mode 100644 index 0000000..6e5a8d8 --- /dev/null +++ b/parser/parser.go @@ -0,0 +1,29 @@ +// Copyright 2019 Michael Li . All rights reserved. +// Use of this source code is governed by Apache License 2.0 that +// can be found in the LICENSE file. + +package parser + +import ( + "errors" + + "github.com/alimy/mir/v2/core" +) + +func init() { + core.SetDefParser(parserStructTag{}) +} + +// parserStructTag parse for struct tag +type parserStructTag struct{} + +// Name name of parser +func (parserStructTag) Name() string { + return "parserStructTag" +} + +// Parse parse interface define object entries +func (parserStructTag) Parse(entries []interface{}) ([]*core.TagMir, error) { + // TODO + return nil, errors.New("not ready") +}