Add all special cases for Go importing WKT proto packages (#193)
When Go code generated from protos (via go_proto_library) import WKT
packages, they implicitly depend on targets in
@io_bazel_rules_go//proto/wkt. When static Go code imports the same
packages, Gazelle can resolve the dependencies differently. This
results in conflicting dependencies in many builds.
With this change, Gazelle has special cases for every target in
@io_bazel_rules_go//proto/wkt.
Fixes #159
diff --git a/internal/resolve/resolve.go b/internal/resolve/resolve.go
index 0e6473e..ecba7e2 100644
--- a/internal/resolve/resolve.go
+++ b/internal/resolve/resolve.go
@@ -234,12 +234,8 @@
return label.NoLabel, standardImportError{imp}
}
- if isWellKnownGo(imp) {
- return label.Label{
- Repo: config.RulesGoRepoName,
- Pkg: config.WellKnownTypesPkg,
- Name: path.Base(imp) + "_go_proto",
- }, nil
+ if l := resolveWellKnownGo(imp); !l.Equal(label.NoLabel) {
+ return l, nil
}
if l, err := r.ix.findLabelByImport(importSpec{config.GoLang, imp}, config.GoLang, from); err != nil {
@@ -342,6 +338,42 @@
return pathtools.HasPrefix(imp, config.WellKnownTypesProtoPrefix) && pathtools.TrimPrefix(imp, config.WellKnownTypesProtoPrefix) == path.Base(imp)
}
+func resolveWellKnownGo(imp string) label.Label {
+ // keep in sync with @io_bazel_rules_go//proto/wkt:well_known_types.bzl
+ // TODO(jayconrod): in well_known_types.bzl, write the import paths and
+ // targets in a public dict. Import it here, and use it to generate this code.
+ switch imp {
+ case "github.com/golang/protobuf/ptypes/any",
+ "github.com/golang/protobuf/ptypes/api",
+ "github.com/golang/protobuf/protoc-gen-go/descriptor",
+ "github.com/golang/protobuf/ptypes/duration",
+ "github.com/golang/protobuf/ptypes/empty",
+ "google.golang.org/genproto/protobuf/field_mask",
+ "google.golang.org/genproto/protobuf/source_context",
+ "github.com/golang/protobuf/ptypes/struct",
+ "github.com/golang/protobuf/ptypes/timestamp",
+ "github.com/golang/protobuf/ptypes/wrappers":
+ return label.Label{
+ Repo: config.RulesGoRepoName,
+ Pkg: config.WellKnownTypesPkg,
+ Name: path.Base(imp) + "_go_proto",
+ }
+ case "github.com/golang/protobuf/protoc-gen-go/plugin":
+ return label.Label{
+ Repo: config.RulesGoRepoName,
+ Pkg: config.WellKnownTypesPkg,
+ Name: "compiler_plugin_go_proto",
+ }
+ case "google.golang.org/genproto/protobuf/ptype":
+ return label.Label{
+ Repo: config.RulesGoRepoName,
+ Pkg: config.WellKnownTypesPkg,
+ Name: "type_go_proto",
+ }
+ }
+ return label.NoLabel
+}
+
func isWellKnownGo(imp string) bool {
prefix := config.WellKnownTypesGoPrefix + "/ptypes/"
return strings.HasPrefix(imp, prefix) && strings.TrimPrefix(imp, prefix) == path.Base(imp)
diff --git a/internal/resolve/resolve_test.go b/internal/resolve/resolve_test.go
index 396fac5..41920dd 100644
--- a/internal/resolve/resolve_test.go
+++ b/internal/resolve/resolve_test.go
@@ -463,15 +463,34 @@
ix := NewRuleIndex()
r := NewResolver(c, l, ix, nil)
- want := label.Label{
- Repo: config.RulesGoRepoName,
- Pkg: config.WellKnownTypesPkg,
- Name: "any_go_proto",
- }
- if got, err := r.resolveGo("github.com/golang/protobuf/ptypes/any", label.NoLabel); err != nil {
- t.Error(err)
- } else if !got.Equal(want) {
- t.Errorf("got %s; want %s", got, want)
+ for _, tc := range []struct {
+ imp, want string
+ }{
+ {"github.com/golang/protobuf/ptypes/any", "any_go_proto"},
+ {"github.com/golang/protobuf/ptypes/api", "api_go_proto"},
+ {"github.com/golang/protobuf/protoc-gen-go/descriptor", "descriptor_go_proto"},
+ {"github.com/golang/protobuf/ptypes/duration", "duration_go_proto"},
+ {"github.com/golang/protobuf/ptypes/empty", "empty_go_proto"},
+ {"google.golang.org/genproto/protobuf/field_mask", "field_mask_go_proto"},
+ {"google.golang.org/genproto/protobuf/source_context", "source_context_go_proto"},
+ {"github.com/golang/protobuf/ptypes/struct", "struct_go_proto"},
+ {"github.com/golang/protobuf/ptypes/timestamp", "timestamp_go_proto"},
+ {"github.com/golang/protobuf/ptypes/wrappers", "wrappers_go_proto"},
+ {"github.com/golang/protobuf/protoc-gen-go/plugin", "compiler_plugin_go_proto"},
+ {"google.golang.org/genproto/protobuf/ptype", "type_go_proto"},
+ } {
+ t.Run(tc.want, func(t *testing.T) {
+ want := label.Label{
+ Repo: config.RulesGoRepoName,
+ Pkg: config.WellKnownTypesPkg,
+ Name: tc.want,
+ }
+ if got, err := r.resolveGo(tc.imp, label.NoLabel); err != nil {
+ t.Error(err)
+ } else if !got.Equal(want) {
+ t.Errorf("got %s; want %s", got, want)
+ }
+ })
}
}