diff --git a/.travis.yml b/.travis.yml index ed5930e..172f172 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,12 @@ install: - go get github.com/Masterminds/glide - wget https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/master/.travis/install-protoc.sh && chmod +x install-protoc.sh && ./install-protoc.sh 3.2.0 - go get -u github.com/golang/protobuf/protoc-gen-go +- go get -u github.com/alecthomas/gometalinter +- gometalinter --install script: - make install - make test +- make lint cache: directories: - $HOME/local diff --git a/Makefile b/Makefile index 0efb3dc..14ef388 100644 --- a/Makefile +++ b/Makefile @@ -29,3 +29,7 @@ docker.build: .PHONY: docker.push docker.push: docker.build docker push moul/protoc-gen-gotemplate + +.PHONY: lint +lint: + gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow --enable=golint --enable=gas --enable=ineffassign --enable=goconst --enable=goimports --enable=gofmt --exclude="Binds to all network interfaces" --exclude="should have comment" --enable=staticcheck --enable=gosimple --enable=misspell --deadline=120s . ./cmd/... ./helpers/... diff --git a/cmd/web-editor/main.go b/cmd/web-editor/main.go index 52df628..1531080 100644 --- a/cmd/web-editor/main.go +++ b/cmd/web-editor/main.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/ioutil" + "log" "net/http" "os" "os/exec" @@ -32,18 +33,23 @@ func generate(w http.ResponseWriter, r *http.Request) { if err != nil { returnError(w, err) } - defer os.RemoveAll(dir) // clean up - if err := ioutil.WriteFile(filepath.Join(dir, "example.proto"), []byte(input.Protobuf), 0644); err != nil { + // clean up + defer func() { + if err = os.RemoveAll(dir); err != nil { + log.Printf("error: failed to remove temporary directory: %v", err) + } + }() + if err = ioutil.WriteFile(filepath.Join(dir, "example.proto"), []byte(input.Protobuf), 0644); err != nil { returnError(w, err) return } - if err := ioutil.WriteFile(filepath.Join(dir, "example.output.tmpl"), []byte(input.Template), 0644); err != nil { + if err = ioutil.WriteFile(filepath.Join(dir, "example.output.tmpl"), []byte(input.Template), 0644); err != nil { returnError(w, err) return } // generate - cmd := exec.Command("protoc", "-I"+dir, "--gotemplate_out=template_dir="+dir+",debug=true:"+dir, filepath.Join(dir, "example.proto")) + cmd := exec.Command("protoc", "-I"+dir, "--gotemplate_out=template_dir="+dir+",debug=true:"+dir, filepath.Join(dir, "example.proto")) // #nosec out, err := cmd.CombinedOutput() if err != nil { returnError(w, errors.New(string(out))) @@ -64,20 +70,32 @@ func returnContent(w http.ResponseWriter, output interface{}) { payload := map[string]interface{}{ "output": fmt.Sprintf("%s", output), } - response, _ := json.Marshal(payload) + response, err := json.Marshal(payload) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - w.Write(response) + if _, err := w.Write(response); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } } func returnError(w http.ResponseWriter, err error) { payload := map[string]interface{}{ "error": fmt.Sprintf("%v", err), } - response, _ := json.Marshal(payload) + response, err := json.Marshal(payload) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) - w.Write(response) + if _, err := w.Write(response); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } } func main() { @@ -94,5 +112,7 @@ func main() { h := handlers.LoggingHandler(os.Stderr, r) h = handlers.CompressHandler(h) h = handlers.RecoveryHandler()(h) - http.ListenAndServe(addr, r) + if err := http.ListenAndServe(addr, h); err != nil { + panic(err) + } } diff --git a/encoder.go b/encoder.go index 2406137..53a0779 100644 --- a/encoder.go +++ b/encoder.go @@ -100,11 +100,20 @@ func (e *GenericTemplateBasedEncoder) templates() ([]string, error) { func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, error) { // prepare the ast passed to the template engine - hostname, _ := os.Hostname() - pwd, _ := os.Getwd() + hostname, err := os.Hostname() + if err != nil { + return nil, err + } + pwd, err := os.Getwd() + if err != nil { + return nil, err + } goPwd := "" if os.Getenv("GOPATH") != "" { - goPwd, _ = filepath.Rel(os.Getenv("GOPATH")+"/src", pwd) + goPwd, err = filepath.Rel(os.Getenv("GOPATH")+"/src", pwd) + if err != nil { + return nil, err + } if strings.Contains(goPwd, "../") { goPwd = "" } @@ -170,7 +179,8 @@ func (e *GenericTemplateBasedEncoder) Files() []*plugin_go.CodeGeneratorResponse resultChan := make(chan *plugin_go.CodeGeneratorResponse_File, length) for _, templateFilename := range templates { go func(tmpl string) { - content, translatedFilename, err := e.buildContent(tmpl) + var translatedFilename, content string + content, translatedFilename, err = e.buildContent(tmpl) if err != nil { errChan <- err return diff --git a/helpers/helpers.go b/helpers/helpers.go index ebb4977..d7bcccf 100644 --- a/helpers/helpers.go +++ b/helpers/helpers.go @@ -15,7 +15,7 @@ import ( options "google.golang.org/genproto/googleapis/api/annotations" ) -var jsReservedRe *regexp.Regexp = regexp.MustCompile(`(^|[^A-Za-z])(do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)($|[^A-Za-z])`) +var jsReservedRe = regexp.MustCompile(`(^|[^A-Za-z])(do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)($|[^A-Za-z])`) var ( registry *ggdescriptor.Registry // some helpers need access to registry @@ -32,11 +32,17 @@ var ProtoHelpersFuncMap = template.FuncMap{ return i.String() }, "json": func(v interface{}) string { - a, _ := json.Marshal(v) + a, err := json.Marshal(v) + if err != nil { + return err.Error() + } return string(a) }, "prettyjson": func(v interface{}) string { - a, _ := json.MarshalIndent(v, "", " ") + a, err := json.MarshalIndent(v, "", " ") + if err != nil { + return err.Error() + } return string(a) }, "splitArray": func(sep string, s string) []interface{} { @@ -315,7 +321,7 @@ func goType(pkg string, f *descriptor.FieldDescriptorProto) string { func jsType(f *descriptor.FieldDescriptorProto) string { template := "%s" - if isFieldRepeated(f) == true { + if isFieldRepeated(f) { template = "Array<%s>" } diff --git a/main.go b/main.go index 618ce84..3014869 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,11 @@ var ( registry *ggdescriptor.Registry // some helpers need access to registry ) +const ( + boolTrue = "true" + boolFalse = "false" +) + func main() { g := generator.New() @@ -26,7 +31,7 @@ func main() { g.Error(err, "reading input") } - if err := proto.Unmarshal(data, g.Request); err != nil { + if err = proto.Unmarshal(data, g.Request); err != nil { g.Error(err, "parsing input proto") } @@ -54,37 +59,32 @@ func main() { switch parts[0] { case "template_dir": templateDir = parts[1] - break case "destination_dir": destinationDir = parts[1] - break case "single-package-mode": switch strings.ToLower(parts[1]) { - case "true", "t": + case boolTrue, "t": singlePackageMode = true - case "false", "f": + case boolFalse, "f": default: log.Printf("Err: invalid value for single-package-mode: %q", parts[1]) } - break case "debug": switch strings.ToLower(parts[1]) { - case "true", "t": + case boolTrue, "t": debug = true - case "false", "f": + case boolFalse, "f": default: log.Printf("Err: invalid value for debug: %q", parts[1]) } - break case "all": switch strings.ToLower(parts[1]) { - case "true", "t": + case boolTrue, "t": all = true - case "false", "f": + case boolFalse, "f": default: log.Printf("Err: invalid value for debug: %q", parts[1]) } - break default: log.Printf("Err: unknown parameter: %q", param) } @@ -104,7 +104,7 @@ func main() { if singlePackageMode { registry = ggdescriptor.NewRegistry() pgghelpers.SetRegistry(registry) - if err := registry.Load(g.Request); err != nil { + if err = registry.Load(g.Request); err != nil { g.Error(err, "registry: failed to load the request") } } @@ -113,7 +113,7 @@ func main() { for _, file := range g.Request.GetProtoFile() { if all { if singlePackageMode { - if _, err := registry.LookupFile(file.GetName()); err != nil { + if _, err = registry.LookupFile(file.GetName()); err != nil { g.Error(err, "registry: failed to lookup file %q", file.GetName()) } }