diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl index aeacfba8da6..a12208e9579 100644 --- a/bazel/protobuf.bzl +++ b/bazel/protobuf.bzl @@ -145,6 +145,29 @@ def get_plugin_args( ), ] +def _make_prefix(label): + """Returns the directory prefix for a label. + + @repo//foo/bar:sub/dir/file.proto => 'external/repo/foo/bar/' + //foo/bar:sub/dir/file.proto => 'foo/bar/' + //:sub/dir/file.proto => '' + + That is, the prefix can be removed from a file's full path to + obtain the file's relative location within the package's effective + directory.""" + + wsr = label.workspace_root + pkg = label.package + + if not wsr and not pkg: + return "" + elif not wsr: + return pkg + "/" + elif not pkg: + return wsr + "/" + else: + return wsr + "/" + pkg + "/" + def get_staged_proto_file(label, context, source_file): """Copies a proto file to the appropriate location if necessary. @@ -163,7 +186,8 @@ def get_staged_proto_file(label, context, source_file): else: # Current target and source_file are in different packages (most # probably even in different repositories) - copied_proto = context.actions.declare_file(source_file.basename) + prefix = _make_prefix(source_file.owner) + copied_proto = context.actions.declare_file(source_file.path[len(prefix):]) context.actions.run_shell( inputs = [source_file], outputs = [copied_proto], @@ -236,10 +260,14 @@ def declare_out_files(protos, context, generated_file_format): out_file_paths = [] for proto in protos: if not is_in_virtual_imports(proto): - out_file_paths.append(proto.basename) + prefix = _make_prefix(proto.owner) + full_prefix = context.genfiles_dir.path + "/" + prefix + if proto.path.startswith(full_prefix): + out_file_paths.append(proto.path[len(full_prefix):]) + elif proto.path.startswith(prefix): + out_file_paths.append(proto.path[len(prefix):]) else: - path = proto.path[proto.path.index(_VIRTUAL_IMPORTS) + 1:] - out_file_paths.append(path) + out_file_paths.append(proto.path[proto.path.index(_VIRTUAL_IMPORTS) + 1:]) return [ context.actions.declare_file( diff --git a/bazel/test/python_test_repo/BUILD b/bazel/test/python_test_repo/BUILD index b0f0e53d95e..127a43568c8 100644 --- a/bazel/test/python_test_repo/BUILD +++ b/bazel/test/python_test_repo/BUILD @@ -29,11 +29,18 @@ proto_library( name = "helloworld_proto", srcs = ["helloworld.proto"], deps = [ + ":hello_dep_proto", "@com_google_protobuf//:duration_proto", "@com_google_protobuf//:timestamp_proto", ], ) +# Test that .proto files can be located in strict subdiretories of the package. +proto_library( + name = "hello_dep_proto", + srcs = ["subdir/hello_dep.proto"], +) + py_proto_library( name = "helloworld_py_pb2", deps = [":helloworld_proto"], @@ -79,6 +86,7 @@ proto_library( import_prefix = "google/cloud", strip_import_prefix = "", deps = [ + ":hello_dep_proto", "@com_google_protobuf//:duration_proto", "@com_google_protobuf//:timestamp_proto", ], diff --git a/bazel/test/python_test_repo/helloworld.proto b/bazel/test/python_test_repo/helloworld.proto index b333a7409b8..d9cb0b53c30 100644 --- a/bazel/test/python_test_repo/helloworld.proto +++ b/bazel/test/python_test_repo/helloworld.proto @@ -23,6 +23,7 @@ package helloworld; import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; +import "subdir/hello_dep.proto"; // The greeting service definition. service Greeter { @@ -36,8 +37,10 @@ message HelloRequest { google.protobuf.Timestamp request_initiation = 2; } -// The response message containing the greetings +// The response message containing the greetings, plus some additional +// data of a type defined in a separate .proto file. message HelloReply { string message = 1; google.protobuf.Duration request_duration = 2; + HelloDep dep = 3; } diff --git a/bazel/test/python_test_repo/subdir/hello_dep.proto b/bazel/test/python_test_repo/subdir/hello_dep.proto new file mode 100644 index 00000000000..ad9f751496d --- /dev/null +++ b/bazel/test/python_test_repo/subdir/hello_dep.proto @@ -0,0 +1,21 @@ +// Copyright 2019 The gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package helloworld; + +message HelloDep { + repeated int64 numbers = 1; +}