From 3abd865342195b49f1db0d33e5f77848ebdadcb3 Mon Sep 17 00:00:00 2001 From: Will Schmitt Date: Tue, 6 Aug 2024 15:05:34 -0700 Subject: [PATCH] fix: convert forward slashes to backslashes for protoc plugins on Windows. Fixes https://github.com/aspect-build/rules_ts/issues/667 This takes the approach [rules_proto_grpc does](https://github.com/rules-proto-grpc/rules_proto_grpc/blob/9e61a4c3dfc78de163febe7530bd04dabfbcca16/modules/core/internal/protoc.bzl#L79-L83) to detect if we are building on Windows via the `host_path_separator`. protoc will fail to call into the plugins if they are expressed to protoc as forward-slash paths. --- ts/private/ts_proto_library.bzl | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ts/private/ts_proto_library.bzl b/ts/private/ts_proto_library.bzl index ccd08927..ccdd537c 100644 --- a/ts/private/ts_proto_library.bzl +++ b/ts/private/ts_proto_library.bzl @@ -6,6 +6,16 @@ load("@rules_proto//proto:proto_common.bzl", proto_toolchains = "toolchains") _PROTO_TOOLCHAIN_TYPE = "@rules_proto//proto:toolchain_type" +def _windows_path_normalize(ctx, path): + """Changes forward slashs to backslashs for Windows paths.""" + # This is a hack to check if we are on Windows, where we assume Windows + # if the PATH environment variable is split by ";", and POSIX is split by + # ":", exclusively. This is the same approach rules_proto_grpc takes to + # normalize Windows paths of plugins handed to protoc. + if ctx.configuration.host_path_separator == ";": + return path.replace("/", "\\") + return path + # buildifier: disable=function-docstring-header def _protoc_action(ctx, proto_info, outputs): """Create an action like @@ -29,19 +39,19 @@ def _protoc_action(ctx, proto_info, outputs): fail("protoc_gen_options.target must be 'js+dts'") args = ctx.actions.args() - args.add_joined(["--plugin", "protoc-gen-es", ctx.executable.protoc_gen_es.path], join_with = "=") + args.add_joined(["--plugin", "protoc-gen-es", _windows_path_normalize(ctx, ctx.executable.protoc_gen_es.path)], join_with = "=") for (key, value) in options.items(): args.add_joined(["--es_opt", key, value], join_with = "=") args.add_joined(["--es_out", ctx.bin_dir.path], join_with = "=") if ctx.attr.gen_connect_es: - args.add_joined(["--plugin", "protoc-gen-connect-es", ctx.executable.protoc_gen_connect_es.path], join_with = "=") + args.add_joined(["--plugin", "protoc-gen-connect-es", _windows_path_normalize(ctx, ctx.executable.protoc_gen_connect_es.path)], join_with = "=") for (key, value) in options.items(): args.add_joined(["--connect-es_opt", key, value], join_with = "=") args.add_joined(["--connect-es_out", ctx.bin_dir.path], join_with = "=") if ctx.attr.gen_connect_query: - args.add_joined(["--plugin", "protoc-gen-connect-query", ctx.executable.protoc_gen_connect_query.path], join_with = "=") + args.add_joined(["--plugin", "protoc-gen-connect-query", _windows_path_normalize(ctx, ctx.executable.protoc_gen_connect_query.path)], join_with = "=") for (key, value) in options.items(): args.add_joined(["--connect-query_opt", key, value], join_with = "=") args.add_joined(["--connect-query_out", ctx.bin_dir.path], join_with = "=")