Skip to content

Commit

Permalink
Support proto files in subdirectories of the package directory (#436)
Browse files Browse the repository at this point in the history
The existing code assumed that all input .proto files were in the same directory as the BUILD file for the build rule. This isn't always the case, since it's perfectly legal to reference files in a subdirectory that doesn't have its own BUILD file.

Signed-off-by: Alex Konradi <akonradi@google.com>
  • Loading branch information
akonradi authored Mar 8, 2021
1 parent b79666f commit c7b588c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
35 changes: 26 additions & 9 deletions bazel/protobuf.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,30 @@ def _path_ignoring_repository(f):
# before "external/workspace", so we need to add the starting index of "external/workspace"
return f.path[f.path.find(f.owner.workspace_root) + len(f.owner.workspace_root) + 1:]

def _protoc_cc_output_files(proto_file_sources):
def _package_relative_path(ctx, file):
# Remove the path prefix common to both the BUILD file that defines the
# package and the input file.
path_parts = file.short_path.split("/")
for piece in ctx.build_file_path.split("/"):
if path_parts[0] != piece:
break
path_parts.pop(0)

return "/".join(path_parts)

def _protoc_cc_output_files(ctx, proto_file_sources):
cc_hdrs = []
cc_srcs = []

for p in proto_file_sources:
basename = p.basename[:-len(".proto")]
# The returned path needs to be relative to the package directory.
file_path = _package_relative_path(ctx, p)

cc_hdrs.append(basename + ".pb.validate.h")
if p.basename.endswith(".proto"):
file_path = file_path[:-len(".proto")]

cc_srcs.append(basename + ".pb.validate.cc")
cc_hdrs.append(file_path + ".pb.validate.h")
cc_srcs.append(file_path + ".pb.validate.cc")

return cc_hdrs + cc_srcs

Expand All @@ -51,7 +65,7 @@ def _protoc_gen_validate_cc_impl(ctx):
"""Generate C++ protos using protoc-gen-validate plugin"""
protos = _proto_sources(ctx)

cc_files = _protoc_cc_output_files(protos)
cc_files = _protoc_cc_output_files(ctx, protos)
out_files = [ctx.actions.declare_file(out) for out in cc_files]

dir_out = _output_dir(ctx)
Expand All @@ -69,20 +83,23 @@ def _protoc_gen_validate_cc_impl(ctx):
package_command = "true",
)

def _protoc_python_output_files(proto_file_sources):
def _protoc_python_output_files(ctx, proto_file_sources):
python_srcs = []

for p in proto_file_sources:
basename = p.basename[:-len(".proto")]
# The returned path needs to be relative to the package directory.
file_path = _package_relative_path(ctx, p)
if file_path.endswith(".proto"):
file_path = file_path[:-len(".proto")]

python_srcs.append(basename.replace("-", "_") + "_pb2.py")
python_srcs.append(file_path.replace("-", "_") + "_pb2.py")
return python_srcs

def _protoc_gen_validate_python_impl(ctx):
"""Generate Python protos using protoc-gen-validate plugin"""
protos = _proto_sources(ctx)

python_files = _protoc_python_output_files(protos)
python_files = _protoc_python_output_files(ctx, protos)
out_files = [ctx.actions.declare_file(out) for out in python_files]

dir_out = _output_dir(ctx)
Expand Down
1 change: 1 addition & 0 deletions tests/harness/cases/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ proto_library(
"oneofs.proto",
"repeated.proto",
"strings.proto",
"subdirectory/in_subdirectory.proto",
"wkt_any.proto",
"wkt_duration.proto",
"wkt_timestamp.proto",
Expand Down
7 changes: 7 additions & 0 deletions tests/harness/cases/subdirectory/in_subdirectory.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

package tests.harness.cases;
option go_package = "cases";

import "validate/validate.proto";

0 comments on commit c7b588c

Please sign in to comment.