Skip to content

Commit

Permalink
Merge pull request #45 from kzys/generators
Browse files Browse the repository at this point in the history
Support multiple generators
  • Loading branch information
stevvooe authored Oct 19, 2021
2 parents 6b023c6 + 96b64a3 commit b7ebc4c
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 19 deletions.
57 changes: 50 additions & 7 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,19 @@ import (
const configVersion = "unstable"

type config struct {
Version string
Version string
Generators []string

// Generator is a code generator which is used from protoc.
// Deprecated: Use Generators instead.
Generator string
Plugins []string
Includes struct {

// Plugins will be deprecated. It has to be per-Generator setting,
// but neither protoc-gen-go nor protoc-gen-go-grpc support plugins.
// So the refactoring is not worth to do.
Plugins []string

Includes struct {
Before []string
Vendored []string
Packages []string
Expand All @@ -40,9 +49,12 @@ type config struct {
Packages map[string]string

Overrides []struct {
Prefixes []string
Generator string
Plugins *[]string
Prefixes []string
// Generator is a code generator which is used from protoc.
// Deprecated: Use Generators instead.
Generator string
Generators []string
Plugins *[]string

// TODO(stevvooe): We could probably support overriding of includes and
// package maps, but they don't seem to be as useful. Likely,
Expand All @@ -59,7 +71,6 @@ type config struct {

func newDefaultConfig() config {
return config{
Generator: "go",
Includes: struct {
Before []string
Vendored []string
Expand All @@ -77,6 +88,10 @@ func readConfig(path string) (config, error) {
if err != nil {
log.Fatalln(err)
}
return readConfigFrom(p)
}

func readConfigFrom(p []byte) (config, error) {
c := newDefaultConfig()
if err := toml.Unmarshal(p, &c); err != nil {
log.Fatalln(err)
Expand All @@ -86,5 +101,33 @@ func readConfig(path string) (config, error) {
return config{}, fmt.Errorf("unknown file version %v; please upgrade to %v", c.Version, configVersion)
}

if c.Generator != "" {
if len(c.Generators) > 0 {
return config{}, fmt.Errorf(
`specify either "generators = %v" or "generator = %v", not both`,
c.Generators, c.Generator,
)
}
c.Generators = []string{c.Generator}
c.Generator = ""
}

for i, o := range c.Overrides {
if o.Generator != "" {
if len(o.Generators) > 0 {
return config{}, fmt.Errorf(
`specify either "overrides[%d].generators" or "overrides[%d].generator", not both`,
i, i,
)
}
c.Overrides[i].Generators = []string{o.Generator}
c.Overrides[i].Generator = ""
}
}

if len(c.Generators) == 0 {
c.Generators = []string{"go"}
}

return c, nil
}
60 changes: 60 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import "testing"

func TestReadConfigFrom(t *testing.T) {
testcases := []struct {
name string
toml string
}{
{
name: "empty",
toml: `version="unstable"`,
},
{
name: "generator",
toml: `
version="unstable"
generator="go"
`,
},
{
name: "generators",
toml: `
version="unstable"
generators=["go"]
`,
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
c, err := readConfigFrom([]byte(tc.toml))
if err != nil {
t.Fatalf("err must be nil, but got %v", err)
}
if c.Generator == "go" {
t.Fatalf("Generator must be cleared, but got %v", c.Generator)
}
if len(c.Generators) != 1 || c.Generators[0] != "go" {
t.Fatalf("Generators must be [go], but got %v", c.Generators)
}
})
}
}
13 changes: 7 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ func main() {

// Index overrides by target import path
overrides := map[string]struct {
Prefixes []string
Generator string
Plugins *[]string
Prefixes []string
Generator string
Generators []string
Plugins *[]string
}{}
for _, override := range c.Overrides {
for _, prefix := range override.Prefixes {
Expand Down Expand Up @@ -166,7 +167,7 @@ func main() {
includes = append(includes, c.Includes.After...)

protoc := protocCmd{
Name: c.Generator,
Names: c.Generators,
ImportPath: pkg.GoImportPath,
PackageMap: c.Packages,
Plugins: c.Plugins,
Expand All @@ -182,8 +183,8 @@ func main() {

if override, ok := overrides[importDirPath]; ok {
// selectively apply the overrides to the protoc structure.
if override.Generator != "" {
protoc.Name = override.Generator
if len(override.Generators) > 0 {
protoc.Names = override.Generators
}

if override.Plugins != nil {
Expand Down
16 changes: 10 additions & 6 deletions protoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ var (
{{if $index}}` + string(filepath.ListSeparator) + `{{end -}}
{{.}}
{{- end -}}
{{- if .Descriptors}} --include_imports --descriptor_set_out={{.Descriptors}}{{- end }} --
{{- .Name -}}_out={{if .Plugins}}plugins={{- range $index, $plugin := .Plugins -}}
{{- if $index}}+{{end}}
{{- $plugin}}
{{- if .Descriptors}} --include_imports --descriptor_set_out={{.Descriptors}}{{- end -}}
{{- range $index, $name := .Names }} --{{- $name -}}_out=
{{- if $.Plugins}}plugins={{- range $index, $plugin := $.Plugins -}}
{{- if $index}}+{{end}}
{{- $plugin}}
{{- end -}},{{- end -}}
import_path={{$.ImportPath}}
{{- end -}}
,{{- end -}}import_path={{.ImportPath}}
{{- range $proto, $gopkg := .PackageMap -}},M
{{- $proto}}={{$gopkg -}}
{{- end -}}
Expand All @@ -46,7 +50,7 @@ var (

// protocParams defines inputs to a protoc command string.
type protocCmd struct {
Name string // backend name
Names []string
Includes []string
Plugins []string
Descriptors string
Expand Down
57 changes: 57 additions & 0 deletions protoc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import "testing"

func TestMkcmd(t *testing.T) {
testcases := []struct {
name string
cmd protocCmd
expected string
}{
{
name: "basic",
cmd: protocCmd{Names: []string{"go"}},
expected: "protoc -I --go_out=import_path=:",
},
{
name: "plugin",
cmd: protocCmd{Names: []string{"go"}, Plugins: []string{"grpc"}},
expected: "protoc -I --go_out=plugins=grpc,import_path=:",
},
{
name: "use protoc-gen-go-grpc instead of plugins",
cmd: protocCmd{Names: []string{"go", "go-grpc"}},
expected: "protoc -I --go_out=import_path= --go-grpc_out=import_path=:",
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
cmd := &tc.cmd

s, err := cmd.mkcmd()
if err != nil {
t.Fatalf("err must be nil but %+v", err)
}

if s != tc.expected {
t.Fatalf(`s must be %q, but %q`, tc.expected, s)
}
})
}
}

0 comments on commit b7ebc4c

Please sign in to comment.