Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ END_UNRELEASED_TEMPLATE
* 3.14.0b3
* (gazelle) New directive `gazelle:python_generate_proto`; when `true`,
Gazelle generates `py_proto_library` rules for `proto_library`. `false` by default.
* (gazelle) New directive `gazelle:python_proto_naming_convention`; controls
naming of `py_proto_library` rules. See `gazelle/README.md`.

{#v0-0-0-removed}
### Removed
Expand Down
2 changes: 2 additions & 0 deletions gazelle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ Python-specific directives are as follows:
| Controls the `py_binary` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. | |
| `# gazelle:python_test_naming_convention` | `$package_name$_test` |
| Controls the `py_test` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. | |
| `# gazelle:python_proto_naming_convention` | `$proto_name$_py_pb2` |
| Controls the `py_proto_library naming convention. It interpolates `$proto_name$` with the proto_library rule name, minus any trailing _proto. E.g. if the proto_library name is `foo_proto`, setting this to `$proto_name$_my_lib` would render to `foo_my_lib`. | |
| `# gazelle:resolve py ...` | n/a |
| Instructs the plugin what target to add as a dependency to satisfy a given import statement. The syntax is `# gazelle:resolve py import-string label` where `import-string` is the symbol in the python `import` statement, and `label` is the Bazel label that Gazelle should write in `deps`. | |
| [`# gazelle:python_default_visibility labels`](#directive-python_default_visibility) | |
Expand Down
3 changes: 3 additions & 0 deletions gazelle/python/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func (py *Configurer) KnownDirectives() []string {
pythonconfig.LibraryNamingConvention,
pythonconfig.BinaryNamingConvention,
pythonconfig.TestNamingConvention,
pythonconfig.ProtoNamingConvention,
pythonconfig.DefaultVisibilty,
pythonconfig.Visibility,
pythonconfig.TestFilePattern,
Expand Down Expand Up @@ -179,6 +180,8 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) {
config.SetBinaryNamingConvention(strings.TrimSpace(d.Value))
case pythonconfig.TestNamingConvention:
config.SetTestNamingConvention(strings.TrimSpace(d.Value))
case pythonconfig.ProtoNamingConvention:
config.SetProtoNamingConvention(strings.TrimSpace(d.Value))
case pythonconfig.DefaultVisibilty:
switch directiveArg := strings.TrimSpace(d.Value); directiveArg {
case "NONE":
Expand Down
6 changes: 3 additions & 3 deletions gazelle/python/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
result.Gen = make([]*rule.Rule, 0)

if cfg.GenerateProto() {
generateProtoLibraries(args, pythonProjectRoot, visibility, &result)
generateProtoLibraries(args, cfg, pythonProjectRoot, visibility, &result)
}

collisionErrors := singlylinkedlist.New()
Expand Down Expand Up @@ -556,7 +556,7 @@ func ensureNoCollision(file *rule.File, targetName, kind string) error {
return nil
}

func generateProtoLibraries(args language.GenerateArgs, pythonProjectRoot string, visibility []string, res *language.GenerateResult) {
func generateProtoLibraries(args language.GenerateArgs, cfg *pythonconfig.Config, pythonProjectRoot string, visibility []string, res *language.GenerateResult) {
// First, enumerate all the proto_library in this package.
var protoRuleNames []string
for _, r := range args.OtherGen {
Expand All @@ -580,7 +580,7 @@ func generateProtoLibraries(args language.GenerateArgs, pythonProjectRoot string
emptySiblings := treeset.Set{}
// Generate a py_proto_library for each proto_library.
for _, protoRuleName := range protoRuleNames {
pyProtoLibraryName := strings.TrimSuffix(protoRuleName, "_proto") + "_py_pb2"
pyProtoLibraryName := cfg.RenderProtoName(protoRuleName)
pyProtoLibrary := newTargetBuilder(pyProtoLibraryKind, pyProtoLibraryName, pythonProjectRoot, args.Rel, &emptySiblings).
addVisibility(visibility).
addResolvedDependency(":" + protoRuleName).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Directive: `python_proto_naming_convention`

This test case asserts that the `# gazelle:python_proto_naming_convention` directive
correctly:

1. Has no effect on pre-existing `py_proto_library` when `gazelle:python_generate_proto` is disabled.
2. Uses the default value when proto generation is on and `python_proto_naming_convention` is not set.
2. Uses the provided naming convention when proto generation is on and `python_proto_naming_convention` is set.

[gh-3081]: https://github.com/bazel-contrib/rules_python/issues/3081
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is a Bazel workspace for the Gazelle test data.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
expect:
exit_code: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

# gazelle:python_generate_proto false
# gazelle:python_proto_naming_convention some_$proto_name$_value

proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//:__subpackages__"],
)

py_proto_library(
name = "foo_proto_custom_name",
visibility = ["//:__subpackages__"],
deps = [":foo_proto"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

# gazelle:python_generate_proto false
# gazelle:python_proto_naming_convention some_$proto_name$_value

proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//:__subpackages__"],
)

py_proto_library(
name = "foo_proto_custom_name",
visibility = ["//:__subpackages__"],
deps = [":foo_proto"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

package foo.bar;

message Foo {
string bar = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
load("@rules_proto//proto:defs.bzl", "proto_library")

# gazelle:python_generate_proto true

proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//:__subpackages__"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

# gazelle:python_generate_proto true

proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//:__subpackages__"],
)

py_proto_library(
name = "foo_py_pb2",
visibility = ["//:__subpackages__"],
deps = [":foo_proto"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

package foo;

message Foo {
string bar = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
load("@rules_proto//proto:defs.bzl", "proto_library")

# gazelle:python_generate_proto true
# gazelle:python_proto_naming_convention some_$proto_name$_value

proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//:__subpackages__"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

# gazelle:python_generate_proto true
# gazelle:python_proto_naming_convention some_$proto_name$_value

proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//:__subpackages__"],
)

py_proto_library(
name = "some_foo_value",
visibility = ["//:__subpackages__"],
deps = [":foo_proto"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

package foo;

message Foo {
string bar = 1;
}
21 changes: 21 additions & 0 deletions gazelle/pythonconfig/pythonconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ const (
// naming convention. See python_library_naming_convention for more info on
// the package name interpolation.
TestNamingConvention = "python_test_naming_convention"
// ProtoNamingConvention represents the directive that controls the
// py_proto_library naming convention. It interpolates $proto_name$ with
// the proto_library rule name, minus any trailing _proto. E.g. if the
// proto_library name is `foo_proto`, setting this to `$proto_name$_my_lib`
// would render to `foo_my_lib`.
ProtoNamingConvention = "python_proto_naming_convention"
// DefaultVisibilty represents the directive that controls what visibility
// labels are added to generated python targets.
DefaultVisibilty = "python_default_visibility"
Expand Down Expand Up @@ -121,6 +127,7 @@ const (

const (
packageNameNamingConventionSubstitution = "$package_name$"
protoNameNamingConventionSubstitution = "$proto_name$"
distributionNameLabelConventionSubstitution = "$distribution_name$"
)

Expand Down Expand Up @@ -182,6 +189,7 @@ type Config struct {
libraryNamingConvention string
binaryNamingConvention string
testNamingConvention string
protoNamingConvention string
defaultVisibility []string
visibility []string
testFilePattern []string
Expand Down Expand Up @@ -220,6 +228,7 @@ func New(
libraryNamingConvention: packageNameNamingConventionSubstitution,
binaryNamingConvention: fmt.Sprintf("%s_bin", packageNameNamingConventionSubstitution),
testNamingConvention: fmt.Sprintf("%s_test", packageNameNamingConventionSubstitution),
protoNamingConvention: fmt.Sprintf("%s_py_pb2", protoNameNamingConventionSubstitution),
defaultVisibility: []string{fmt.Sprintf(DefaultVisibilityFmtString, "")},
visibility: []string{},
testFilePattern: strings.Split(DefaultTestFilePatternString, ","),
Expand Down Expand Up @@ -255,6 +264,7 @@ func (c *Config) NewChild() *Config {
libraryNamingConvention: c.libraryNamingConvention,
binaryNamingConvention: c.binaryNamingConvention,
testNamingConvention: c.testNamingConvention,
protoNamingConvention: c.protoNamingConvention,
defaultVisibility: c.defaultVisibility,
visibility: c.visibility,
testFilePattern: c.testFilePattern,
Expand Down Expand Up @@ -489,6 +499,17 @@ func (c *Config) RenderTestName(packageName string) string {
return strings.ReplaceAll(c.testNamingConvention, packageNameNamingConventionSubstitution, packageName)
}

// SetProtoNamingConvention sets the py_proto_library target naming convention.
func (c *Config) SetProtoNamingConvention(protoNamingConvention string) {
c.protoNamingConvention = protoNamingConvention
}

// RenderProtoName returns the py_proto_library target name by performing all
// substitutions.
func (c *Config) RenderProtoName(protoName string) string {
return strings.ReplaceAll(c.protoNamingConvention, protoNameNamingConventionSubstitution, strings.TrimSuffix(protoName, "_proto"))
}

// AppendVisibility adds additional items to the target's visibility.
func (c *Config) AppendVisibility(visibility string) {
c.visibility = append(c.visibility, visibility)
Expand Down