Skip to content

Commit dd6550f

Browse files
feat(gazelle): Gazelle plugin generates py_proto_library (bazel-contrib#3057)
Fixes bazel-contrib#2994. Please go over this with a fine-toothed comb! This is my first contribution to `rules_python` / the gazelle plugin, and while I've worked in Gazelle before, I'm pretty unfamiliar with the Python plugin's architecture. This adds support in the Gazelle plugin for generating `py_proto_library` rules automatically, if there are any `proto_library` rules detected in a given package. We do this via a new Gazelle directive, `python_generate_proto`, which defaults to `true`, and controls whether these rules are generated. See the tests in `testdata/directive_python_generate_proto` for examples. By default, we source the `py_proto_library` rule from the `@protobuf` repository. I think this the intended long-term home of the rule? Users are expected to use `gazelle:map_kind` to change this if need be. I haven't done anything here to support resolution of imports of `py_proto_library`. I think this is worth landing first, to save folks from having to maintain these by hand. But this should lay the foundation for resolving that in bazel-contrib#1703. --------- Co-authored-by: Douglas Thor <dougthor42@users.noreply.github.com>
1 parent 6f27511 commit dd6550f

File tree

50 files changed

+412
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+412
-26
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ END_UNRELEASED_TEMPLATE
106106
* 3.12.11
107107
* 3.13.5
108108
* 3.14.0b3
109+
* (gazelle) New directive `gazelle:python_generate_proto`; when `true`,
110+
Gazelle generates `py_proto_library` rules for `proto_library`. `false` by default.
109111

110112
{#v0-0-0-removed}
111113
### Removed

examples/bzlmod/py_proto_library/BUILD.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ py_test(
66
srcs = ["test.py"],
77
main = "test.py",
88
deps = [
9-
"//py_proto_library/example.com/proto:pricetag_proto_py_pb2",
9+
"//py_proto_library/example.com/proto:pricetag_py_pb2",
1010
],
1111
)
1212

1313
py_test(
1414
name = "message_test",
1515
srcs = ["message_test.py"],
1616
deps = [
17-
"//py_proto_library/example.com/another_proto:message_proto_py_pb2",
17+
"//py_proto_library/example.com/another_proto:message_py_pb2",
1818
],
1919
)
2020

examples/bzlmod/py_proto_library/example.com/another_proto/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
22
load("@rules_python//python:proto.bzl", "py_proto_library")
33

44
py_proto_library(
5-
name = "message_proto_py_pb2",
5+
name = "message_py_pb2",
66
visibility = ["//visibility:public"],
77
deps = [":message_proto"],
88
)

examples/bzlmod/py_proto_library/example.com/proto/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
22
load("@rules_python//python:proto.bzl", "py_proto_library")
33

44
py_proto_library(
5-
name = "pricetag_proto_py_pb2",
5+
name = "pricetag_py_pb2",
66
visibility = ["//visibility:public"],
77
deps = [":pricetag_proto"],
88
)

examples/py_proto_library/BUILD.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ py_test(
55
srcs = ["test.py"],
66
main = "test.py",
77
deps = [
8-
"//example.com/proto:pricetag_proto_py_pb2",
8+
"//example.com/proto:pricetag_py_pb2",
99
],
1010
)
1111

1212
py_test(
1313
name = "message_test",
1414
srcs = ["message_test.py"],
1515
deps = [
16-
"//example.com/another_proto:message_proto_py_pb2",
16+
"//example.com/another_proto:message_py_pb2",
1717
],
1818
)

examples/py_proto_library/example.com/another_proto/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
22
load("@rules_python//python:proto.bzl", "py_proto_library")
33

44
py_proto_library(
5-
name = "message_proto_py_pb2",
5+
name = "message_py_pb2",
66
visibility = ["//visibility:public"],
77
deps = [":message_proto"],
88
)

examples/py_proto_library/example.com/proto/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
22
load("@rules_python//python:proto.bzl", "py_proto_library")
33

44
py_proto_library(
5-
name = "pricetag_proto_py_pb2",
5+
name = "pricetag_py_pb2",
66
visibility = ["//visibility:public"],
77
deps = [":pricetag_proto"],
88
)

gazelle/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ Python-specific directives are as follows:
224224
| Controls whether Gazelle resolves dependencies for import statements that use paths relative to the current package. Can be "true" or "false".|
225225
| `# gazelle:python_generate_pyi_deps` | `false` |
226226
| Controls whether to generate a separate `pyi_deps` attribute for type-checking dependencies or merge them into the regular `deps` attribute. When `false` (default), type-checking dependencies are merged into `deps` for backward compatibility. When `true`, generates separate `pyi_deps`. Imports in blocks with the format `if typing.TYPE_CHECKING:`/`if TYPE_CHECKING:` and type-only stub packages (eg. boto3-stubs) are recognized as type-checking dependencies. |
227+
| [`# gazelle:python_generate_proto`](#directive-python_generate_proto) | `false` |
228+
| Controls whether to generate a `py_proto_library` for each `proto_library` in the package. By default we load this rule from the `@protobuf` repository; use `gazelle:map_kind` if you need to load this from somewhere else. |
227229

228230
#### Directive: `python_root`:
229231

@@ -484,6 +486,41 @@ def py_test(name, main=None, **kwargs):
484486
)
485487
```
486488

489+
#### Directive: `python_generate_proto`:
490+
491+
When `# gazelle:python_generate_proto true`, Gazelle will generate one
492+
`py_proto_library` for each `proto_library`, generating Python clients for
493+
protobuf in each package. By default this is turned off. Gazelle will also
494+
generate a load statement for the `py_proto_library` - attempting to detect
495+
the configured name for the `@protobuf` / `@com_google_protobuf` repo in your
496+
`MODULE.bazel`, and otherwise falling back to `@com_google_protobuf` for
497+
compatibility with `WORKSPACE`.
498+
499+
For example, in a package with `# gazelle:python_generate_proto true` and a
500+
`foo.proto`, if you have both the proto extension and the Python extension
501+
loaded into Gazelle, you'll get something like:
502+
503+
```starlark
504+
load("@protobuf//bazel:py_proto_library.bzl", "py_proto_library")
505+
load("@rules_proto//proto:defs.bzl", "proto_library")
506+
507+
# gazelle:python_generate_proto true
508+
509+
proto_library(
510+
name = "foo_proto",
511+
srcs = ["foo.proto"],
512+
visibility = ["//:__subpackages__"],
513+
)
514+
515+
py_proto_library(
516+
name = "foo_py_pb2",
517+
visibility = ["//:__subpackages__"],
518+
deps = [":foo_proto"],
519+
)
520+
```
521+
522+
When `false`, Gazelle will ignore any `py_proto_library`, including previously-generated or hand-created rules.
523+
487524
### Annotations
488525

489526
*Annotations* refer to comments found _within Python files_ that configure how

gazelle/python/BUILD.bazel

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ go_library(
3434
"@bazel_gazelle//config:go_default_library",
3535
"@bazel_gazelle//label:go_default_library",
3636
"@bazel_gazelle//language:go_default_library",
37+
"@bazel_gazelle//language/proto:go_default_library",
3738
"@bazel_gazelle//repo:go_default_library",
3839
"@bazel_gazelle//resolve:go_default_library",
3940
"@bazel_gazelle//rule:go_default_library",
@@ -91,7 +92,10 @@ gazelle_test(
9192

9293
gazelle_binary(
9394
name = "gazelle_binary",
94-
languages = [":python"],
95+
languages = [
96+
"@bazel_gazelle//language/proto",
97+
":python",
98+
],
9599
visibility = ["//visibility:public"],
96100
)
97101

gazelle/python/configure.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func (py *Configurer) KnownDirectives() []string {
7070
pythonconfig.LabelNormalization,
7171
pythonconfig.GeneratePyiDeps,
7272
pythonconfig.ExperimentalAllowRelativeImports,
73+
pythonconfig.GenerateProto,
7374
}
7475
}
7576

@@ -237,6 +238,12 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) {
237238
log.Fatal(err)
238239
}
239240
config.SetGeneratePyiDeps(v)
241+
case pythonconfig.GenerateProto:
242+
v, err := strconv.ParseBool(strings.TrimSpace(d.Value))
243+
if err != nil {
244+
log.Fatal(err)
245+
}
246+
config.SetGenerateProto(v)
240247
}
241248
}
242249

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy