Codebase list golang-github-go-kit-kit / f80eb06
Merge pull request #1121 from sagikazarmark/remove-kitgen Remove deprecated kitgen Márk Sági-Kazár authored 2 years ago GitHub committed 2 years ago
44 changed file(s) with 0 addition(s) and 3532 deletion(s). Raw diff Collapse all Expand all
+0
-1
cmd/kitgen/.ignore less more
0 testdata/*/*/
+0
-59
cmd/kitgen/README.md less more
0 **DEPRECATED**
1
2 kitgen is no longer maintained.
3
4 # kitgen
5
6 kitgen is an experimental code generation utility that helps with some of the
7 boilerplate code required to implement the "onion" pattern `go-kit` utilizes.
8
9 ## Usage
10 Before using this tool please explore the [testdata]() directory for examples
11 of the inputs it requires and the outputs that will be produced. _You may not
12 need this tool._ If you are new to and just learning `go-kit` or if your use
13 case involves introducing `go-kit` to an existing codebase you are better
14 suited by slowly building out the "onion" by hand.
15
16 Before starting you need to *install* `kitgen` utility — see instructions below.
17 1. **Define** your service. Create a `.go` file with the definition of your
18 Service interface and any of the custom types it refers to:
19 ```go
20 // service.go
21 package profilesvc // don't forget to name your package
22
23 type Service interface {
24 PostProfile(ctx context.Context, p Profile) error
25 // ...
26 }
27 type Profile struct {
28 ID string `json:"id"`
29 Name string `json:"name,omitempty"`
30 // ...
31 }
32 ```
33 2. **Generate** your code. Run the following command:
34 ```sh
35 kitgen ./service.go
36 # kitgen has a couple of flags that you may find useful
37
38 # keep all code in the root directory
39 kitgen -repo-layout flat ./service.go
40
41 # put generated code elsewhere
42 kitgen -target-dir ~/Projects/gohome/src/home.com/kitchenservice/brewcoffee
43 ```
44
45 ## Installation
46 1. **Fetch** the `inlinefiles` utility. Go generate will use it to create your
47 code:
48 ```
49 go get github.com/nyarly/inlinefiles
50 ```
51 2. **Install** the binary for easy access to `kitgen`. Run the following commands:
52 ```sh
53 cd $GOPATH/src/github.com/go-kit/kit/cmd/kitgen
54 go install
55
56 # Check installation by running:
57 kitgen -h
58 ```
+0
-36
cmd/kitgen/arg.go less more
0 package main
1
2 import "go/ast"
3
4 type arg struct {
5 name, asField *ast.Ident
6 typ ast.Expr
7 }
8
9 func (a arg) chooseName(scope *ast.Scope) *ast.Ident {
10 if a.name == nil || scope.Lookup(a.name.Name) != nil {
11 return inventName(a.typ, scope)
12 }
13 return a.name
14 }
15
16 func (a arg) field(scope *ast.Scope) *ast.Field {
17 return &ast.Field{
18 Names: []*ast.Ident{a.chooseName(scope)},
19 Type: a.typ,
20 }
21 }
22
23 func (a arg) result() *ast.Field {
24 return &ast.Field{
25 Names: nil,
26 Type: a.typ,
27 }
28 }
29
30 func (a arg) exported() *ast.Field {
31 return &ast.Field{
32 Names: []*ast.Ident{id(export(a.asField.Name))},
33 Type: a.typ,
34 }
35 }
+0
-209
cmd/kitgen/ast_helpers.go less more
0 package main
1
2 import (
3 "fmt"
4 "go/ast"
5 "go/parser"
6 "go/token"
7 "path/filepath"
8 "strings"
9 "unicode"
10 )
11
12 func export(s string) string {
13 return strings.Title(s)
14 }
15
16 func unexport(s string) string {
17 first := true
18 return strings.Map(func(r rune) rune {
19 if first {
20 first = false
21 return unicode.ToLower(r)
22 }
23 return r
24 }, s)
25 }
26
27 func inventName(t ast.Expr, scope *ast.Scope) *ast.Ident {
28 n := baseName(t)
29 for try := 0; ; try++ {
30 nstr := pickName(n, try)
31 obj := ast.NewObj(ast.Var, nstr)
32 if alt := scope.Insert(obj); alt == nil {
33 return ast.NewIdent(nstr)
34 }
35 }
36 }
37
38 func baseName(t ast.Expr) string {
39 switch tt := t.(type) {
40 default:
41 panic(fmt.Sprintf("don't know how to choose a base name for %T (%[1]v)", tt))
42 case *ast.ArrayType:
43 return "slice"
44 case *ast.Ident:
45 return tt.Name
46 case *ast.SelectorExpr:
47 return tt.Sel.Name
48 }
49 }
50
51 func pickName(base string, idx int) string {
52 if idx == 0 {
53 switch base {
54 default:
55 return strings.Split(base, "")[0]
56 case "Context":
57 return "ctx"
58 case "error":
59 return "err"
60 }
61 }
62 return fmt.Sprintf("%s%d", base, idx)
63 }
64
65 func scopeWith(names ...string) *ast.Scope {
66 scope := ast.NewScope(nil)
67 for _, name := range names {
68 scope.Insert(ast.NewObj(ast.Var, name))
69 }
70 return scope
71 }
72
73 type visitFn func(ast.Node, func(ast.Node))
74
75 func (fn visitFn) Visit(node ast.Node, r func(ast.Node)) Visitor {
76 fn(node, r)
77 return fn
78 }
79
80 func replaceIdent(src ast.Node, named string, with ast.Node) ast.Node {
81 r := visitFn(func(node ast.Node, replaceWith func(ast.Node)) {
82 switch id := node.(type) {
83 case *ast.Ident:
84 if id.Name == named {
85 replaceWith(with)
86 }
87 }
88 })
89 return WalkReplace(r, src)
90 }
91
92 func replaceLit(src ast.Node, from, to string) ast.Node {
93 r := visitFn(func(node ast.Node, replaceWith func(ast.Node)) {
94 switch lit := node.(type) {
95 case *ast.BasicLit:
96 if lit.Value == from {
97 replaceWith(&ast.BasicLit{Value: to})
98 }
99 }
100 })
101 return WalkReplace(r, src)
102 }
103
104 func fullAST() *ast.File {
105 full, err := ASTTemplates.Open("full.go")
106 if err != nil {
107 panic(err)
108 }
109 f, err := parser.ParseFile(token.NewFileSet(), "templates/full.go", full, parser.DeclarationErrors)
110 if err != nil {
111 panic(err)
112 }
113 return f
114 }
115
116 func fetchImports() []*ast.ImportSpec {
117 return fullAST().Imports
118 }
119
120 func fetchFuncDecl(name string) *ast.FuncDecl {
121 f := fullAST()
122 for _, decl := range f.Decls {
123 if f, ok := decl.(*ast.FuncDecl); ok && f.Name.Name == name {
124 return f
125 }
126 }
127 panic(fmt.Errorf("no function called %q in 'templates/full.go'", name))
128 }
129
130 func id(name string) *ast.Ident {
131 return ast.NewIdent(name)
132 }
133
134 func sel(ids ...*ast.Ident) ast.Expr {
135 switch len(ids) {
136 default:
137 return &ast.SelectorExpr{
138 X: sel(ids[:len(ids)-1]...),
139 Sel: ids[len(ids)-1],
140 }
141 case 1:
142 return ids[0]
143 case 0:
144 panic("zero ids to sel()")
145 }
146 }
147
148 func typeField(t ast.Expr) *ast.Field {
149 return &ast.Field{Type: t}
150 }
151
152 func field(n *ast.Ident, t ast.Expr) *ast.Field {
153 return &ast.Field{
154 Names: []*ast.Ident{n},
155 Type: t,
156 }
157 }
158
159 func fieldList(list ...*ast.Field) *ast.FieldList {
160 return &ast.FieldList{List: list}
161 }
162
163 func mappedFieldList(fn func(arg) *ast.Field, args ...arg) *ast.FieldList {
164 fl := &ast.FieldList{List: []*ast.Field{}}
165 for _, a := range args {
166 fl.List = append(fl.List, fn(a))
167 }
168 return fl
169 }
170
171 func blockStmt(stmts ...ast.Stmt) *ast.BlockStmt {
172 return &ast.BlockStmt{
173 List: stmts,
174 }
175 }
176
177 func structDecl(name *ast.Ident, fields *ast.FieldList) ast.Decl {
178 return typeDecl(&ast.TypeSpec{
179 Name: name,
180 Type: &ast.StructType{
181 Fields: fields,
182 },
183 })
184 }
185
186 func typeDecl(ts *ast.TypeSpec) ast.Decl {
187 return &ast.GenDecl{
188 Tok: token.TYPE,
189 Specs: []ast.Spec{ts},
190 }
191 }
192
193 func pasteStmts(body *ast.BlockStmt, idx int, stmts []ast.Stmt) {
194 list := body.List
195 prefix := list[:idx]
196 suffix := make([]ast.Stmt, len(list)-idx-1)
197 copy(suffix, list[idx+1:])
198
199 body.List = append(append(prefix, stmts...), suffix...)
200 }
201
202 func importFor(is *ast.ImportSpec) *ast.GenDecl {
203 return &ast.GenDecl{Tok: token.IMPORT, Specs: []ast.Spec{is}}
204 }
205
206 func importSpec(path string) *ast.ImportSpec {
207 return &ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"` + filepath.ToSlash(path) + `"`}}
208 }
+0
-11
cmd/kitgen/ast_templates.go less more
0 // This file was automatically generated based on the contents of *.tmpl
1 // If you need to update this file, change the contents of those files
2 // (or add new ones) and run 'go generate'
3
4 package main
5
6 import "golang.org/x/tools/godoc/vfs/mapfs"
7
8 var ASTTemplates = mapfs.New(map[string]string{
9 `full.go`: "package foo\n\nimport (\n \"context\"\n \"encoding/json\"\n \"errors\"\n \"net/http\"\n\n \"github.com/go-kit/kit/endpoint\"\n httptransport \"github.com/go-kit/kit/transport/http\"\n)\n\ntype ExampleService struct {\n}\n\ntype ExampleRequest struct {\n I int\n S string\n}\ntype ExampleResponse struct {\n S string\n Err error\n}\n\ntype Endpoints struct {\n ExampleEndpoint endpoint.Endpoint\n}\n\nfunc (f ExampleService) ExampleEndpoint(ctx context.Context, i int, s string) (string, error) {\n panic(errors.New(\"not implemented\"))\n}\n\nfunc makeExampleEndpoint(f ExampleService) endpoint.Endpoint {\n return func(ctx context.Context, request interface{}) (interface{}, error) {\n req := request.(ExampleRequest)\n s, err := f.ExampleEndpoint(ctx, req.I, req.S)\n return ExampleResponse{S: s, Err: err}, nil\n }\n}\n\nfunc inlineHandlerBuilder(m *http.ServeMux, endpoints Endpoints) {\n m.Handle(\"/bar\", httptransport.NewServer(endpoints.ExampleEndpoint, DecodeExampleRequest, EncodeExampleResponse))\n}\n\nfunc NewHTTPHandler(endpoints Endpoints) http.Handler {\n m := http.NewServeMux()\n inlineHandlerBuilder(m, endpoints)\n return m\n}\n\nfunc DecodeExampleRequest(_ context.Context, r *http.Request) (interface{}, error) {\n var req ExampleRequest\n err := json.NewDecoder(r.Body).Decode(&req)\n return req, err\n}\n\nfunc EncodeExampleResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {\n w.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n return json.NewEncoder(w).Encode(response)\n}\n",
10 })
+0
-63
cmd/kitgen/deflayout.go less more
0 package main
1
2 import "path/filepath"
3
4 type deflayout struct {
5 targetDir string
6 }
7
8 func (l deflayout) packagePath(sub string) string {
9 return filepath.Join(l.targetDir, sub)
10 }
11
12 func (l deflayout) transformAST(ctx *sourceContext) (files, error) {
13 out := make(outputTree)
14
15 endpoints := out.addFile("endpoints/endpoints.go", "endpoints")
16 http := out.addFile("http/http.go", "http")
17 service := out.addFile("service/service.go", "service")
18
19 addImports(endpoints, ctx)
20 addImports(http, ctx)
21 addImports(service, ctx)
22
23 for _, typ := range ctx.types {
24 addType(service, typ)
25 }
26
27 for _, iface := range ctx.interfaces { //only one...
28 addStubStruct(service, iface)
29
30 for _, meth := range iface.methods {
31 addMethod(service, iface, meth)
32 addRequestStruct(endpoints, meth)
33 addResponseStruct(endpoints, meth)
34 addEndpointMaker(endpoints, iface, meth)
35 }
36
37 addEndpointsStruct(endpoints, iface)
38 addHTTPHandler(http, iface)
39
40 for _, meth := range iface.methods {
41 addDecoder(http, meth)
42 addEncoder(http, meth)
43 }
44
45 for name := range out {
46 out[name] = selectify(out[name], "service", iface.stubName().Name, l.packagePath("service"))
47 for _, meth := range iface.methods {
48 out[name] = selectify(out[name], "endpoints", meth.requestStructName().Name, l.packagePath("endpoints"))
49 }
50 }
51 }
52
53 for name := range out {
54 out[name] = selectify(out[name], "endpoints", "Endpoints", l.packagePath("endpoints"))
55
56 for _, typ := range ctx.types {
57 out[name] = selectify(out[name], "service", typ.Name.Name, l.packagePath("service"))
58 }
59 }
60
61 return formatNodes(out)
62 }
+0
-39
cmd/kitgen/flatlayout.go less more
0 package main
1
2 import "go/ast"
3
4 type flat struct{}
5
6 func (f flat) transformAST(ctx *sourceContext) (files, error) {
7 root := &ast.File{
8 Name: ctx.pkg,
9 Decls: []ast.Decl{},
10 }
11
12 addImports(root, ctx)
13
14 for _, typ := range ctx.types {
15 addType(root, typ)
16 }
17
18 for _, iface := range ctx.interfaces { //only one...
19 addStubStruct(root, iface)
20
21 for _, meth := range iface.methods {
22 addMethod(root, iface, meth)
23 addRequestStruct(root, meth)
24 addResponseStruct(root, meth)
25 addEndpointMaker(root, iface, meth)
26 }
27
28 addEndpointsStruct(root, iface)
29 addHTTPHandler(root, iface)
30
31 for _, meth := range iface.methods {
32 addDecoder(root, meth)
33 addEncoder(root, meth)
34 }
35 }
36
37 return formatNodes(outputTree{"gokit.go": root})
38 }
+0
-70
cmd/kitgen/interface.go less more
0 package main
1
2 import "go/ast"
3
4 // because "interface" is a keyword...
5 type iface struct {
6 name, stubname, rcvrName *ast.Ident
7 methods []method
8 }
9
10 func (i iface) stubName() *ast.Ident {
11 return i.stubname
12 }
13
14 func (i iface) stubStructDecl() ast.Decl {
15 return structDecl(i.stubName(), &ast.FieldList{})
16 }
17
18 func (i iface) endpointsStruct() ast.Decl {
19 fl := &ast.FieldList{}
20 for _, m := range i.methods {
21 fl.List = append(fl.List, &ast.Field{Names: []*ast.Ident{m.name}, Type: sel(id("endpoint"), id("Endpoint"))})
22 }
23 return structDecl(id("Endpoints"), fl)
24 }
25
26 func (i iface) httpHandler() ast.Decl {
27 handlerFn := fetchFuncDecl("NewHTTPHandler")
28
29 // does this "inlining" process merit a helper akin to replaceIdent?
30 handleCalls := []ast.Stmt{}
31 for _, m := range i.methods {
32 handleCall := fetchFuncDecl("inlineHandlerBuilder").Body.List[0].(*ast.ExprStmt).X.(*ast.CallExpr)
33
34 handleCall = replaceLit(handleCall, `"/bar"`, `"`+m.pathName()+`"`).(*ast.CallExpr)
35 handleCall = replaceIdent(handleCall, "ExampleEndpoint", m.name).(*ast.CallExpr)
36 handleCall = replaceIdent(handleCall, "DecodeExampleRequest", m.decodeFuncName()).(*ast.CallExpr)
37 handleCall = replaceIdent(handleCall, "EncodeExampleResponse", m.encodeFuncName()).(*ast.CallExpr)
38
39 handleCalls = append(handleCalls, &ast.ExprStmt{X: handleCall})
40 }
41
42 pasteStmts(handlerFn.Body, 1, handleCalls)
43
44 return handlerFn
45 }
46
47 func (i iface) receiver() *ast.Field {
48 return field(i.receiverName(), i.stubName())
49 }
50
51 func (i iface) receiverName() *ast.Ident {
52 if i.rcvrName != nil {
53 return i.rcvrName
54 }
55 scope := ast.NewScope(nil)
56 for _, meth := range i.methods {
57 for _, arg := range meth.params {
58 if arg.name != nil {
59 scope.Insert(ast.NewObj(ast.Var, arg.name.Name))
60 }
61 }
62 for _, arg := range meth.results {
63 if arg.name != nil {
64 scope.Insert(ast.NewObj(ast.Var, arg.name.Name))
65 }
66 }
67 }
68 return id(unexport(inventName(i.name, scope).Name))
69 }
+0
-156
cmd/kitgen/main.go less more
0 package main
1
2 import (
3 "flag"
4 "fmt"
5 "go/ast"
6 "go/parser"
7 "go/token"
8 "io"
9 "log"
10 "os"
11 "path"
12
13 "github.com/pkg/errors"
14 )
15
16 // go get github.com/nyarly/inlinefiles
17 //go:generate inlinefiles --package=main --vfs=ASTTemplates ./templates ast_templates.go
18
19 func usage() string {
20 return fmt.Sprintf("Usage: %s <filename> (try -h)", os.Args[0])
21 }
22
23 var (
24 help = flag.Bool("h", false, "print this help")
25 layoutkind = flag.String("repo-layout", "default", "default, flat...")
26 outdirrel = flag.String("target-dir", ".", "base directory to emit into")
27 //contextOmittable = flag.Bool("allow-no-context", false, "allow service methods to omit context parameter")
28 )
29
30 func helpText() {
31 fmt.Println("USAGE")
32 fmt.Println(" kitgen [flags] path/to/service.go")
33 fmt.Println("")
34 fmt.Println("FLAGS")
35 flag.PrintDefaults()
36 }
37
38 func main() {
39 flag.Parse()
40
41 if *help {
42 helpText()
43 os.Exit(0)
44 }
45
46 outdir := *outdirrel
47 if !path.IsAbs(*outdirrel) {
48 wd, err := os.Getwd()
49 if err != nil {
50 log.Fatalf("error getting current working directory: %v", err)
51 }
52 outdir = path.Join(wd, *outdirrel)
53 }
54
55 var layout layout
56 switch *layoutkind {
57 default:
58 log.Fatalf("Unrecognized layout kind: %q - try 'default' or 'flat'", *layoutkind)
59 case "default":
60 gopath := getGopath()
61 importBase, err := importPath(outdir, gopath)
62 if err != nil {
63 log.Fatal(err)
64 }
65 layout = deflayout{targetDir: importBase}
66 case "flat":
67 layout = flat{}
68 }
69
70 if len(os.Args) < 2 {
71 log.Fatal(usage())
72 }
73 filename := flag.Arg(0)
74 file, err := os.Open(filename)
75 if err != nil {
76 log.Fatalf("error while opening %q: %v", filename, err)
77 }
78
79 tree, err := process(filename, file, layout)
80 if err != nil {
81 log.Fatal(err)
82 }
83
84 err = splat(outdir, tree)
85 if err != nil {
86 log.Fatal(err)
87 }
88 }
89
90 func process(filename string, source io.Reader, layout layout) (files, error) {
91 f, err := parseFile(filename, source)
92 if err != nil {
93 return nil, errors.Wrapf(err, "parsing input %q", filename)
94 }
95
96 context, err := extractContext(f)
97 if err != nil {
98 return nil, errors.Wrapf(err, "examining input file %q", filename)
99 }
100
101 tree, err := layout.transformAST(context)
102 if err != nil {
103 return nil, errors.Wrapf(err, "generating AST")
104 }
105 return tree, nil
106 }
107
108 /*
109 buf, err := formatNode(dest)
110 if err != nil {
111 return nil, errors.Wrapf(err, "formatting")
112 }
113 return buf, nil
114 }
115 */
116
117 func parseFile(fname string, source io.Reader) (ast.Node, error) {
118 f, err := parser.ParseFile(token.NewFileSet(), fname, source, parser.DeclarationErrors)
119 if err != nil {
120 return nil, err
121 }
122 return f, nil
123 }
124
125 func extractContext(f ast.Node) (*sourceContext, error) {
126 context := &sourceContext{}
127 visitor := &parseVisitor{src: context}
128
129 ast.Walk(visitor, f)
130
131 return context, context.validate()
132 }
133
134 func splat(dir string, tree files) error {
135 for fn, buf := range tree {
136 if err := splatFile(path.Join(dir, fn), buf); err != nil {
137 return err
138 }
139 }
140 return nil
141 }
142
143 func splatFile(target string, buf io.Reader) error {
144 err := os.MkdirAll(path.Dir(target), os.ModePerm)
145 if err != nil {
146 return errors.Wrapf(err, "Couldn't create directory for %q", target)
147 }
148 f, err := os.Create(target)
149 if err != nil {
150 return errors.Wrapf(err, "Couldn't create file %q", target)
151 }
152 defer f.Close()
153 _, err = io.Copy(f, buf)
154 return errors.Wrapf(err, "Error writing data to file %q", target)
155 }
+0
-117
cmd/kitgen/main_test.go less more
0 package main
1
2 import (
3 "bufio"
4 "bytes"
5 "flag"
6 "fmt"
7 "io/ioutil"
8 "os/exec"
9 "path/filepath"
10 "testing"
11
12 "github.com/aryann/difflib"
13 )
14
15 var update = flag.Bool("update", false, "update golden files")
16
17 func TestProcess(t *testing.T) {
18 cases, err := filepath.Glob("testdata/*")
19 if err != nil {
20 t.Fatal(err)
21 }
22
23 laidout := func(t *testing.T, inpath, dir, kind string, layout layout, in []byte) {
24 t.Run(kind, func(t *testing.T) {
25 targetDir := filepath.Join(dir, kind)
26 tree, err := process(inpath, bytes.NewBuffer(in), layout)
27 if err != nil {
28 t.Fatal(inpath, fmt.Sprintf("%+#v", err))
29 }
30
31 if *update {
32 err := splat(targetDir, tree)
33 if err != nil {
34 t.Fatal(kind, err)
35 }
36 // otherwise we need to do some tomfoolery with resetting buffers
37 // I'm willing to just run the tests again - besides, we shouldn't be
38 // regerating the golden files that often
39 t.Error("Updated outputs - DID NOT COMPARE! (run tests again without -update)")
40 return
41 }
42
43 for filename, buf := range tree {
44 actual, err := ioutil.ReadAll(buf)
45 if err != nil {
46 t.Fatal(kind, filename, err)
47 }
48
49 outpath := filepath.Join(targetDir, filename)
50
51 expected, err := ioutil.ReadFile(outpath)
52 if err != nil {
53 t.Fatal(outpath, err)
54 }
55
56 if !bytes.Equal(expected, actual) {
57 results := difflib.Diff(splitLines(expected), splitLines(actual))
58 for _, result := range results {
59 if result.Delta == difflib.Common {
60 continue
61 }
62 t.Error(result)
63 }
64 }
65 }
66
67 if !t.Failed() {
68 build := exec.Command("go", "build", "./...")
69 build.Dir = targetDir
70 out, err := build.CombinedOutput()
71 if err != nil {
72 t.Fatalf("Cannot build output: %v\n%s", err, string(out))
73 }
74 }
75 })
76
77 }
78
79 testcase := func(dir string) {
80 name := filepath.Base(dir)
81 t.Run(name, func(t *testing.T) {
82 inpath := filepath.Join(dir, "in.go")
83
84 in, err := ioutil.ReadFile(inpath)
85 if err != nil {
86 t.Fatal(inpath, err)
87 }
88 laidout(t, inpath, dir, "flat", flat{}, in)
89 laidout(t, inpath, dir, "default", deflayout{
90 targetDir: filepath.Join("github.com/go-kit/kit/cmd/kitgen", dir, "default"),
91 }, in)
92 })
93 }
94
95 for _, dir := range cases {
96 testcase(dir)
97 }
98 }
99
100 func TestTemplatesBuild(t *testing.T) {
101 build := exec.Command("go", "build", "./...")
102 build.Dir = "templates"
103 out, err := build.CombinedOutput()
104 if err != nil {
105 t.Fatal(err, "\n", string(out))
106 }
107 }
108
109 func splitLines(txt []byte) []string {
110 s := bufio.NewScanner(bytes.NewReader(txt))
111 var ss []string
112 for s.Scan() {
113 ss = append(ss, s.Text())
114 }
115 return ss
116 }
+0
-220
cmd/kitgen/method.go less more
0 package main
1
2 import (
3 "go/ast"
4 "go/token"
5 "strings"
6 )
7
8 type method struct {
9 name *ast.Ident
10 params []arg
11 results []arg
12 structsResolved bool
13 }
14
15 func (m method) definition(ifc iface) ast.Decl {
16 notImpl := fetchFuncDecl("ExampleEndpoint")
17
18 notImpl.Name = m.name
19 notImpl.Recv = fieldList(ifc.receiver())
20 scope := scopeWith(notImpl.Recv.List[0].Names[0].Name)
21 notImpl.Type.Params = m.funcParams(scope)
22 notImpl.Type.Results = m.funcResults()
23
24 return notImpl
25 }
26
27 func (m method) endpointMaker(ifc iface) ast.Decl {
28 endpointFn := fetchFuncDecl("makeExampleEndpoint")
29 scope := scopeWith("ctx", "req", ifc.receiverName().Name)
30
31 anonFunc := endpointFn.Body.List[0].(*ast.ReturnStmt).Results[0].(*ast.FuncLit)
32 if !m.hasContext() {
33 // strip context param from endpoint function
34 anonFunc.Type.Params.List = anonFunc.Type.Params.List[1:]
35 }
36
37 anonFunc = replaceIdent(anonFunc, "ExampleRequest", m.requestStructName()).(*ast.FuncLit)
38 callMethod := m.called(ifc, scope, "ctx", "req")
39 anonFunc.Body.List[1] = callMethod
40 anonFunc.Body.List[2].(*ast.ReturnStmt).Results[0] = m.wrapResult(callMethod.Lhs)
41
42 endpointFn.Body.List[0].(*ast.ReturnStmt).Results[0] = anonFunc
43 endpointFn.Name = m.endpointMakerName()
44 endpointFn.Type.Params = fieldList(ifc.receiver())
45 endpointFn.Type.Results = fieldList(typeField(sel(id("endpoint"), id("Endpoint"))))
46 return endpointFn
47 }
48
49 func (m method) pathName() string {
50 return "/" + strings.ToLower(m.name.Name)
51 }
52
53 func (m method) encodeFuncName() *ast.Ident {
54 return id("Encode" + m.name.Name + "Response")
55 }
56
57 func (m method) decodeFuncName() *ast.Ident {
58 return id("Decode" + m.name.Name + "Request")
59 }
60
61 func (m method) resultNames(scope *ast.Scope) []*ast.Ident {
62 ids := []*ast.Ident{}
63 for _, rz := range m.results {
64 ids = append(ids, rz.chooseName(scope))
65 }
66 return ids
67 }
68
69 func (m method) called(ifc iface, scope *ast.Scope, ctxName, spreadStruct string) *ast.AssignStmt {
70 m.resolveStructNames()
71
72 resNamesExpr := []ast.Expr{}
73 for _, r := range m.resultNames(scope) {
74 resNamesExpr = append(resNamesExpr, ast.Expr(r))
75 }
76
77 arglist := []ast.Expr{}
78 if m.hasContext() {
79 arglist = append(arglist, id(ctxName))
80 }
81 ssid := id(spreadStruct)
82 for _, f := range m.requestStructFields().List {
83 arglist = append(arglist, sel(ssid, f.Names[0]))
84 }
85
86 return &ast.AssignStmt{
87 Lhs: resNamesExpr,
88 Tok: token.DEFINE,
89 Rhs: []ast.Expr{
90 &ast.CallExpr{
91 Fun: sel(ifc.receiverName(), m.name),
92 Args: arglist,
93 },
94 },
95 }
96 }
97
98 func (m method) wrapResult(results []ast.Expr) ast.Expr {
99 kvs := []ast.Expr{}
100 m.resolveStructNames()
101
102 for i, a := range m.results {
103 kvs = append(kvs, &ast.KeyValueExpr{
104 Key: ast.NewIdent(export(a.asField.Name)),
105 Value: results[i],
106 })
107 }
108 return &ast.CompositeLit{
109 Type: m.responseStructName(),
110 Elts: kvs,
111 }
112 }
113
114 func (m method) resolveStructNames() {
115 if m.structsResolved {
116 return
117 }
118 m.structsResolved = true
119 scope := ast.NewScope(nil)
120 for i, p := range m.params {
121 p.asField = p.chooseName(scope)
122 m.params[i] = p
123 }
124 scope = ast.NewScope(nil)
125 for i, r := range m.results {
126 r.asField = r.chooseName(scope)
127 m.results[i] = r
128 }
129 }
130
131 func (m method) decoderFunc() ast.Decl {
132 fn := fetchFuncDecl("DecodeExampleRequest")
133 fn.Name = m.decodeFuncName()
134 fn = replaceIdent(fn, "ExampleRequest", m.requestStructName()).(*ast.FuncDecl)
135 return fn
136 }
137
138 func (m method) encoderFunc() ast.Decl {
139 fn := fetchFuncDecl("EncodeExampleResponse")
140 fn.Name = m.encodeFuncName()
141 return fn
142 }
143
144 func (m method) endpointMakerName() *ast.Ident {
145 return id("Make" + m.name.Name + "Endpoint")
146 }
147
148 func (m method) requestStruct() ast.Decl {
149 m.resolveStructNames()
150 return structDecl(m.requestStructName(), m.requestStructFields())
151 }
152
153 func (m method) responseStruct() ast.Decl {
154 m.resolveStructNames()
155 return structDecl(m.responseStructName(), m.responseStructFields())
156 }
157
158 func (m method) hasContext() bool {
159 if len(m.params) < 1 {
160 return false
161 }
162 carg := m.params[0].typ
163 // ugh. this is maybe okay for the one-off, but a general case for matching
164 // types would be helpful
165 if sel, is := carg.(*ast.SelectorExpr); is && sel.Sel.Name == "Context" {
166 if id, is := sel.X.(*ast.Ident); is && id.Name == "context" {
167 return true
168 }
169 }
170 return false
171 }
172
173 func (m method) nonContextParams() []arg {
174 if m.hasContext() {
175 return m.params[1:]
176 }
177 return m.params
178 }
179
180 func (m method) funcParams(scope *ast.Scope) *ast.FieldList {
181 parms := &ast.FieldList{}
182 if m.hasContext() {
183 parms.List = []*ast.Field{{
184 Names: []*ast.Ident{ast.NewIdent("ctx")},
185 Type: sel(id("context"), id("Context")),
186 }}
187 scope.Insert(ast.NewObj(ast.Var, "ctx"))
188 }
189 parms.List = append(parms.List, mappedFieldList(func(a arg) *ast.Field {
190 return a.field(scope)
191 }, m.nonContextParams()...).List...)
192 return parms
193 }
194
195 func (m method) funcResults() *ast.FieldList {
196 return mappedFieldList(func(a arg) *ast.Field {
197 return a.result()
198 }, m.results...)
199 }
200
201 func (m method) requestStructName() *ast.Ident {
202 return id(export(m.name.Name) + "Request")
203 }
204
205 func (m method) requestStructFields() *ast.FieldList {
206 return mappedFieldList(func(a arg) *ast.Field {
207 return a.exported()
208 }, m.nonContextParams()...)
209 }
210
211 func (m method) responseStructName() *ast.Ident {
212 return id(export(m.name.Name) + "Response")
213 }
214
215 func (m method) responseStructFields() *ast.FieldList {
216 return mappedFieldList(func(a arg) *ast.Field {
217 return a.exported()
218 }, m.results...)
219 }
+0
-178
cmd/kitgen/parsevisitor.go less more
0 package main
1
2 import (
3 "go/ast"
4 )
5
6 type (
7 parseVisitor struct {
8 src *sourceContext
9 }
10
11 typeSpecVisitor struct {
12 src *sourceContext
13 node *ast.TypeSpec
14 iface *iface
15 name *ast.Ident
16 }
17
18 interfaceTypeVisitor struct {
19 node *ast.TypeSpec
20 ts *typeSpecVisitor
21 methods []method
22 }
23
24 methodVisitor struct {
25 depth int
26 node *ast.TypeSpec
27 list *[]method
28 name *ast.Ident
29 params, results *[]arg
30 isMethod bool
31 }
32
33 argListVisitor struct {
34 list *[]arg
35 }
36
37 argVisitor struct {
38 node *ast.TypeSpec
39 parts []ast.Expr
40 list *[]arg
41 }
42 )
43
44 func (v *parseVisitor) Visit(n ast.Node) ast.Visitor {
45 switch rn := n.(type) {
46 default:
47 return v
48 case *ast.File:
49 v.src.pkg = rn.Name
50 return v
51 case *ast.ImportSpec:
52 v.src.imports = append(v.src.imports, rn)
53 return nil
54
55 case *ast.TypeSpec:
56 switch rn.Type.(type) {
57 default:
58 v.src.types = append(v.src.types, rn)
59 case *ast.InterfaceType:
60 // can't output interfaces
61 // because they'd conflict with our implementations
62 }
63 return &typeSpecVisitor{src: v.src, node: rn}
64 }
65 }
66
67 /*
68 package foo
69
70 type FooService interface {
71 Bar(ctx context.Context, i int, s string) (string, error)
72 }
73 */
74
75 func (v *typeSpecVisitor) Visit(n ast.Node) ast.Visitor {
76 switch rn := n.(type) {
77 default:
78 return v
79 case *ast.Ident:
80 if v.name == nil {
81 v.name = rn
82 }
83 return v
84 case *ast.InterfaceType:
85 return &interfaceTypeVisitor{ts: v, methods: []method{}}
86 case nil:
87 if v.iface != nil {
88 v.iface.name = v.name
89 sn := *v.name
90 v.iface.stubname = &sn
91 v.iface.stubname.Name = v.name.String()
92 v.src.interfaces = append(v.src.interfaces, *v.iface)
93 }
94 return nil
95 }
96 }
97
98 func (v *interfaceTypeVisitor) Visit(n ast.Node) ast.Visitor {
99 switch n.(type) {
100 default:
101 return v
102 case *ast.Field:
103 return &methodVisitor{list: &v.methods}
104 case nil:
105 v.ts.iface = &iface{methods: v.methods}
106 return nil
107 }
108 }
109
110 func (v *methodVisitor) Visit(n ast.Node) ast.Visitor {
111 switch rn := n.(type) {
112 default:
113 v.depth++
114 return v
115 case *ast.Ident:
116 if rn.IsExported() {
117 v.name = rn
118 }
119 v.depth++
120 return v
121 case *ast.FuncType:
122 v.depth++
123 v.isMethod = true
124 return v
125 case *ast.FieldList:
126 if v.params == nil {
127 v.params = &[]arg{}
128 return &argListVisitor{list: v.params}
129 }
130 if v.results == nil {
131 v.results = &[]arg{}
132 }
133 return &argListVisitor{list: v.results}
134 case nil:
135 v.depth--
136 if v.depth == 0 && v.isMethod && v.name != nil {
137 *v.list = append(*v.list, method{name: v.name, params: *v.params, results: *v.results})
138 }
139 return nil
140 }
141 }
142
143 func (v *argListVisitor) Visit(n ast.Node) ast.Visitor {
144 switch n.(type) {
145 default:
146 return nil
147 case *ast.Field:
148 return &argVisitor{list: v.list}
149 }
150 }
151
152 func (v *argVisitor) Visit(n ast.Node) ast.Visitor {
153 switch t := n.(type) {
154 case *ast.CommentGroup, *ast.BasicLit:
155 return nil
156 case *ast.Ident: //Expr -> everything, but clarity
157 if t.Name != "_" {
158 v.parts = append(v.parts, t)
159 }
160 case ast.Expr:
161 v.parts = append(v.parts, t)
162 case nil:
163 names := v.parts[:len(v.parts)-1]
164 tp := v.parts[len(v.parts)-1]
165 if len(names) == 0 {
166 *v.list = append(*v.list, arg{typ: tp})
167 return nil
168 }
169 for _, n := range names {
170 *v.list = append(*v.list, arg{
171 name: n.(*ast.Ident),
172 typ: tp,
173 })
174 }
175 }
176 return nil
177 }
+0
-54
cmd/kitgen/path_test.go less more
0 package main
1
2 import (
3 "fmt"
4 "runtime"
5 "strings"
6 "testing"
7 )
8
9 func TestImportPath(t *testing.T) {
10 testcase := func(gopath, targetpath, expected string) {
11 t.Run(fmt.Sprintf("%q + %q", gopath, targetpath), func(t *testing.T) {
12 actual, err := importPath(targetpath, gopath)
13 if err != nil {
14 t.Fatalf("Expected no error, got %q", err)
15 }
16 if actual != expected {
17 t.Errorf("Expected %q, got %q", expected, actual)
18 }
19 })
20 }
21
22 if runtime.GOOS == "windows" {
23 testcase("c:\\gopath\\", "c:\\gopath\\src\\somewhere", "somewhere")
24 testcase("c:\\gopath", "c:\\gopath\\src\\somewhere", "somewhere")
25 testcase("c:\\gopath;\\other", "c:\\gopath\\src\\somewhere", "somewhere")
26 testcase("c:\\other;c:\\gopath\\", "c:\\gopath\\src\\somewhere", "somewhere")
27 } else {
28 testcase("/gopath/", "/gopath/src/somewhere", "somewhere")
29 testcase("/gopath", "/gopath/src/somewhere", "somewhere")
30 testcase("/gopath:/other", "/gopath/src/somewhere", "somewhere")
31 testcase("/other:/gopath/", "/gopath/src/somewhere", "somewhere")
32 }
33 }
34
35 func TestImportPathSadpath(t *testing.T) {
36 testcase := func(gopath, targetpath, expected string) {
37 t.Run(fmt.Sprintf("%q + %q", gopath, targetpath), func(t *testing.T) {
38 actual, err := importPath(targetpath, gopath)
39 if actual != "" {
40 t.Errorf("Expected empty path, got %q", actual)
41 }
42 if strings.Index(err.Error(), expected) == -1 {
43 t.Errorf("Expected %q to include %q", err, expected)
44 }
45 })
46 }
47 if runtime.GOOS == "windows" {
48 testcase("", "c:\\gopath\\src\\somewhere", "is not in")
49 } else {
50 testcase("", "/gopath/src/somewhere", "is not in")
51 }
52 testcase("", "./somewhere", "not an absolute")
53 }
+0
-759
cmd/kitgen/replacewalk.go less more
0 package main
1
2 import (
3 "fmt"
4 "go/ast"
5 )
6
7 // A Visitor's Visit method is invoked for each node encountered by walkToReplace.
8 // If the result visitor w is not nil, walkToReplace visits each of the children
9 // of node with the visitor w, followed by a call of w.Visit(nil).
10 type Visitor interface {
11 Visit(node ast.Node, replace func(ast.Node)) (w Visitor)
12 }
13
14 // Helper functions for common node lists. They may be empty.
15
16 func walkIdentList(v Visitor, list []*ast.Ident) {
17 for i, x := range list {
18 walkToReplace(v, x, func(r ast.Node) {
19 list[i] = r.(*ast.Ident)
20 })
21 }
22 }
23
24 func walkExprList(v Visitor, list []ast.Expr) {
25 for i, x := range list {
26 walkToReplace(v, x, func(r ast.Node) {
27 list[i] = r.(ast.Expr)
28 })
29 }
30 }
31
32 func walkStmtList(v Visitor, list []ast.Stmt) {
33 for i, x := range list {
34 walkToReplace(v, x, func(r ast.Node) {
35 list[i] = r.(ast.Stmt)
36 })
37 }
38 }
39
40 func walkDeclList(v Visitor, list []ast.Decl) {
41 for i, x := range list {
42 walkToReplace(v, x, func(r ast.Node) {
43 list[i] = r.(ast.Decl)
44 })
45 }
46 }
47
48 // WalkToReplace traverses an AST in depth-first order: It starts by calling
49 // v.Visit(node); node must not be nil. If the visitor w returned by
50 // v.Visit(node) is not nil, walkToReplace is invoked recursively with visitor
51 // w for each of the non-nil children of node, followed by a call of
52 // w.Visit(nil).
53 func WalkReplace(v Visitor, node ast.Node) (replacement ast.Node) {
54 walkToReplace(v, node, func(r ast.Node) {
55 replacement = r
56 })
57 return
58 }
59
60 func walkToReplace(v Visitor, node ast.Node, replace func(ast.Node)) {
61 if v == nil {
62 return
63 }
64 var replacement ast.Node
65 repl := func(r ast.Node) {
66 replacement = r
67 replace(r)
68 }
69
70 v = v.Visit(node, repl)
71
72 if replacement != nil {
73 return
74 }
75
76 // walk children
77 // (the order of the cases matches the order
78 // of the corresponding node types in ast.go)
79 switch n := node.(type) {
80
81 // These are all leaves, so there's no sub-walk to do.
82 // We just need to replace them on their parent with a copy.
83 case *ast.Comment:
84 cpy := *n
85 replace(&cpy)
86 case *ast.BadExpr:
87 cpy := *n
88 replace(&cpy)
89 case *ast.Ident:
90 cpy := *n
91 replace(&cpy)
92 case *ast.BasicLit:
93 cpy := *n
94 replace(&cpy)
95 case *ast.BadDecl:
96 cpy := *n
97 replace(&cpy)
98 case *ast.EmptyStmt:
99 cpy := *n
100 replace(&cpy)
101 case *ast.BadStmt:
102 cpy := *n
103 replace(&cpy)
104
105 case *ast.CommentGroup:
106 cpy := *n
107
108 if n.List != nil {
109 cpy.List = make([]*ast.Comment, len(n.List))
110 copy(cpy.List, n.List)
111 }
112
113 for i, c := range cpy.List {
114 walkToReplace(v, c, func(r ast.Node) {
115 cpy.List[i] = r.(*ast.Comment)
116 })
117 }
118 replace(&cpy)
119
120 case *ast.Field:
121 cpy := *n
122 if n.Names != nil {
123 cpy.Names = make([]*ast.Ident, len(n.Names))
124 copy(cpy.Names, n.Names)
125 }
126
127 if cpy.Doc != nil {
128 walkToReplace(v, cpy.Doc, func(r ast.Node) {
129 cpy.Doc = r.(*ast.CommentGroup)
130 })
131 }
132 walkIdentList(v, cpy.Names)
133
134 walkToReplace(v, cpy.Type, func(r ast.Node) {
135 cpy.Type = r.(ast.Expr)
136 })
137 if cpy.Tag != nil {
138 walkToReplace(v, cpy.Tag, func(r ast.Node) {
139 cpy.Tag = r.(*ast.BasicLit)
140 })
141 }
142 if cpy.Comment != nil {
143 walkToReplace(v, cpy.Comment, func(r ast.Node) {
144 cpy.Comment = r.(*ast.CommentGroup)
145 })
146 }
147 replace(&cpy)
148
149 case *ast.FieldList:
150 cpy := *n
151 if n.List != nil {
152 cpy.List = make([]*ast.Field, len(n.List))
153 copy(cpy.List, n.List)
154 }
155
156 for i, f := range cpy.List {
157 walkToReplace(v, f, func(r ast.Node) {
158 cpy.List[i] = r.(*ast.Field)
159 })
160 }
161
162 replace(&cpy)
163
164 case *ast.Ellipsis:
165 cpy := *n
166
167 if cpy.Elt != nil {
168 walkToReplace(v, cpy.Elt, func(r ast.Node) {
169 cpy.Elt = r.(ast.Expr)
170 })
171 }
172
173 replace(&cpy)
174
175 case *ast.FuncLit:
176 cpy := *n
177 walkToReplace(v, cpy.Type, func(r ast.Node) {
178 cpy.Type = r.(*ast.FuncType)
179 })
180 walkToReplace(v, cpy.Body, func(r ast.Node) {
181 cpy.Body = r.(*ast.BlockStmt)
182 })
183
184 replace(&cpy)
185 case *ast.CompositeLit:
186 cpy := *n
187 if n.Elts != nil {
188 cpy.Elts = make([]ast.Expr, len(n.Elts))
189 copy(cpy.Elts, n.Elts)
190 }
191
192 if cpy.Type != nil {
193 walkToReplace(v, cpy.Type, func(r ast.Node) {
194 cpy.Type = r.(ast.Expr)
195 })
196 }
197 walkExprList(v, cpy.Elts)
198
199 replace(&cpy)
200 case *ast.ParenExpr:
201 cpy := *n
202 walkToReplace(v, cpy.X, func(r ast.Node) {
203 cpy.X = r.(ast.Expr)
204 })
205
206 replace(&cpy)
207 case *ast.SelectorExpr:
208 cpy := *n
209 walkToReplace(v, cpy.X, func(r ast.Node) {
210 cpy.X = r.(ast.Expr)
211 })
212 walkToReplace(v, cpy.Sel, func(r ast.Node) {
213 cpy.Sel = r.(*ast.Ident)
214 })
215
216 replace(&cpy)
217 case *ast.IndexExpr:
218 cpy := *n
219 walkToReplace(v, cpy.X, func(r ast.Node) {
220 cpy.X = r.(ast.Expr)
221 })
222 walkToReplace(v, cpy.Index, func(r ast.Node) {
223 cpy.Index = r.(ast.Expr)
224 })
225
226 replace(&cpy)
227 case *ast.SliceExpr:
228 cpy := *n
229 walkToReplace(v, cpy.X, func(r ast.Node) {
230 cpy.X = r.(ast.Expr)
231 })
232 if cpy.Low != nil {
233 walkToReplace(v, cpy.Low, func(r ast.Node) {
234 cpy.Low = r.(ast.Expr)
235 })
236 }
237 if cpy.High != nil {
238 walkToReplace(v, cpy.High, func(r ast.Node) {
239 cpy.High = r.(ast.Expr)
240 })
241 }
242 if cpy.Max != nil {
243 walkToReplace(v, cpy.Max, func(r ast.Node) {
244 cpy.Max = r.(ast.Expr)
245 })
246 }
247
248 replace(&cpy)
249 case *ast.TypeAssertExpr:
250 cpy := *n
251 walkToReplace(v, cpy.X, func(r ast.Node) {
252 cpy.X = r.(ast.Expr)
253 })
254 if cpy.Type != nil {
255 walkToReplace(v, cpy.Type, func(r ast.Node) {
256 cpy.Type = r.(ast.Expr)
257 })
258 }
259 replace(&cpy)
260 case *ast.CallExpr:
261 cpy := *n
262 if n.Args != nil {
263 cpy.Args = make([]ast.Expr, len(n.Args))
264 copy(cpy.Args, n.Args)
265 }
266
267 walkToReplace(v, cpy.Fun, func(r ast.Node) {
268 cpy.Fun = r.(ast.Expr)
269 })
270 walkExprList(v, cpy.Args)
271
272 replace(&cpy)
273 case *ast.StarExpr:
274 cpy := *n
275 walkToReplace(v, cpy.X, func(r ast.Node) {
276 cpy.X = r.(ast.Expr)
277 })
278
279 replace(&cpy)
280 case *ast.UnaryExpr:
281 cpy := *n
282 walkToReplace(v, cpy.X, func(r ast.Node) {
283 cpy.X = r.(ast.Expr)
284 })
285
286 replace(&cpy)
287 case *ast.BinaryExpr:
288 cpy := *n
289 walkToReplace(v, cpy.X, func(r ast.Node) {
290 cpy.X = r.(ast.Expr)
291 })
292 walkToReplace(v, cpy.Y, func(r ast.Node) {
293 cpy.Y = r.(ast.Expr)
294 })
295
296 replace(&cpy)
297 case *ast.KeyValueExpr:
298 cpy := *n
299 walkToReplace(v, cpy.Key, func(r ast.Node) {
300 cpy.Key = r.(ast.Expr)
301 })
302 walkToReplace(v, cpy.Value, func(r ast.Node) {
303 cpy.Value = r.(ast.Expr)
304 })
305
306 replace(&cpy)
307
308 // Types
309 case *ast.ArrayType:
310 cpy := *n
311 if cpy.Len != nil {
312 walkToReplace(v, cpy.Len, func(r ast.Node) {
313 cpy.Len = r.(ast.Expr)
314 })
315 }
316 walkToReplace(v, cpy.Elt, func(r ast.Node) {
317 cpy.Elt = r.(ast.Expr)
318 })
319
320 replace(&cpy)
321 case *ast.StructType:
322 cpy := *n
323 walkToReplace(v, cpy.Fields, func(r ast.Node) {
324 cpy.Fields = r.(*ast.FieldList)
325 })
326
327 replace(&cpy)
328 case *ast.FuncType:
329 cpy := *n
330 if cpy.Params != nil {
331 walkToReplace(v, cpy.Params, func(r ast.Node) {
332 cpy.Params = r.(*ast.FieldList)
333 })
334 }
335 if cpy.Results != nil {
336 walkToReplace(v, cpy.Results, func(r ast.Node) {
337 cpy.Results = r.(*ast.FieldList)
338 })
339 }
340
341 replace(&cpy)
342 case *ast.InterfaceType:
343 cpy := *n
344 walkToReplace(v, cpy.Methods, func(r ast.Node) {
345 cpy.Methods = r.(*ast.FieldList)
346 })
347
348 replace(&cpy)
349 case *ast.MapType:
350 cpy := *n
351 walkToReplace(v, cpy.Key, func(r ast.Node) {
352 cpy.Key = r.(ast.Expr)
353 })
354 walkToReplace(v, cpy.Value, func(r ast.Node) {
355 cpy.Value = r.(ast.Expr)
356 })
357
358 replace(&cpy)
359 case *ast.ChanType:
360 cpy := *n
361 walkToReplace(v, cpy.Value, func(r ast.Node) {
362 cpy.Value = r.(ast.Expr)
363 })
364
365 replace(&cpy)
366 case *ast.DeclStmt:
367 cpy := *n
368 walkToReplace(v, cpy.Decl, func(r ast.Node) {
369 cpy.Decl = r.(ast.Decl)
370 })
371
372 replace(&cpy)
373 case *ast.LabeledStmt:
374 cpy := *n
375 walkToReplace(v, cpy.Label, func(r ast.Node) {
376 cpy.Label = r.(*ast.Ident)
377 })
378 walkToReplace(v, cpy.Stmt, func(r ast.Node) {
379 cpy.Stmt = r.(ast.Stmt)
380 })
381
382 replace(&cpy)
383 case *ast.ExprStmt:
384 cpy := *n
385 walkToReplace(v, cpy.X, func(r ast.Node) {
386 cpy.X = r.(ast.Expr)
387 })
388
389 replace(&cpy)
390 case *ast.SendStmt:
391 cpy := *n
392 walkToReplace(v, cpy.Chan, func(r ast.Node) {
393 cpy.Chan = r.(ast.Expr)
394 })
395 walkToReplace(v, cpy.Value, func(r ast.Node) {
396 cpy.Value = r.(ast.Expr)
397 })
398
399 replace(&cpy)
400 case *ast.IncDecStmt:
401 cpy := *n
402 walkToReplace(v, cpy.X, func(r ast.Node) {
403 cpy.X = r.(ast.Expr)
404 })
405
406 replace(&cpy)
407 case *ast.AssignStmt:
408 cpy := *n
409 if n.Lhs != nil {
410 cpy.Lhs = make([]ast.Expr, len(n.Lhs))
411 copy(cpy.Lhs, n.Lhs)
412 }
413 if n.Rhs != nil {
414 cpy.Rhs = make([]ast.Expr, len(n.Rhs))
415 copy(cpy.Rhs, n.Rhs)
416 }
417
418 walkExprList(v, cpy.Lhs)
419 walkExprList(v, cpy.Rhs)
420
421 replace(&cpy)
422 case *ast.GoStmt:
423 cpy := *n
424 walkToReplace(v, cpy.Call, func(r ast.Node) {
425 cpy.Call = r.(*ast.CallExpr)
426 })
427
428 replace(&cpy)
429 case *ast.DeferStmt:
430 cpy := *n
431 walkToReplace(v, cpy.Call, func(r ast.Node) {
432 cpy.Call = r.(*ast.CallExpr)
433 })
434
435 replace(&cpy)
436 case *ast.ReturnStmt:
437 cpy := *n
438 if n.Results != nil {
439 cpy.Results = make([]ast.Expr, len(n.Results))
440 copy(cpy.Results, n.Results)
441 }
442
443 walkExprList(v, cpy.Results)
444
445 replace(&cpy)
446 case *ast.BranchStmt:
447 cpy := *n
448 if cpy.Label != nil {
449 walkToReplace(v, cpy.Label, func(r ast.Node) {
450 cpy.Label = r.(*ast.Ident)
451 })
452 }
453
454 replace(&cpy)
455 case *ast.BlockStmt:
456 cpy := *n
457 if n.List != nil {
458 cpy.List = make([]ast.Stmt, len(n.List))
459 copy(cpy.List, n.List)
460 }
461
462 walkStmtList(v, cpy.List)
463
464 replace(&cpy)
465 case *ast.IfStmt:
466 cpy := *n
467
468 if cpy.Init != nil {
469 walkToReplace(v, cpy.Init, func(r ast.Node) {
470 cpy.Init = r.(ast.Stmt)
471 })
472 }
473 walkToReplace(v, cpy.Cond, func(r ast.Node) {
474 cpy.Cond = r.(ast.Expr)
475 })
476 walkToReplace(v, cpy.Body, func(r ast.Node) {
477 cpy.Body = r.(*ast.BlockStmt)
478 })
479 if cpy.Else != nil {
480 walkToReplace(v, cpy.Else, func(r ast.Node) {
481 cpy.Else = r.(ast.Stmt)
482 })
483 }
484
485 replace(&cpy)
486 case *ast.CaseClause:
487 cpy := *n
488 if n.List != nil {
489 cpy.List = make([]ast.Expr, len(n.List))
490 copy(cpy.List, n.List)
491 }
492 if n.Body != nil {
493 cpy.Body = make([]ast.Stmt, len(n.Body))
494 copy(cpy.Body, n.Body)
495 }
496
497 walkExprList(v, cpy.List)
498 walkStmtList(v, cpy.Body)
499
500 replace(&cpy)
501 case *ast.SwitchStmt:
502 cpy := *n
503 if cpy.Init != nil {
504 walkToReplace(v, cpy.Init, func(r ast.Node) {
505 cpy.Init = r.(ast.Stmt)
506 })
507 }
508 if cpy.Tag != nil {
509 walkToReplace(v, cpy.Tag, func(r ast.Node) {
510 cpy.Tag = r.(ast.Expr)
511 })
512 }
513 walkToReplace(v, cpy.Body, func(r ast.Node) {
514 cpy.Body = r.(*ast.BlockStmt)
515 })
516
517 replace(&cpy)
518 case *ast.TypeSwitchStmt:
519 cpy := *n
520 if cpy.Init != nil {
521 walkToReplace(v, cpy.Init, func(r ast.Node) {
522 cpy.Init = r.(ast.Stmt)
523 })
524 }
525 walkToReplace(v, cpy.Assign, func(r ast.Node) {
526 cpy.Assign = r.(ast.Stmt)
527 })
528 walkToReplace(v, cpy.Body, func(r ast.Node) {
529 cpy.Body = r.(*ast.BlockStmt)
530 })
531
532 replace(&cpy)
533 case *ast.CommClause:
534 cpy := *n
535 if n.Body != nil {
536 cpy.Body = make([]ast.Stmt, len(n.Body))
537 copy(cpy.Body, n.Body)
538 }
539
540 if cpy.Comm != nil {
541 walkToReplace(v, cpy.Comm, func(r ast.Node) {
542 cpy.Comm = r.(ast.Stmt)
543 })
544 }
545 walkStmtList(v, cpy.Body)
546
547 replace(&cpy)
548 case *ast.SelectStmt:
549 cpy := *n
550 walkToReplace(v, cpy.Body, func(r ast.Node) {
551 cpy.Body = r.(*ast.BlockStmt)
552 })
553
554 replace(&cpy)
555 case *ast.ForStmt:
556 cpy := *n
557 if cpy.Init != nil {
558 walkToReplace(v, cpy.Init, func(r ast.Node) {
559 cpy.Init = r.(ast.Stmt)
560 })
561 }
562 if cpy.Cond != nil {
563 walkToReplace(v, cpy.Cond, func(r ast.Node) {
564 cpy.Cond = r.(ast.Expr)
565 })
566 }
567 if cpy.Post != nil {
568 walkToReplace(v, cpy.Post, func(r ast.Node) {
569 cpy.Post = r.(ast.Stmt)
570 })
571 }
572 walkToReplace(v, cpy.Body, func(r ast.Node) {
573 cpy.Body = r.(*ast.BlockStmt)
574 })
575
576 replace(&cpy)
577 case *ast.RangeStmt:
578 cpy := *n
579 if cpy.Key != nil {
580 walkToReplace(v, cpy.Key, func(r ast.Node) {
581 cpy.Key = r.(ast.Expr)
582 })
583 }
584 if cpy.Value != nil {
585 walkToReplace(v, cpy.Value, func(r ast.Node) {
586 cpy.Value = r.(ast.Expr)
587 })
588 }
589 walkToReplace(v, cpy.X, func(r ast.Node) {
590 cpy.X = r.(ast.Expr)
591 })
592 walkToReplace(v, cpy.Body, func(r ast.Node) {
593 cpy.Body = r.(*ast.BlockStmt)
594 })
595
596 // Declarations
597 replace(&cpy)
598 case *ast.ImportSpec:
599 cpy := *n
600 if cpy.Doc != nil {
601 walkToReplace(v, cpy.Doc, func(r ast.Node) {
602 cpy.Doc = r.(*ast.CommentGroup)
603 })
604 }
605 if cpy.Name != nil {
606 walkToReplace(v, cpy.Name, func(r ast.Node) {
607 cpy.Name = r.(*ast.Ident)
608 })
609 }
610 walkToReplace(v, cpy.Path, func(r ast.Node) {
611 cpy.Path = r.(*ast.BasicLit)
612 })
613 if cpy.Comment != nil {
614 walkToReplace(v, cpy.Comment, func(r ast.Node) {
615 cpy.Comment = r.(*ast.CommentGroup)
616 })
617 }
618
619 replace(&cpy)
620 case *ast.ValueSpec:
621 cpy := *n
622 if n.Names != nil {
623 cpy.Names = make([]*ast.Ident, len(n.Names))
624 copy(cpy.Names, n.Names)
625 }
626 if n.Values != nil {
627 cpy.Values = make([]ast.Expr, len(n.Values))
628 copy(cpy.Values, n.Values)
629 }
630
631 if cpy.Doc != nil {
632 walkToReplace(v, cpy.Doc, func(r ast.Node) {
633 cpy.Doc = r.(*ast.CommentGroup)
634 })
635 }
636
637 walkIdentList(v, cpy.Names)
638
639 if cpy.Type != nil {
640 walkToReplace(v, cpy.Type, func(r ast.Node) {
641 cpy.Type = r.(ast.Expr)
642 })
643 }
644
645 walkExprList(v, cpy.Values)
646
647 if cpy.Comment != nil {
648 walkToReplace(v, cpy.Comment, func(r ast.Node) {
649 cpy.Comment = r.(*ast.CommentGroup)
650 })
651 }
652
653 replace(&cpy)
654
655 case *ast.TypeSpec:
656 cpy := *n
657
658 if cpy.Doc != nil {
659 walkToReplace(v, cpy.Doc, func(r ast.Node) {
660 cpy.Doc = r.(*ast.CommentGroup)
661 })
662 }
663 walkToReplace(v, cpy.Name, func(r ast.Node) {
664 cpy.Name = r.(*ast.Ident)
665 })
666 walkToReplace(v, cpy.Type, func(r ast.Node) {
667 cpy.Type = r.(ast.Expr)
668 })
669 if cpy.Comment != nil {
670 walkToReplace(v, cpy.Comment, func(r ast.Node) {
671 cpy.Comment = r.(*ast.CommentGroup)
672 })
673 }
674
675 replace(&cpy)
676 case *ast.GenDecl:
677 cpy := *n
678 if n.Specs != nil {
679 cpy.Specs = make([]ast.Spec, len(n.Specs))
680 copy(cpy.Specs, n.Specs)
681 }
682
683 if cpy.Doc != nil {
684 walkToReplace(v, cpy.Doc, func(r ast.Node) {
685 cpy.Doc = r.(*ast.CommentGroup)
686 })
687 }
688 for i, s := range cpy.Specs {
689 walkToReplace(v, s, func(r ast.Node) {
690 cpy.Specs[i] = r.(ast.Spec)
691 })
692 }
693
694 replace(&cpy)
695 case *ast.FuncDecl:
696 cpy := *n
697
698 if cpy.Doc != nil {
699 walkToReplace(v, cpy.Doc, func(r ast.Node) {
700 cpy.Doc = r.(*ast.CommentGroup)
701 })
702 }
703 if cpy.Recv != nil {
704 walkToReplace(v, cpy.Recv, func(r ast.Node) {
705 cpy.Recv = r.(*ast.FieldList)
706 })
707 }
708 walkToReplace(v, cpy.Name, func(r ast.Node) {
709 cpy.Name = r.(*ast.Ident)
710 })
711 walkToReplace(v, cpy.Type, func(r ast.Node) {
712 cpy.Type = r.(*ast.FuncType)
713 })
714 if cpy.Body != nil {
715 walkToReplace(v, cpy.Body, func(r ast.Node) {
716 cpy.Body = r.(*ast.BlockStmt)
717 })
718 }
719
720 // Files and packages
721 replace(&cpy)
722 case *ast.File:
723 cpy := *n
724
725 if cpy.Doc != nil {
726 walkToReplace(v, cpy.Doc, func(r ast.Node) {
727 cpy.Doc = r.(*ast.CommentGroup)
728 })
729 }
730 walkToReplace(v, cpy.Name, func(r ast.Node) {
731 cpy.Name = r.(*ast.Ident)
732 })
733 walkDeclList(v, cpy.Decls)
734 // don't walk cpy.Comments - they have been
735 // visited already through the individual
736 // nodes
737
738 replace(&cpy)
739 case *ast.Package:
740 cpy := *n
741 cpy.Files = map[string]*ast.File{}
742
743 for i, f := range n.Files {
744 cpy.Files[i] = f
745 walkToReplace(v, f, func(r ast.Node) {
746 cpy.Files[i] = r.(*ast.File)
747 })
748 }
749 replace(&cpy)
750
751 default:
752 panic(fmt.Sprintf("walkToReplace: unexpected node type %T", n))
753 }
754
755 if v != nil {
756 v.Visit(nil, func(ast.Node) { panic("can't replace the go-up nil") })
757 }
758 }
+0
-53
cmd/kitgen/sourcecontext.go less more
0 package main
1
2 import (
3 "fmt"
4 "go/ast"
5 "go/token"
6 )
7
8 type sourceContext struct {
9 pkg *ast.Ident
10 imports []*ast.ImportSpec
11 interfaces []iface
12 types []*ast.TypeSpec
13 }
14
15 func (sc *sourceContext) validate() error {
16 if len(sc.interfaces) != 1 {
17 return fmt.Errorf("found %d interfaces, expecting exactly 1", len(sc.interfaces))
18 }
19 for _, i := range sc.interfaces {
20 for _, m := range i.methods {
21 if len(m.results) < 1 {
22 return fmt.Errorf("method %q of interface %q has no result types", m.name, i.name)
23 }
24 }
25 }
26 return nil
27 }
28
29 func (sc *sourceContext) importDecls() (decls []ast.Decl) {
30 have := map[string]struct{}{}
31 notHave := func(is *ast.ImportSpec) bool {
32 if _, has := have[is.Path.Value]; has {
33 return false
34 }
35 have[is.Path.Value] = struct{}{}
36 return true
37 }
38
39 for _, is := range sc.imports {
40 if notHave(is) {
41 decls = append(decls, importFor(is))
42 }
43 }
44
45 for _, is := range fetchImports() {
46 if notHave(is) {
47 decls = append(decls, &ast.GenDecl{Tok: token.IMPORT, Specs: []ast.Spec{is}})
48 }
49 }
50
51 return
52 }
+0
-60
cmd/kitgen/templates/full.go less more
0 package foo
1
2 import (
3 "context"
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/go-kit/kit/endpoint"
9 httptransport "github.com/go-kit/kit/transport/http"
10 )
11
12 type ExampleService struct {
13 }
14
15 type ExampleRequest struct {
16 I int
17 S string
18 }
19 type ExampleResponse struct {
20 S string
21 Err error
22 }
23
24 type Endpoints struct {
25 ExampleEndpoint endpoint.Endpoint
26 }
27
28 func (f ExampleService) ExampleEndpoint(ctx context.Context, i int, s string) (string, error) {
29 panic(errors.New("not implemented"))
30 }
31
32 func makeExampleEndpoint(f ExampleService) endpoint.Endpoint {
33 return func(ctx context.Context, request interface{}) (interface{}, error) {
34 req := request.(ExampleRequest)
35 s, err := f.ExampleEndpoint(ctx, req.I, req.S)
36 return ExampleResponse{S: s, Err: err}, nil
37 }
38 }
39
40 func inlineHandlerBuilder(m *http.ServeMux, endpoints Endpoints) {
41 m.Handle("/bar", httptransport.NewServer(endpoints.ExampleEndpoint, DecodeExampleRequest, EncodeExampleResponse))
42 }
43
44 func NewHTTPHandler(endpoints Endpoints) http.Handler {
45 m := http.NewServeMux()
46 inlineHandlerBuilder(m, endpoints)
47 return m
48 }
49
50 func DecodeExampleRequest(_ context.Context, r *http.Request) (interface{}, error) {
51 var req ExampleRequest
52 err := json.NewDecoder(r.Body).Decode(&req)
53 return req, err
54 }
55
56 func EncodeExampleResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
57 w.Header().Set("Content-Type", "application/json; charset=utf-8")
58 return json.NewEncoder(w).Encode(response)
59 }
+0
-29
cmd/kitgen/testdata/anonfields/default/endpoints/endpoints.go less more
0 package endpoints
1
2 import (
3 "context"
4
5 "github.com/go-kit/kit/cmd/kitgen/testdata/anonfields/default/service"
6 "github.com/go-kit/kit/endpoint"
7 )
8
9 type FooRequest struct {
10 I int
11 S string
12 }
13 type FooResponse struct {
14 I int
15 Err error
16 }
17
18 func MakeFooEndpoint(s service.Service) endpoint.Endpoint {
19 return func(ctx context.Context, request interface{}) (interface{}, error) {
20 req := request.(FooRequest)
21 i, err := s.Foo(ctx, req.I, req.S)
22 return FooResponse{I: i, Err: err}, nil
23 }
24 }
25
26 type Endpoints struct {
27 Foo endpoint.Endpoint
28 }
+0
-25
cmd/kitgen/testdata/anonfields/default/http/http.go less more
0 package http
1
2 import (
3 "context"
4 "encoding/json"
5 "net/http"
6
7 "github.com/go-kit/kit/cmd/kitgen/testdata/anonfields/default/endpoints"
8 httptransport "github.com/go-kit/kit/transport/http"
9 )
10
11 func NewHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
12 m := http.NewServeMux()
13 m.Handle("/foo", httptransport.NewServer(endpoints.Foo, DecodeFooRequest, EncodeFooResponse))
14 return m
15 }
16 func DecodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
17 var req endpoints.FooRequest
18 err := json.NewDecoder(r.Body).Decode(&req)
19 return req, err
20 }
21 func EncodeFooResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
22 w.Header().Set("Content-Type", "application/json; charset=utf-8")
23 return json.NewEncoder(w).Encode(response)
24 }
+0
-13
cmd/kitgen/testdata/anonfields/default/service/service.go less more
0 package service
1
2 import (
3 "context"
4 "errors"
5 )
6
7 type Service struct {
8 }
9
10 func (s Service) Foo(ctx context.Context, i int, string1 string) (int, error) {
11 panic(errors.New("not implemented"))
12 }
+0
-55
cmd/kitgen/testdata/anonfields/flat/gokit.go less more
0 package foo
1
2 import (
3 "context"
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/go-kit/kit/endpoint"
9
10 httptransport "github.com/go-kit/kit/transport/http"
11 )
12
13 type Service struct {
14 }
15
16 func (s Service) Foo(ctx context.Context, i int, string1 string) (int, error) {
17 panic(errors.New("not implemented"))
18 }
19
20 type FooRequest struct {
21 I int
22 S string
23 }
24 type FooResponse struct {
25 I int
26 Err error
27 }
28
29 func MakeFooEndpoint(s Service) endpoint.Endpoint {
30 return func(ctx context.Context, request interface{}) (interface{}, error) {
31 req := request.(FooRequest)
32 i, err := s.Foo(ctx, req.I, req.S)
33 return FooResponse{I: i, Err: err}, nil
34 }
35 }
36
37 type Endpoints struct {
38 Foo endpoint.Endpoint
39 }
40
41 func NewHTTPHandler(endpoints Endpoints) http.Handler {
42 m := http.NewServeMux()
43 m.Handle("/foo", httptransport.NewServer(endpoints.Foo, DecodeFooRequest, EncodeFooResponse))
44 return m
45 }
46 func DecodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
47 var req FooRequest
48 err := json.NewDecoder(r.Body).Decode(&req)
49 return req, err
50 }
51 func EncodeFooResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
52 w.Header().Set("Content-Type", "application/json; charset=utf-8")
53 return json.NewEncoder(w).Encode(response)
54 }
+0
-6
cmd/kitgen/testdata/anonfields/in.go less more
0 package foo
1
2 // from https://github.com/go-kit/kit/pull/589#issuecomment-319937530
3 type Service interface {
4 Foo(context.Context, int, string) (int, error)
5 }
+0
-29
cmd/kitgen/testdata/foo/default/endpoints/endpoints.go less more
0 package endpoints
1
2 import (
3 "context"
4
5 "github.com/go-kit/kit/cmd/kitgen/testdata/foo/default/service"
6 "github.com/go-kit/kit/endpoint"
7 )
8
9 type BarRequest struct {
10 I int
11 S string
12 }
13 type BarResponse struct {
14 S string
15 Err error
16 }
17
18 func MakeBarEndpoint(f service.FooService) endpoint.Endpoint {
19 return func(ctx context.Context, request interface{}) (interface{}, error) {
20 req := request.(BarRequest)
21 s, err := f.Bar(ctx, req.I, req.S)
22 return BarResponse{S: s, Err: err}, nil
23 }
24 }
25
26 type Endpoints struct {
27 Bar endpoint.Endpoint
28 }
+0
-25
cmd/kitgen/testdata/foo/default/http/http.go less more
0 package http
1
2 import (
3 "context"
4 "encoding/json"
5 "net/http"
6
7 "github.com/go-kit/kit/cmd/kitgen/testdata/foo/default/endpoints"
8 httptransport "github.com/go-kit/kit/transport/http"
9 )
10
11 func NewHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
12 m := http.NewServeMux()
13 m.Handle("/bar", httptransport.NewServer(endpoints.Bar, DecodeBarRequest, EncodeBarResponse))
14 return m
15 }
16 func DecodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
17 var req endpoints.BarRequest
18 err := json.NewDecoder(r.Body).Decode(&req)
19 return req, err
20 }
21 func EncodeBarResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
22 w.Header().Set("Content-Type", "application/json; charset=utf-8")
23 return json.NewEncoder(w).Encode(response)
24 }
+0
-13
cmd/kitgen/testdata/foo/default/service/service.go less more
0 package service
1
2 import (
3 "context"
4 "errors"
5 )
6
7 type FooService struct {
8 }
9
10 func (f FooService) Bar(ctx context.Context, i int, s string) (string, error) {
11 panic(errors.New("not implemented"))
12 }
+0
-55
cmd/kitgen/testdata/foo/flat/gokit.go less more
0 package foo
1
2 import (
3 "context"
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/go-kit/kit/endpoint"
9
10 httptransport "github.com/go-kit/kit/transport/http"
11 )
12
13 type FooService struct {
14 }
15
16 func (f FooService) Bar(ctx context.Context, i int, s string) (string, error) {
17 panic(errors.New("not implemented"))
18 }
19
20 type BarRequest struct {
21 I int
22 S string
23 }
24 type BarResponse struct {
25 S string
26 Err error
27 }
28
29 func MakeBarEndpoint(f FooService) endpoint.Endpoint {
30 return func(ctx context.Context, request interface{}) (interface{}, error) {
31 req := request.(BarRequest)
32 s, err := f.Bar(ctx, req.I, req.S)
33 return BarResponse{S: s, Err: err}, nil
34 }
35 }
36
37 type Endpoints struct {
38 Bar endpoint.Endpoint
39 }
40
41 func NewHTTPHandler(endpoints Endpoints) http.Handler {
42 m := http.NewServeMux()
43 m.Handle("/bar", httptransport.NewServer(endpoints.Bar, DecodeBarRequest, EncodeBarResponse))
44 return m
45 }
46 func DecodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
47 var req BarRequest
48 err := json.NewDecoder(r.Body).Decode(&req)
49 return req, err
50 }
51 func EncodeBarResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
52 w.Header().Set("Content-Type", "application/json; charset=utf-8")
53 return json.NewEncoder(w).Encode(response)
54 }
+0
-5
cmd/kitgen/testdata/foo/in.go less more
0 package foo
1
2 type FooService interface {
3 Bar(ctx context.Context, i int, s string) (string, error)
4 }
+0
-163
cmd/kitgen/testdata/profilesvc/default/endpoints/endpoints.go less more
0 package endpoints
1
2 import (
3 "context"
4
5 "github.com/go-kit/kit/cmd/kitgen/testdata/profilesvc/default/service"
6 "github.com/go-kit/kit/endpoint"
7 )
8
9 type PostProfileRequest struct {
10 P service.Profile
11 }
12 type PostProfileResponse struct {
13 Err error
14 }
15
16 func MakePostProfileEndpoint(s service.Service) endpoint.Endpoint {
17 return func(ctx context.Context, request interface{}) (interface{}, error) {
18 req := request.(PostProfileRequest)
19 err := s.PostProfile(ctx, req.P)
20 return PostProfileResponse{Err: err}, nil
21 }
22 }
23
24 type GetProfileRequest struct {
25 Id string
26 }
27 type GetProfileResponse struct {
28 P service.Profile
29 Err error
30 }
31
32 func MakeGetProfileEndpoint(s service.Service) endpoint.Endpoint {
33 return func(ctx context.Context, request interface{}) (interface{}, error) {
34 req := request.(GetProfileRequest)
35 P, err := s.GetProfile(ctx, req.Id)
36 return GetProfileResponse{P: P, Err: err}, nil
37 }
38 }
39
40 type PutProfileRequest struct {
41 Id string
42 P service.Profile
43 }
44 type PutProfileResponse struct {
45 Err error
46 }
47
48 func MakePutProfileEndpoint(s service.Service) endpoint.Endpoint {
49 return func(ctx context.Context, request interface{}) (interface{}, error) {
50 req := request.(PutProfileRequest)
51 err := s.PutProfile(ctx, req.Id, req.P)
52 return PutProfileResponse{Err: err}, nil
53 }
54 }
55
56 type PatchProfileRequest struct {
57 Id string
58 P service.Profile
59 }
60 type PatchProfileResponse struct {
61 Err error
62 }
63
64 func MakePatchProfileEndpoint(s service.Service) endpoint.Endpoint {
65 return func(ctx context.Context, request interface{}) (interface{}, error) {
66 req := request.(PatchProfileRequest)
67 err := s.PatchProfile(ctx, req.Id, req.P)
68 return PatchProfileResponse{Err: err}, nil
69 }
70 }
71
72 type DeleteProfileRequest struct {
73 Id string
74 }
75 type DeleteProfileResponse struct {
76 Err error
77 }
78
79 func MakeDeleteProfileEndpoint(s service.Service) endpoint.Endpoint {
80 return func(ctx context.Context, request interface{}) (interface{}, error) {
81 req := request.(DeleteProfileRequest)
82 err := s.DeleteProfile(ctx, req.Id)
83 return DeleteProfileResponse{Err: err}, nil
84 }
85 }
86
87 type GetAddressesRequest struct {
88 ProfileID string
89 }
90 type GetAddressesResponse struct {
91 S []service.Address
92 Err error
93 }
94
95 func MakeGetAddressesEndpoint(s service.Service) endpoint.Endpoint {
96 return func(ctx context.Context, request interface{}) (interface{}, error) {
97 req := request.(GetAddressesRequest)
98 slice1, err := s.GetAddresses(ctx, req.ProfileID)
99 return GetAddressesResponse{S: slice1, Err: err}, nil
100 }
101 }
102
103 type GetAddressRequest struct {
104 ProfileID string
105 AddressID string
106 }
107 type GetAddressResponse struct {
108 A service.Address
109 Err error
110 }
111
112 func MakeGetAddressEndpoint(s service.Service) endpoint.Endpoint {
113 return func(ctx context.Context, request interface{}) (interface{}, error) {
114 req := request.(GetAddressRequest)
115 A, err := s.GetAddress(ctx, req.ProfileID, req.AddressID)
116 return GetAddressResponse{A: A, Err: err}, nil
117 }
118 }
119
120 type PostAddressRequest struct {
121 ProfileID string
122 A service.Address
123 }
124 type PostAddressResponse struct {
125 Err error
126 }
127
128 func MakePostAddressEndpoint(s service.Service) endpoint.Endpoint {
129 return func(ctx context.Context, request interface{}) (interface{}, error) {
130 req := request.(PostAddressRequest)
131 err := s.PostAddress(ctx, req.ProfileID, req.A)
132 return PostAddressResponse{Err: err}, nil
133 }
134 }
135
136 type DeleteAddressRequest struct {
137 ProfileID string
138 AddressID string
139 }
140 type DeleteAddressResponse struct {
141 Err error
142 }
143
144 func MakeDeleteAddressEndpoint(s service.Service) endpoint.Endpoint {
145 return func(ctx context.Context, request interface{}) (interface{}, error) {
146 req := request.(DeleteAddressRequest)
147 err := s.DeleteAddress(ctx, req.ProfileID, req.AddressID)
148 return DeleteAddressResponse{Err: err}, nil
149 }
150 }
151
152 type Endpoints struct {
153 PostProfile endpoint.Endpoint
154 GetProfile endpoint.Endpoint
155 PutProfile endpoint.Endpoint
156 PatchProfile endpoint.Endpoint
157 DeleteProfile endpoint.Endpoint
158 GetAddresses endpoint.Endpoint
159 GetAddress endpoint.Endpoint
160 PostAddress endpoint.Endpoint
161 DeleteAddress endpoint.Endpoint
162 }
+0
-105
cmd/kitgen/testdata/profilesvc/default/http/http.go less more
0 package http
1
2 import (
3 "context"
4 "encoding/json"
5 "net/http"
6
7 "github.com/go-kit/kit/cmd/kitgen/testdata/profilesvc/default/endpoints"
8 httptransport "github.com/go-kit/kit/transport/http"
9 )
10
11 func NewHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
12 m := http.NewServeMux()
13 m.Handle("/postprofile", httptransport.NewServer(endpoints.PostProfile, DecodePostProfileRequest, EncodePostProfileResponse))
14 m.Handle("/getprofile", httptransport.NewServer(endpoints.GetProfile, DecodeGetProfileRequest, EncodeGetProfileResponse))
15 m.Handle("/putprofile", httptransport.NewServer(endpoints.PutProfile, DecodePutProfileRequest, EncodePutProfileResponse))
16 m.Handle("/patchprofile", httptransport.NewServer(endpoints.PatchProfile, DecodePatchProfileRequest, EncodePatchProfileResponse))
17 m.Handle("/deleteprofile", httptransport.NewServer(endpoints.DeleteProfile, DecodeDeleteProfileRequest, EncodeDeleteProfileResponse))
18 m.Handle("/getaddresses", httptransport.NewServer(endpoints.GetAddresses, DecodeGetAddressesRequest, EncodeGetAddressesResponse))
19 m.Handle("/getaddress", httptransport.NewServer(endpoints.GetAddress, DecodeGetAddressRequest, EncodeGetAddressResponse))
20 m.Handle("/postaddress", httptransport.NewServer(endpoints.PostAddress, DecodePostAddressRequest, EncodePostAddressResponse))
21 m.Handle("/deleteaddress", httptransport.NewServer(endpoints.DeleteAddress, DecodeDeleteAddressRequest, EncodeDeleteAddressResponse))
22 return m
23 }
24 func DecodePostProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
25 var req endpoints.PostProfileRequest
26 err := json.NewDecoder(r.Body).Decode(&req)
27 return req, err
28 }
29 func EncodePostProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
30 w.Header().Set("Content-Type", "application/json; charset=utf-8")
31 return json.NewEncoder(w).Encode(response)
32 }
33 func DecodeGetProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
34 var req endpoints.GetProfileRequest
35 err := json.NewDecoder(r.Body).Decode(&req)
36 return req, err
37 }
38 func EncodeGetProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
39 w.Header().Set("Content-Type", "application/json; charset=utf-8")
40 return json.NewEncoder(w).Encode(response)
41 }
42 func DecodePutProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
43 var req endpoints.PutProfileRequest
44 err := json.NewDecoder(r.Body).Decode(&req)
45 return req, err
46 }
47 func EncodePutProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
48 w.Header().Set("Content-Type", "application/json; charset=utf-8")
49 return json.NewEncoder(w).Encode(response)
50 }
51 func DecodePatchProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
52 var req endpoints.PatchProfileRequest
53 err := json.NewDecoder(r.Body).Decode(&req)
54 return req, err
55 }
56 func EncodePatchProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
57 w.Header().Set("Content-Type", "application/json; charset=utf-8")
58 return json.NewEncoder(w).Encode(response)
59 }
60 func DecodeDeleteProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
61 var req endpoints.DeleteProfileRequest
62 err := json.NewDecoder(r.Body).Decode(&req)
63 return req, err
64 }
65 func EncodeDeleteProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
66 w.Header().Set("Content-Type", "application/json; charset=utf-8")
67 return json.NewEncoder(w).Encode(response)
68 }
69 func DecodeGetAddressesRequest(_ context.Context, r *http.Request) (interface{}, error) {
70 var req endpoints.GetAddressesRequest
71 err := json.NewDecoder(r.Body).Decode(&req)
72 return req, err
73 }
74 func EncodeGetAddressesResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
75 w.Header().Set("Content-Type", "application/json; charset=utf-8")
76 return json.NewEncoder(w).Encode(response)
77 }
78 func DecodeGetAddressRequest(_ context.Context, r *http.Request) (interface{}, error) {
79 var req endpoints.GetAddressRequest
80 err := json.NewDecoder(r.Body).Decode(&req)
81 return req, err
82 }
83 func EncodeGetAddressResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
84 w.Header().Set("Content-Type", "application/json; charset=utf-8")
85 return json.NewEncoder(w).Encode(response)
86 }
87 func DecodePostAddressRequest(_ context.Context, r *http.Request) (interface{}, error) {
88 var req endpoints.PostAddressRequest
89 err := json.NewDecoder(r.Body).Decode(&req)
90 return req, err
91 }
92 func EncodePostAddressResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
93 w.Header().Set("Content-Type", "application/json; charset=utf-8")
94 return json.NewEncoder(w).Encode(response)
95 }
96 func DecodeDeleteAddressRequest(_ context.Context, r *http.Request) (interface{}, error) {
97 var req endpoints.DeleteAddressRequest
98 err := json.NewDecoder(r.Body).Decode(&req)
99 return req, err
100 }
101 func EncodeDeleteAddressResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
102 w.Header().Set("Content-Type", "application/json; charset=utf-8")
103 return json.NewEncoder(w).Encode(response)
104 }
+0
-46
cmd/kitgen/testdata/profilesvc/default/service/service.go less more
0 package service
1
2 import (
3 "context"
4 "errors"
5 )
6
7 type Profile struct {
8 ID string `json:"id"`
9 Name string `json:"name,omitempty"`
10 Addresses []Address `json:"addresses,omitempty"`
11 }
12 type Address struct {
13 ID string `json:"id"`
14 Location string `json:"location,omitempty"`
15 }
16 type Service struct {
17 }
18
19 func (s Service) PostProfile(ctx context.Context, p Profile) error {
20 panic(errors.New("not implemented"))
21 }
22 func (s Service) GetProfile(ctx context.Context, id string) (Profile, error) {
23 panic(errors.New("not implemented"))
24 }
25 func (s Service) PutProfile(ctx context.Context, id string, p Profile) error {
26 panic(errors.New("not implemented"))
27 }
28 func (s Service) PatchProfile(ctx context.Context, id string, p Profile) error {
29 panic(errors.New("not implemented"))
30 }
31 func (s Service) DeleteProfile(ctx context.Context, id string) error {
32 panic(errors.New("not implemented"))
33 }
34 func (s Service) GetAddresses(ctx context.Context, profileID string) ([]Address, error) {
35 panic(errors.New("not implemented"))
36 }
37 func (s Service) GetAddress(ctx context.Context, profileID string, addressID string) (Address, error) {
38 panic(errors.New("not implemented"))
39 }
40 func (s Service) PostAddress(ctx context.Context, profileID string, a Address) error {
41 panic(errors.New("not implemented"))
42 }
43 func (s Service) DeleteAddress(ctx context.Context, profileID string, addressID string) error {
44 panic(errors.New("not implemented"))
45 }
+0
-302
cmd/kitgen/testdata/profilesvc/flat/gokit.go less more
0 package profilesvc
1
2 import (
3 "context"
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/go-kit/kit/endpoint"
9
10 httptransport "github.com/go-kit/kit/transport/http"
11 )
12
13 type Profile struct {
14 ID string `json:"id"`
15 Name string `json:"name,omitempty"`
16 Addresses []Address `json:"addresses,omitempty"`
17 }
18 type Address struct {
19 ID string `json:"id"`
20 Location string `json:"location,omitempty"`
21 }
22 type Service struct {
23 }
24
25 func (s Service) PostProfile(ctx context.Context, p Profile) error {
26 panic(errors.New("not implemented"))
27 }
28
29 type PostProfileRequest struct {
30 P Profile
31 }
32 type PostProfileResponse struct {
33 Err error
34 }
35
36 func MakePostProfileEndpoint(s Service) endpoint.Endpoint {
37 return func(ctx context.Context, request interface{}) (interface{}, error) {
38 req := request.(PostProfileRequest)
39 err := s.PostProfile(ctx, req.P)
40 return PostProfileResponse{Err: err}, nil
41 }
42 }
43 func (s Service) GetProfile(ctx context.Context, id string) (Profile, error) {
44 panic(errors.New("not implemented"))
45 }
46
47 type GetProfileRequest struct {
48 Id string
49 }
50 type GetProfileResponse struct {
51 P Profile
52 Err error
53 }
54
55 func MakeGetProfileEndpoint(s Service) endpoint.Endpoint {
56 return func(ctx context.Context, request interface{}) (interface{}, error) {
57 req := request.(GetProfileRequest)
58 P, err := s.GetProfile(ctx, req.Id)
59 return GetProfileResponse{P: P, Err: err}, nil
60 }
61 }
62 func (s Service) PutProfile(ctx context.Context, id string, p Profile) error {
63 panic(errors.New("not implemented"))
64 }
65
66 type PutProfileRequest struct {
67 Id string
68 P Profile
69 }
70 type PutProfileResponse struct {
71 Err error
72 }
73
74 func MakePutProfileEndpoint(s Service) endpoint.Endpoint {
75 return func(ctx context.Context, request interface{}) (interface{}, error) {
76 req := request.(PutProfileRequest)
77 err := s.PutProfile(ctx, req.Id, req.P)
78 return PutProfileResponse{Err: err}, nil
79 }
80 }
81 func (s Service) PatchProfile(ctx context.Context, id string, p Profile) error {
82 panic(errors.New("not implemented"))
83 }
84
85 type PatchProfileRequest struct {
86 Id string
87 P Profile
88 }
89 type PatchProfileResponse struct {
90 Err error
91 }
92
93 func MakePatchProfileEndpoint(s Service) endpoint.Endpoint {
94 return func(ctx context.Context, request interface{}) (interface{}, error) {
95 req := request.(PatchProfileRequest)
96 err := s.PatchProfile(ctx, req.Id, req.P)
97 return PatchProfileResponse{Err: err}, nil
98 }
99 }
100 func (s Service) DeleteProfile(ctx context.Context, id string) error {
101 panic(errors.New("not implemented"))
102 }
103
104 type DeleteProfileRequest struct {
105 Id string
106 }
107 type DeleteProfileResponse struct {
108 Err error
109 }
110
111 func MakeDeleteProfileEndpoint(s Service) endpoint.Endpoint {
112 return func(ctx context.Context, request interface{}) (interface{}, error) {
113 req := request.(DeleteProfileRequest)
114 err := s.DeleteProfile(ctx, req.Id)
115 return DeleteProfileResponse{Err: err}, nil
116 }
117 }
118 func (s Service) GetAddresses(ctx context.Context, profileID string) ([]Address, error) {
119 panic(errors.New("not implemented"))
120 }
121
122 type GetAddressesRequest struct {
123 ProfileID string
124 }
125 type GetAddressesResponse struct {
126 S []Address
127 Err error
128 }
129
130 func MakeGetAddressesEndpoint(s Service) endpoint.Endpoint {
131 return func(ctx context.Context, request interface{}) (interface{}, error) {
132 req := request.(GetAddressesRequest)
133 slice1, err := s.GetAddresses(ctx, req.ProfileID)
134 return GetAddressesResponse{S: slice1, Err: err}, nil
135 }
136 }
137 func (s Service) GetAddress(ctx context.Context, profileID string, addressID string) (Address, error) {
138 panic(errors.New("not implemented"))
139 }
140
141 type GetAddressRequest struct {
142 ProfileID string
143 AddressID string
144 }
145 type GetAddressResponse struct {
146 A Address
147 Err error
148 }
149
150 func MakeGetAddressEndpoint(s Service) endpoint.Endpoint {
151 return func(ctx context.Context, request interface{}) (interface{}, error) {
152 req := request.(GetAddressRequest)
153 A, err := s.GetAddress(ctx, req.ProfileID, req.AddressID)
154 return GetAddressResponse{A: A, Err: err}, nil
155 }
156 }
157 func (s Service) PostAddress(ctx context.Context, profileID string, a Address) error {
158 panic(errors.New("not implemented"))
159 }
160
161 type PostAddressRequest struct {
162 ProfileID string
163 A Address
164 }
165 type PostAddressResponse struct {
166 Err error
167 }
168
169 func MakePostAddressEndpoint(s Service) endpoint.Endpoint {
170 return func(ctx context.Context, request interface{}) (interface{}, error) {
171 req := request.(PostAddressRequest)
172 err := s.PostAddress(ctx, req.ProfileID, req.A)
173 return PostAddressResponse{Err: err}, nil
174 }
175 }
176 func (s Service) DeleteAddress(ctx context.Context, profileID string, addressID string) error {
177 panic(errors.New("not implemented"))
178 }
179
180 type DeleteAddressRequest struct {
181 ProfileID string
182 AddressID string
183 }
184 type DeleteAddressResponse struct {
185 Err error
186 }
187
188 func MakeDeleteAddressEndpoint(s Service) endpoint.Endpoint {
189 return func(ctx context.Context, request interface{}) (interface{}, error) {
190 req := request.(DeleteAddressRequest)
191 err := s.DeleteAddress(ctx, req.ProfileID, req.AddressID)
192 return DeleteAddressResponse{Err: err}, nil
193 }
194 }
195
196 type Endpoints struct {
197 PostProfile endpoint.Endpoint
198 GetProfile endpoint.Endpoint
199 PutProfile endpoint.Endpoint
200 PatchProfile endpoint.Endpoint
201 DeleteProfile endpoint.Endpoint
202 GetAddresses endpoint.Endpoint
203 GetAddress endpoint.Endpoint
204 PostAddress endpoint.Endpoint
205 DeleteAddress endpoint.Endpoint
206 }
207
208 func NewHTTPHandler(endpoints Endpoints) http.Handler {
209 m := http.NewServeMux()
210 m.Handle("/postprofile", httptransport.NewServer(endpoints.PostProfile, DecodePostProfileRequest, EncodePostProfileResponse))
211 m.Handle("/getprofile", httptransport.NewServer(endpoints.GetProfile, DecodeGetProfileRequest, EncodeGetProfileResponse))
212 m.Handle("/putprofile", httptransport.NewServer(endpoints.PutProfile, DecodePutProfileRequest, EncodePutProfileResponse))
213 m.Handle("/patchprofile", httptransport.NewServer(endpoints.PatchProfile, DecodePatchProfileRequest, EncodePatchProfileResponse))
214 m.Handle("/deleteprofile", httptransport.NewServer(endpoints.DeleteProfile, DecodeDeleteProfileRequest, EncodeDeleteProfileResponse))
215 m.Handle("/getaddresses", httptransport.NewServer(endpoints.GetAddresses, DecodeGetAddressesRequest, EncodeGetAddressesResponse))
216 m.Handle("/getaddress", httptransport.NewServer(endpoints.GetAddress, DecodeGetAddressRequest, EncodeGetAddressResponse))
217 m.Handle("/postaddress", httptransport.NewServer(endpoints.PostAddress, DecodePostAddressRequest, EncodePostAddressResponse))
218 m.Handle("/deleteaddress", httptransport.NewServer(endpoints.DeleteAddress, DecodeDeleteAddressRequest, EncodeDeleteAddressResponse))
219 return m
220 }
221 func DecodePostProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
222 var req PostProfileRequest
223 err := json.NewDecoder(r.Body).Decode(&req)
224 return req, err
225 }
226 func EncodePostProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
227 w.Header().Set("Content-Type", "application/json; charset=utf-8")
228 return json.NewEncoder(w).Encode(response)
229 }
230 func DecodeGetProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
231 var req GetProfileRequest
232 err := json.NewDecoder(r.Body).Decode(&req)
233 return req, err
234 }
235 func EncodeGetProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
236 w.Header().Set("Content-Type", "application/json; charset=utf-8")
237 return json.NewEncoder(w).Encode(response)
238 }
239 func DecodePutProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
240 var req PutProfileRequest
241 err := json.NewDecoder(r.Body).Decode(&req)
242 return req, err
243 }
244 func EncodePutProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
245 w.Header().Set("Content-Type", "application/json; charset=utf-8")
246 return json.NewEncoder(w).Encode(response)
247 }
248 func DecodePatchProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
249 var req PatchProfileRequest
250 err := json.NewDecoder(r.Body).Decode(&req)
251 return req, err
252 }
253 func EncodePatchProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
254 w.Header().Set("Content-Type", "application/json; charset=utf-8")
255 return json.NewEncoder(w).Encode(response)
256 }
257 func DecodeDeleteProfileRequest(_ context.Context, r *http.Request) (interface{}, error) {
258 var req DeleteProfileRequest
259 err := json.NewDecoder(r.Body).Decode(&req)
260 return req, err
261 }
262 func EncodeDeleteProfileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
263 w.Header().Set("Content-Type", "application/json; charset=utf-8")
264 return json.NewEncoder(w).Encode(response)
265 }
266 func DecodeGetAddressesRequest(_ context.Context, r *http.Request) (interface{}, error) {
267 var req GetAddressesRequest
268 err := json.NewDecoder(r.Body).Decode(&req)
269 return req, err
270 }
271 func EncodeGetAddressesResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
272 w.Header().Set("Content-Type", "application/json; charset=utf-8")
273 return json.NewEncoder(w).Encode(response)
274 }
275 func DecodeGetAddressRequest(_ context.Context, r *http.Request) (interface{}, error) {
276 var req GetAddressRequest
277 err := json.NewDecoder(r.Body).Decode(&req)
278 return req, err
279 }
280 func EncodeGetAddressResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
281 w.Header().Set("Content-Type", "application/json; charset=utf-8")
282 return json.NewEncoder(w).Encode(response)
283 }
284 func DecodePostAddressRequest(_ context.Context, r *http.Request) (interface{}, error) {
285 var req PostAddressRequest
286 err := json.NewDecoder(r.Body).Decode(&req)
287 return req, err
288 }
289 func EncodePostAddressResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
290 w.Header().Set("Content-Type", "application/json; charset=utf-8")
291 return json.NewEncoder(w).Encode(response)
292 }
293 func DecodeDeleteAddressRequest(_ context.Context, r *http.Request) (interface{}, error) {
294 var req DeleteAddressRequest
295 err := json.NewDecoder(r.Body).Decode(&req)
296 return req, err
297 }
298 func EncodeDeleteAddressResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
299 w.Header().Set("Content-Type", "application/json; charset=utf-8")
300 return json.NewEncoder(w).Encode(response)
301 }
+0
-24
cmd/kitgen/testdata/profilesvc/in.go less more
0 package profilesvc
1
2 type Service interface {
3 PostProfile(ctx context.Context, p Profile) error
4 GetProfile(ctx context.Context, id string) (Profile, error)
5 PutProfile(ctx context.Context, id string, p Profile) error
6 PatchProfile(ctx context.Context, id string, p Profile) error
7 DeleteProfile(ctx context.Context, id string) error
8 GetAddresses(ctx context.Context, profileID string) ([]Address, error)
9 GetAddress(ctx context.Context, profileID string, addressID string) (Address, error)
10 PostAddress(ctx context.Context, profileID string, a Address) error
11 DeleteAddress(ctx context.Context, profileID string, addressID string) error
12 }
13
14 type Profile struct {
15 ID string `json:"id"`
16 Name string `json:"name,omitempty"`
17 Addresses []Address `json:"addresses,omitempty"`
18 }
19
20 type Address struct {
21 ID string `json:"id"`
22 Location string `json:"location,omitempty"`
23 }
+0
-45
cmd/kitgen/testdata/stringservice/default/endpoints/endpoints.go less more
0 package endpoints
1
2 import (
3 "context"
4
5 "github.com/go-kit/kit/cmd/kitgen/testdata/stringservice/default/service"
6 "github.com/go-kit/kit/endpoint"
7 )
8
9 type ConcatRequest struct {
10 A string
11 B string
12 }
13 type ConcatResponse struct {
14 S string
15 Err error
16 }
17
18 func MakeConcatEndpoint(s service.Service) endpoint.Endpoint {
19 return func(ctx context.Context, request interface{}) (interface{}, error) {
20 req := request.(ConcatRequest)
21 string1, err := s.Concat(ctx, req.A, req.B)
22 return ConcatResponse{S: string1, Err: err}, nil
23 }
24 }
25
26 type CountRequest struct {
27 S string
28 }
29 type CountResponse struct {
30 Count int
31 }
32
33 func MakeCountEndpoint(s service.Service) endpoint.Endpoint {
34 return func(ctx context.Context, request interface{}) (interface{}, error) {
35 req := request.(CountRequest)
36 count := s.Count(ctx, req.S)
37 return CountResponse{Count: count}, nil
38 }
39 }
40
41 type Endpoints struct {
42 Concat endpoint.Endpoint
43 Count endpoint.Endpoint
44 }
+0
-35
cmd/kitgen/testdata/stringservice/default/http/http.go less more
0 package http
1
2 import (
3 "context"
4 "encoding/json"
5 "net/http"
6
7 "github.com/go-kit/kit/cmd/kitgen/testdata/stringservice/default/endpoints"
8 httptransport "github.com/go-kit/kit/transport/http"
9 )
10
11 func NewHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
12 m := http.NewServeMux()
13 m.Handle("/concat", httptransport.NewServer(endpoints.Concat, DecodeConcatRequest, EncodeConcatResponse))
14 m.Handle("/count", httptransport.NewServer(endpoints.Count, DecodeCountRequest, EncodeCountResponse))
15 return m
16 }
17 func DecodeConcatRequest(_ context.Context, r *http.Request) (interface{}, error) {
18 var req endpoints.ConcatRequest
19 err := json.NewDecoder(r.Body).Decode(&req)
20 return req, err
21 }
22 func EncodeConcatResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
23 w.Header().Set("Content-Type", "application/json; charset=utf-8")
24 return json.NewEncoder(w).Encode(response)
25 }
26 func DecodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
27 var req endpoints.CountRequest
28 err := json.NewDecoder(r.Body).Decode(&req)
29 return req, err
30 }
31 func EncodeCountResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
32 w.Header().Set("Content-Type", "application/json; charset=utf-8")
33 return json.NewEncoder(w).Encode(response)
34 }
+0
-16
cmd/kitgen/testdata/stringservice/default/service/service.go less more
0 package service
1
2 import (
3 "context"
4 "errors"
5 )
6
7 type Service struct {
8 }
9
10 func (s Service) Concat(ctx context.Context, a string, b string) (string, error) {
11 panic(errors.New("not implemented"))
12 }
13 func (s Service) Count(ctx context.Context, string1 string) int {
14 panic(errors.New("not implemented"))
15 }
+0
-84
cmd/kitgen/testdata/stringservice/flat/gokit.go less more
0 package foo
1
2 import (
3 "context"
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/go-kit/kit/endpoint"
9
10 httptransport "github.com/go-kit/kit/transport/http"
11 )
12
13 type Service struct {
14 }
15
16 func (s Service) Concat(ctx context.Context, a string, b string) (string, error) {
17 panic(errors.New("not implemented"))
18 }
19
20 type ConcatRequest struct {
21 A string
22 B string
23 }
24 type ConcatResponse struct {
25 S string
26 Err error
27 }
28
29 func MakeConcatEndpoint(s Service) endpoint.Endpoint {
30 return func(ctx context.Context, request interface{}) (interface{}, error) {
31 req := request.(ConcatRequest)
32 string1, err := s.Concat(ctx, req.A, req.B)
33 return ConcatResponse{S: string1, Err: err}, nil
34 }
35 }
36 func (s Service) Count(ctx context.Context, string1 string) int {
37 panic(errors.New("not implemented"))
38 }
39
40 type CountRequest struct {
41 S string
42 }
43 type CountResponse struct {
44 Count int
45 }
46
47 func MakeCountEndpoint(s Service) endpoint.Endpoint {
48 return func(ctx context.Context, request interface{}) (interface{}, error) {
49 req := request.(CountRequest)
50 count := s.Count(ctx, req.S)
51 return CountResponse{Count: count}, nil
52 }
53 }
54
55 type Endpoints struct {
56 Concat endpoint.Endpoint
57 Count endpoint.Endpoint
58 }
59
60 func NewHTTPHandler(endpoints Endpoints) http.Handler {
61 m := http.NewServeMux()
62 m.Handle("/concat", httptransport.NewServer(endpoints.Concat, DecodeConcatRequest, EncodeConcatResponse))
63 m.Handle("/count", httptransport.NewServer(endpoints.Count, DecodeCountRequest, EncodeCountResponse))
64 return m
65 }
66 func DecodeConcatRequest(_ context.Context, r *http.Request) (interface{}, error) {
67 var req ConcatRequest
68 err := json.NewDecoder(r.Body).Decode(&req)
69 return req, err
70 }
71 func EncodeConcatResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
72 w.Header().Set("Content-Type", "application/json; charset=utf-8")
73 return json.NewEncoder(w).Encode(response)
74 }
75 func DecodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
76 var req CountRequest
77 err := json.NewDecoder(r.Body).Decode(&req)
78 return req, err
79 }
80 func EncodeCountResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
81 w.Header().Set("Content-Type", "application/json; charset=utf-8")
82 return json.NewEncoder(w).Encode(response)
83 }
+0
-6
cmd/kitgen/testdata/stringservice/in.go less more
0 package foo
1
2 type Service interface {
3 Concat(ctx context.Context, a, b string) (string, error)
4 Count(ctx context.Context, s string) (count int)
5 }
+0
-28
cmd/kitgen/testdata/underscores/default/endpoints/endpoints.go less more
0 package endpoints
1
2 import (
3 "context"
4
5 "github.com/go-kit/kit/cmd/kitgen/testdata/underscores/default/service"
6 "github.com/go-kit/kit/endpoint"
7 )
8
9 type FooRequest struct {
10 I int
11 }
12 type FooResponse struct {
13 I int
14 Err error
15 }
16
17 func MakeFooEndpoint(s service.Service) endpoint.Endpoint {
18 return func(ctx context.Context, request interface{}) (interface{}, error) {
19 req := request.(FooRequest)
20 i, err := s.Foo(ctx, req.I)
21 return FooResponse{I: i, Err: err}, nil
22 }
23 }
24
25 type Endpoints struct {
26 Foo endpoint.Endpoint
27 }
+0
-25
cmd/kitgen/testdata/underscores/default/http/http.go less more
0 package http
1
2 import (
3 "context"
4 "encoding/json"
5 "net/http"
6
7 "github.com/go-kit/kit/cmd/kitgen/testdata/underscores/default/endpoints"
8 httptransport "github.com/go-kit/kit/transport/http"
9 )
10
11 func NewHTTPHandler(endpoints endpoints.Endpoints) http.Handler {
12 m := http.NewServeMux()
13 m.Handle("/foo", httptransport.NewServer(endpoints.Foo, DecodeFooRequest, EncodeFooResponse))
14 return m
15 }
16 func DecodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
17 var req endpoints.FooRequest
18 err := json.NewDecoder(r.Body).Decode(&req)
19 return req, err
20 }
21 func EncodeFooResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
22 w.Header().Set("Content-Type", "application/json; charset=utf-8")
23 return json.NewEncoder(w).Encode(response)
24 }
+0
-13
cmd/kitgen/testdata/underscores/default/service/service.go less more
0 package service
1
2 import (
3 "context"
4 "errors"
5 )
6
7 type Service struct {
8 }
9
10 func (s Service) Foo(ctx context.Context, i int) (int, error) {
11 panic(errors.New("not implemented"))
12 }
+0
-54
cmd/kitgen/testdata/underscores/flat/gokit.go less more
0 package underscores
1
2 import (
3 "context"
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/go-kit/kit/endpoint"
9
10 httptransport "github.com/go-kit/kit/transport/http"
11 )
12
13 type Service struct {
14 }
15
16 func (s Service) Foo(ctx context.Context, i int) (int, error) {
17 panic(errors.New("not implemented"))
18 }
19
20 type FooRequest struct {
21 I int
22 }
23 type FooResponse struct {
24 I int
25 Err error
26 }
27
28 func MakeFooEndpoint(s Service) endpoint.Endpoint {
29 return func(ctx context.Context, request interface{}) (interface{}, error) {
30 req := request.(FooRequest)
31 i, err := s.Foo(ctx, req.I)
32 return FooResponse{I: i, Err: err}, nil
33 }
34 }
35
36 type Endpoints struct {
37 Foo endpoint.Endpoint
38 }
39
40 func NewHTTPHandler(endpoints Endpoints) http.Handler {
41 m := http.NewServeMux()
42 m.Handle("/foo", httptransport.NewServer(endpoints.Foo, DecodeFooRequest, EncodeFooResponse))
43 return m
44 }
45 func DecodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
46 var req FooRequest
47 err := json.NewDecoder(r.Body).Decode(&req)
48 return req, err
49 }
50 func EncodeFooResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
51 w.Header().Set("Content-Type", "application/json; charset=utf-8")
52 return json.NewEncoder(w).Encode(response)
53 }
+0
-7
cmd/kitgen/testdata/underscores/in.go less more
0 package underscores
1
2 import "context"
3
4 type Service interface {
5 Foo(_ context.Context, _ int) (int, error)
6 }
+0
-230
cmd/kitgen/transform.go less more
0 package main
1
2 import (
3 "bytes"
4 "fmt"
5 "go/ast"
6 "go/format"
7 "go/token"
8 "io"
9 "os"
10 "path/filepath"
11 "sort"
12 "strings"
13
14 "github.com/davecgh/go-spew/spew"
15 "github.com/pkg/errors"
16
17 "golang.org/x/tools/imports"
18 )
19
20 type (
21 files map[string]io.Reader
22 layout interface {
23 transformAST(ctx *sourceContext) (files, error)
24 }
25 outputTree map[string]*ast.File
26 )
27
28 func (ot outputTree) addFile(path, pkgname string) *ast.File {
29 file := &ast.File{
30 Name: id(pkgname),
31 Decls: []ast.Decl{},
32 }
33 ot[path] = file
34 return file
35 }
36
37 func getGopath() string {
38 gopath, set := os.LookupEnv("GOPATH")
39 if !set {
40 return filepath.Join(os.Getenv("HOME"), "go")
41 }
42 return gopath
43 }
44
45 func importPath(targetDir, gopath string) (string, error) {
46 if !filepath.IsAbs(targetDir) {
47 return "", fmt.Errorf("%q is not an absolute path", targetDir)
48 }
49
50 for _, dir := range filepath.SplitList(gopath) {
51 abspath, err := filepath.Abs(dir)
52 if err != nil {
53 continue
54 }
55 srcPath := filepath.Join(abspath, "src")
56
57 res, err := filepath.Rel(srcPath, targetDir)
58 if err != nil {
59 continue
60 }
61 if strings.Index(res, "..") == -1 {
62 return res, nil
63 }
64 }
65 return "", fmt.Errorf("%q is not in GOPATH (%s)", targetDir, gopath)
66
67 }
68
69 func selectify(file *ast.File, pkgName, identName, importPath string) *ast.File {
70 if file.Name.Name == pkgName {
71 return file
72 }
73
74 selector := sel(id(pkgName), id(identName))
75 var did bool
76 if file, did = selectifyIdent(identName, file, selector); did {
77 addImport(file, importPath)
78 }
79 return file
80 }
81
82 type selIdentFn func(ast.Node, func(ast.Node)) Visitor
83
84 func (f selIdentFn) Visit(node ast.Node, r func(ast.Node)) Visitor {
85 return f(node, r)
86 }
87
88 func selectifyIdent(identName string, file *ast.File, selector ast.Expr) (*ast.File, bool) {
89 var replaced bool
90 var r selIdentFn
91 r = selIdentFn(func(node ast.Node, replaceWith func(ast.Node)) Visitor {
92 switch id := node.(type) {
93 case *ast.SelectorExpr:
94 return nil
95 case *ast.Ident:
96 if id.Name == identName {
97 replaced = true
98 replaceWith(selector)
99 }
100 }
101 return r
102 })
103 return WalkReplace(r, file).(*ast.File), replaced
104 }
105
106 func formatNode(fname string, node ast.Node) (*bytes.Buffer, error) {
107 if file, is := node.(*ast.File); is {
108 sort.Stable(sortableDecls(file.Decls))
109 }
110 outfset := token.NewFileSet()
111 buf := &bytes.Buffer{}
112 err := format.Node(buf, outfset, node)
113 if err != nil {
114 return nil, err
115 }
116 imps, err := imports.Process(fname, buf.Bytes(), nil)
117 if err != nil {
118 return nil, err
119 }
120 return bytes.NewBuffer(imps), nil
121 }
122
123 type sortableDecls []ast.Decl
124
125 func (sd sortableDecls) Len() int {
126 return len(sd)
127 }
128
129 func (sd sortableDecls) Less(i int, j int) bool {
130 switch left := sd[i].(type) {
131 case *ast.GenDecl:
132 switch right := sd[j].(type) {
133 default:
134 return left.Tok == token.IMPORT
135 case *ast.GenDecl:
136 return left.Tok == token.IMPORT && right.Tok != token.IMPORT
137 }
138 }
139 return false
140 }
141
142 func (sd sortableDecls) Swap(i int, j int) {
143 sd[i], sd[j] = sd[j], sd[i]
144 }
145
146 func formatNodes(nodes outputTree) (files, error) {
147 res := files{}
148 var err error
149 for fn, node := range nodes {
150 res[fn], err = formatNode(fn, node)
151 if err != nil {
152 return nil, errors.Wrapf(err, "formatNodes")
153 }
154 }
155 return res, nil
156 }
157
158 // XXX debug
159 func spewDecls(f *ast.File) {
160 for _, d := range f.Decls {
161 switch dcl := d.(type) {
162 default:
163 spew.Dump(dcl)
164 case *ast.GenDecl:
165 spew.Dump(dcl.Tok)
166 case *ast.FuncDecl:
167 spew.Dump(dcl.Name.Name)
168 }
169 }
170 }
171
172 func addImports(root *ast.File, ctx *sourceContext) {
173 root.Decls = append(root.Decls, ctx.importDecls()...)
174 }
175
176 func addImport(root *ast.File, path string) {
177 for _, d := range root.Decls {
178 if imp, is := d.(*ast.GenDecl); is && imp.Tok == token.IMPORT {
179 for _, s := range imp.Specs {
180 if s.(*ast.ImportSpec).Path.Value == `"`+filepath.ToSlash(path)+`"` {
181 return // already have one
182 // xxx aliased imports?
183 }
184 }
185 }
186 }
187 root.Decls = append(root.Decls, importFor(importSpec(path)))
188 }
189
190 func addStubStruct(root *ast.File, iface iface) {
191 root.Decls = append(root.Decls, iface.stubStructDecl())
192 }
193
194 func addType(root *ast.File, typ *ast.TypeSpec) {
195 root.Decls = append(root.Decls, typeDecl(typ))
196 }
197
198 func addMethod(root *ast.File, iface iface, meth method) {
199 def := meth.definition(iface)
200 root.Decls = append(root.Decls, def)
201 }
202
203 func addRequestStruct(root *ast.File, meth method) {
204 root.Decls = append(root.Decls, meth.requestStruct())
205 }
206
207 func addResponseStruct(root *ast.File, meth method) {
208 root.Decls = append(root.Decls, meth.responseStruct())
209 }
210
211 func addEndpointMaker(root *ast.File, ifc iface, meth method) {
212 root.Decls = append(root.Decls, meth.endpointMaker(ifc))
213 }
214
215 func addEndpointsStruct(root *ast.File, ifc iface) {
216 root.Decls = append(root.Decls, ifc.endpointsStruct())
217 }
218
219 func addHTTPHandler(root *ast.File, ifc iface) {
220 root.Decls = append(root.Decls, ifc.httpHandler())
221 }
222
223 func addDecoder(root *ast.File, meth method) {
224 root.Decls = append(root.Decls, meth.decoderFunc())
225 }
226
227 func addEncoder(root *ast.File, meth method) {
228 root.Decls = append(root.Decls, meth.encoderFunc())
229 }
44 require (
55 github.com/VividCortex/gohistogram v1.0.0
66 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
7 github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a
87 github.com/aws/aws-sdk-go v1.38.68
98 github.com/aws/aws-sdk-go-v2 v1.7.0
109 github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.5.0
1211 github.com/cenkalti/backoff v2.2.1+incompatible // indirect
1312 github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec // indirect
1413 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
15 github.com/davecgh/go-spew v1.1.1
1614 github.com/dgrijalva/jwt-go v3.2.0+incompatible
1715 github.com/edsrzf/mmap-go v1.0.0 // indirect
1816 github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db // indirect
2927 github.com/opentracing/opentracing-go v1.2.0
3028 github.com/openzipkin/zipkin-go v0.2.5
3129 github.com/performancecopilot/speed v3.0.0+incompatible
32 github.com/pkg/errors v0.9.1
3330 github.com/prometheus/client_golang v1.11.0
3431 github.com/sirupsen/logrus v1.8.1
3532 github.com/smartystreets/goconvey v1.6.4 // indirect
4340 go.uber.org/zap v1.17.0
4441 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
4542 golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
46 golang.org/x/tools v0.1.4
4743 google.golang.org/grpc v1.38.0
4844 google.golang.org/protobuf v1.27.1
4945 gopkg.in/gcfg.v1 v1.2.3 // indirect
1919 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
2020 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
2121 github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
22 github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a h1:pv34s756C4pEXnjgPfGYgdhg/ZdajGhyOvzx8k+23nw=
23 github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
2422 github.com/aws/aws-sdk-go v1.38.68 h1:aOG8geU4SohNp659eKBHRBgbqSrZ6jNZlfimIuJAwL8=
2523 github.com/aws/aws-sdk-go v1.38.68/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
2624 github.com/aws/aws-sdk-go-v2 v1.7.0 h1:UYGnoIPIzed+ycmgw8Snb/0HK+KlMD+SndLTneG8ncE=
357355 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
358356 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
359357 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
360 golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
361358 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
362359 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
363360 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
442439 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
443440 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
444441 golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
445 golang.org/x/tools v0.1.4 h1:cVngSRcfgyZCzys3KYOpCFa+4dqX/Oub9tAq00ttGVs=
446 golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
447442 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
448443 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
449444 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=