protogen, cmd/protoc-gen-go: initial commit
Package protogen provides support for writing protoc plugins.
A "plugin" in this case is a program run by protoc to generate output.
The protoc-gen-go command is a protoc plugin to generate Go code.
cmd/protoc-gen-go/golden_test.go is mostly a straight copy from
the golden test in github.com/golang/protobuf.
Change-Id: I332d0df1e4b60bb8cd926320b8721e16b99a4b71
Reviewed-on: https://go-review.googlesource.com/130175
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/protogen/protogen_test.go b/protogen/protogen_test.go
new file mode 100644
index 0000000..1d23cc0
--- /dev/null
+++ b/protogen/protogen_test.go
@@ -0,0 +1,94 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protogen
+
+import (
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/golang/protobuf/proto"
+ pluginpb "github.com/golang/protobuf/protoc-gen-go/plugin"
+)
+
+func TestFiles(t *testing.T) {
+ gen, err := New(makeRequest(t, "testdata/go_package/no_go_package_import.proto"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, test := range []struct {
+ path string
+ wantGenerate bool
+ }{
+ {
+ path: "go_package/no_go_package_import.proto",
+ wantGenerate: true,
+ },
+ {
+ path: "go_package/no_go_package.proto",
+ wantGenerate: false,
+ },
+ } {
+ f, ok := gen.FileByName(test.path)
+ if !ok {
+ t.Errorf("%q: not found by gen.FileByName", test.path)
+ continue
+ }
+ if f.Generate != test.wantGenerate {
+ t.Errorf("%q: Generate=%v, want %v", test.path, f.Generate, test.wantGenerate)
+ }
+ }
+}
+
+// makeRequest returns a CodeGeneratorRequest for the given protoc inputs.
+//
+// It does this by running protoc with the current binary as the protoc-gen-go
+// plugin. This "plugin" produces a single file, named 'request', which contains
+// the code generator request.
+func makeRequest(t *testing.T, args ...string) *pluginpb.CodeGeneratorRequest {
+ workdir, err := ioutil.TempDir("", "test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(workdir)
+
+ cmd := exec.Command("protoc", "--plugin=protoc-gen-go="+os.Args[0])
+ cmd.Args = append(cmd.Args, "--go_out="+workdir, "-Itestdata")
+ cmd.Args = append(cmd.Args, args...)
+ cmd.Env = append(os.Environ(), "RUN_AS_PROTOC_PLUGIN=1")
+ out, err := cmd.CombinedOutput()
+ if len(out) > 0 || err != nil {
+ t.Log("RUNNING: ", strings.Join(cmd.Args, " "))
+ }
+ if len(out) > 0 {
+ t.Log(string(out))
+ }
+ if err != nil {
+ t.Fatalf("protoc: %v", err)
+ }
+
+ b, err := ioutil.ReadFile(filepath.Join(workdir, "request"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ req := &pluginpb.CodeGeneratorRequest{}
+ if err := proto.UnmarshalText(string(b), req); err != nil {
+ t.Fatal(err)
+ }
+ return req
+}
+
+func init() {
+ if os.Getenv("RUN_AS_PROTOC_PLUGIN") != "" {
+ Run(func(p *Plugin) error {
+ g := p.NewGeneratedFile("request")
+ return proto.MarshalText(g, p.Request)
+ })
+ os.Exit(0)
+ }
+}