Skip to content

Commit 25194a2

Browse files
amarijbedard
authored andcommitted
fix: ts_proto_library with strip_import_prefix in proto_library
1 parent dbc0731 commit 25194a2

File tree

5 files changed

+116
-8
lines changed

5 files changed

+116
-8
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
2+
3+
// @generated by protoc-gen-connect-es v1.4.0 with parameter "keep_empty_files=true,target=js+dts"
4+
// @generated from file examples/proto_grpc/status.proto (package rpc, syntax proto3)
5+
/* eslint-disable */
6+
// @ts-nocheck
7+

examples/proto_grpc/status_pb.d.ts

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/proto_grpc/stripping/BUILD.bazel

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ proto_library(
88
# When set, the .proto source files in the srcs attribute of this rule are accessible at
99
# is the value of this attribute prepended to their repository-relative path.
1010
# The prefix in the strip_import_prefix attribute is removed before this prefix is added.
11-
#import_prefix = "a",
11+
import_prefix = "post-stripped",
1212
# The prefix to strip from the paths of the .proto files in this rule.
1313
# When set, .proto source files in the srcs attribute of this rule are accessible at their path with this prefix cut off.
1414
# If it's a relative path (not starting with a slash), it's taken as a package-relative one.
1515
# If it's an absolute one, it's understood as a repository-relative path.
16-
#strip_import_prefix = "stripping",
16+
strip_import_prefix = "/examples",
1717
visibility = ["//visibility:public"],
1818
)
1919

2020
ts_proto_library(
2121
name = "s_ts_proto",
22-
copy_files = False,
2322
node_modules = "//examples/proto_grpc:node_modules",
2423
proto = ":s_proto",
24+
proto_srcs = ["s.proto"],
2525
visibility = ["//visibility:public"],
2626
)

examples/proto_grpc/stripping/s_pb.d.ts

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ts/private/ts_proto_library.bzl

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,43 @@ def _windows_path_normalize(path):
1414
return path.replace("/", "\\")
1515
return path
1616

17+
# These 3 helpers are from "@protobuf//bazel/common:proto_common.bzl"
18+
# After migrating, from @rules_proto to @protobuf, they can be replaced by a single load statement.
19+
# See https://github.com/protocolbuffers/protobuf/blob/main/bazel/common/proto_common.bzl .
20+
21+
def _import_virtual_proto_path(path):
22+
"""Imports all paths for virtual imports.
23+
24+
They're of the form:
25+
'bazel-out/k8-fastbuild/bin/external/foo/e/_virtual_imports/e' or
26+
'bazel-out/foo/k8-fastbuild/bin/e/_virtual_imports/e'"""
27+
if path.count("/") > 4:
28+
return "-I%s" % path
29+
return None
30+
31+
def _import_repo_proto_path(path):
32+
"""Imports all paths for generated files in external repositories.
33+
34+
They are of the form:
35+
'bazel-out/k8-fastbuild/bin/external/foo' or
36+
'bazel-out/foo/k8-fastbuild/bin'"""
37+
path_count = path.count("/")
38+
if path_count > 2 and path_count <= 4:
39+
return "-I%s" % path
40+
return None
41+
42+
def _import_main_output_proto_path(path):
43+
"""Imports all paths for generated files or source files in external repositories.
44+
45+
They're of the form:
46+
'bazel-out/k8-fastbuild/bin'
47+
'external/foo'
48+
'../foo'
49+
"""
50+
if path.count("/") <= 2 and path != ".":
51+
return "-I%s" % path
52+
return None
53+
1754
# buildifier: disable=function-docstring-header
1855
def _protoc_action(ctx, proto_info, outputs):
1956
"""Create an action like
@@ -26,6 +63,13 @@ def _protoc_action(ctx, proto_info, outputs):
2663
"""
2764
inputs = depset(proto_info.direct_sources, transitive = [proto_info.transitive_descriptor_sets])
2865

