Skip to content

Commit

Permalink
python: Provide python rules via CrossResolve. (#316)
Browse files Browse the repository at this point in the history
This allows rules_python's gazelle plugin to find python rules generated
by rules_proto allowing for a fully gazelle'ified experience working
with protos with Python.
  • Loading branch information
DolceTriade committed Feb 21, 2024
1 parent 9fffedb commit c93e1f5
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 1 deletion.
5 changes: 4 additions & 1 deletion pkg/plugin/grpc/grpc/BUILD.bazel
Expand Up @@ -14,7 +14,10 @@ go_library(

go_test(
name = "grpc_test",
srcs = ["protoc-gen-grpc-python_test.go"],
srcs = [
"grpc_test.go",
"protoc-gen-grpc-python_test.go",
],
data = [
":protoc",
":protoc-gen-grpc-python",
Expand Down
14 changes: 14 additions & 0 deletions pkg/rule/rules_python/py_library.go
Expand Up @@ -121,11 +121,25 @@ func (s *PyLibrary) Rule(otherGen ...*rule.Rule) *rule.Rule {
return newRule
}

func pyFilenameToImport(s string) string {
if strings.HasSuffix(s, ".py") {
return strings.ReplaceAll(s[:len(s)-3], "/", ".")
}
return s
}

// Imports implements part of the RuleProvider interface.
func (s *PyLibrary) Imports(c *config.Config, r *rule.Rule, file *rule.File) []resolve.ImportSpec {
if lib, ok := r.PrivateAttr(protoc.ProtoLibraryKey).(protoc.ProtoLibrary); ok {
specs := protoc.ProtoLibraryImportSpecsForKind(r.Kind(), lib)
specs = maybeStripImportPrefix(specs, lib.StripImportPrefix())
from := label.New("", file.Pkg, r.Name())
for _, o := range s.Outputs {
pyImp := pyFilenameToImport(o)
protoc.GlobalResolver().Provide("py", "py", pyImp, from)
specs = append(specs, resolve.ImportSpec{Lang: "py", Imp: pyImp})
}

return specs
}
return nil
Expand Down
47 changes: 47 additions & 0 deletions pkg/rule/rules_python/py_library_test.go
@@ -1,10 +1,14 @@
package rules_python

import (
"fmt"
"path"
"testing"

"github.com/bazelbuild/bazel-gazelle/resolve"
"github.com/bazelbuild/bazel-gazelle/rule"
"github.com/google/go-cmp/cmp"
"github.com/stackb/rules_proto/pkg/protoc"
)

func TestMaybeStripImportPrefix(t *testing.T) {
Expand Down Expand Up @@ -49,3 +53,46 @@ func TestMaybeStripImportPrefix(t *testing.T) {
})
}
}

func TestImports(t *testing.T) {
kind := "mykind"
suffix := "_suffix"
pkg := "mypkg"
protoName := "test"
cases := []struct {
Name string
Outputs []string
WantImports []resolve.ImportSpec
}{{
Name: "Empty",
// If for some reason, no python files were output...
Outputs: []string{},
// Always include the output from the proto_library
WantImports: []resolve.ImportSpec{{Lang: kind, Imp: fmt.Sprintf("%s/%s", pkg, protoName)}},
}, {
Name: "One output",
Outputs: []string{path.Join(pkg, "test_pb2.py")},
WantImports: []resolve.ImportSpec{
{Lang: kind, Imp: fmt.Sprintf("%s/%s", pkg, protoName)},
{Lang: "py", Imp: fmt.Sprintf("%s.%s_pb2", pkg, protoName)},
},
}}

for _, c := range cases {
t.Run(c.Name, func(t *testing.T) {
py := &PyLibrary{
KindName: kind,
RuleNameSuffix: suffix,
Outputs: c.Outputs,
Resolver: protoc.ResolveDepsAttr("deps", true),
}
protoLib := protoc.NewOtherProtoLibrary(&rule.File{}, rule.NewRule("proto_library", protoName+"_proto"), protoc.NewFile(pkg, protoName))
r := rule.NewRule(kind, "test"+suffix)
r.SetPrivateAttr(protoc.ProtoLibraryKey, protoLib)
imps := py.Imports(nil, r, &rule.File{Pkg: pkg})
if diff := cmp.Diff(imps, c.WantImports); diff != "" {
t.Fatalf("import mismatch: (-got, +want): %s", diff)
}
})
}
}
4 changes: 4 additions & 0 deletions rules/private/proto_repository_tools_srcs.bzl
Expand Up @@ -66,6 +66,9 @@ PROTO_REPOSITORY_TOOLS_SRCS = [
"@build_stack_rules_proto//pkg/language/protobuf:resolve.go",
"@build_stack_rules_proto//pkg/plugin/akka/akka_grpc:BUILD.bazel",
"@build_stack_rules_proto//pkg/plugin/akka/akka_grpc:protoc_gen_akka_grpc.go",
"@build_stack_rules_proto//pkg/plugin/bufbuild:BUILD.bazel",
"@build_stack_rules_proto//pkg/plugin/bufbuild:connect_es_plugin.go",
"@build_stack_rules_proto//pkg/plugin/bufbuild:es_plugin.go",
"@build_stack_rules_proto//pkg/plugin/builtin:BUILD.bazel",
"@build_stack_rules_proto//pkg/plugin/builtin:cpp_plugin.go",
"@build_stack_rules_proto//pkg/plugin/builtin:csharp_plugin.go",
Expand Down Expand Up @@ -165,6 +168,7 @@ PROTO_REPOSITORY_TOOLS_SRCS = [
"@build_stack_rules_proto//pkg/rule/rules_scala:scala_proto_library.go",
"@build_stack_rules_proto//plugin:BUILD.bazel",
"@build_stack_rules_proto//plugin/akka/akka-grpc:BUILD.bazel",
"@build_stack_rules_proto//plugin/bufbuild:BUILD.bazel",
"@build_stack_rules_proto//plugin/builtin:BUILD.bazel",
"@build_stack_rules_proto//plugin/gogo/protobuf:BUILD.bazel",
"@build_stack_rules_proto//plugin/golang/protobuf:BUILD.bazel",
Expand Down

0 comments on commit c93e1f5

Please sign in to comment.