66+
# ensure that bin_dir doesn't get duplicated in the path
67+
# e.g. by proto_library(strip_import_prefix=...)
68+
proto_root = proto_info.proto_source_root
69+
if proto_root.startswith(ctx.bin_dir.path):
70+
proto_root = proto_root[len(ctx.bin_dir.path) + 1:]
71+
plugin_output = ctx.bin_dir.path + "/" + proto_root
72+
2973
options = dict({
3074
"keep_empty_files": True,
3175
"target": "js+dts",
@@ -40,23 +84,38 @@ def _protoc_action(ctx, proto_info, outputs):
4084
args.add_joined(["--plugin", "protoc-gen-es", _windows_path_normalize(ctx.executable.protoc_gen_es.path)], join_with = "=")
4185
for (key, value) in options.items():
4286
args.add_joined(["--es_opt", key, value], join_with = "=")
43-
args.add_joined(["--es_out", ctx.bin_dir.path], join_with = "=")
87+
args.add_joined(["--es_out", plugin_output], join_with = "=")
4488

4589
if ctx.attr.gen_connect_es:
4690
args.add_joined(["--plugin", "protoc-gen-connect-es", _windows_path_normalize(ctx.executable.protoc_gen_connect_es.path)], join_with = "=")
4791
for (key, value) in options.items():
4892
args.add_joined(["--connect-es_opt", key, value], join_with = "=")
49-
args.add_joined(["--connect-es_out", ctx.bin_dir.path], join_with = "=")
93+
args.add_joined(["--connect-es_out", plugin_output], join_with = "=")
5094

5195
if ctx.attr.gen_connect_query:
5296
args.add_joined(["--plugin", "protoc-gen-connect-query", _windows_path_normalize(ctx.executable.protoc_gen_connect_query.path)], join_with = "=")
5397
for (key, value) in options.items():
5498
args.add_joined(["--connect-query_opt", key, value], join_with = "=")
55-
args.add_joined(["--connect-query_out", ctx.bin_dir.path], join_with = "=")
99+
args.add_joined(["--connect-query_out", plugin_output], join_with = "=")
56100

57101
args.add("--descriptor_set_in")
58102
args.add_joined(proto_info.transitive_descriptor_sets, join_with = ctx.configuration.host_path_separator)
59103

104+
# Also from "@protobuf//bazel/common:proto_common.bzl":
105+
#
106+
# Protoc searches for .protos -I paths in order they are given and then
107+
# uses the path within the directory as the package.
108+
# This requires ordering the paths from most specific (longest) to least
109+
# specific ones, so that no path in the list is a prefix of any of the
110+
# following paths in the list.
111+
# For example: 'bazel-out/k8-fastbuild/bin/external/foo' needs to be listed
112+
# before 'bazel-out/k8-fastbuild/bin'. If not, protoc will discover file under
113+
# the shorter path and use 'external/foo/...' as its package path.
114+
args.add_all(proto_info.transitive_proto_path, map_each = _import_virtual_proto_path)
115+
args.add_all(proto_info.transitive_proto_path, map_each = _import_repo_proto_path)
116+
args.add_all(proto_info.transitive_proto_path, map_each = _import_main_output_proto_path)
117+
args.add("-I.")
118+
60119
args.add_all(proto_info.direct_sources)
61120

62121
proto_toolchain_enabled = len(proto_toolchains.use_toolchain(_PROTO_TOOLCHAIN_TYPE)) > 0
@@ -81,10 +140,17 @@ def _declare_outs(ctx, info, ext):
81140
if ctx.attr.gen_connect_es:
82141
outs.extend(proto_common.declare_generated_files(ctx.actions, info, "_connect" + ext))
83142
if ctx.attr.gen_connect_query:
143+
proto_sources = info.direct_sources
144+
proto_source_map = {src.basename: src for src in proto_sources}
145+
146+
# FIXME: we should refer to source files via labels instead of filenames
84147
for proto, services in ctx.attr.gen_connect_query_service_mapping.items():
148+
if not proto in proto_source_map:
149+
fail("{} is not provided by proto_srcs".format(proto))
150+
src = proto_source_map.get(proto)
151+
prefix = proto.replace(".proto", "")
85152
for service in services:
86-
prefix = proto.replace(".proto", "")
87-
outs.append(ctx.actions.declare_file("{}-{}_connectquery{}".format(prefix, service, ext)))
153+
outs.append(ctx.actions.declare_file("{}-{}_connectquery{}".format(prefix, service, ext), sibling = src))
88154

89155
return outs
90156

0 commit comments

Comments
 (0)