From ef4912bd29d7ad019489060b5234d2358b54c970 Mon Sep 17 00:00:00 2001
From: Yannic Bonenberger
Do not use this field directly, its only puprose is to help with " + + "migration of Protobuf rules to Starlark.
" + + "Instead, you can access the value through proto_toolchain
" + + "pre class=\"language-python\">\n" + + "def _my_rule_impl(ctx):" + + " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n" + + " protoc = proto_toolchain.compiler\n" + + "
" ) public Label protoCompiler() { return options.protoCompiler; diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java index 3e8d5027bae41d..dea1b5225e71c4 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java @@ -26,25 +26,64 @@ name = "proto", category = SkylarkModuleCategory.CONFIGURATION_FRAGMENT, doc = "A configuration fragment representing protocol buffers. " - + "Do not use these fields, they will be removed after migrating " - + "Protobuf rules to Starlark." + + "Do not use these fields directly, they are considered an implementation " + + "detail and will be removed after migrating Protobuf rules to Starlark.
" + // TODO(yannic): Link to generated docs of `proto_toolchain`. + // https://github.com/bazelbuild/bazel/issues/9203 + + "Instead, you can access them through proto_toolchain
" + + "pre class=\"language-python\">\n" + + "def _my_rule_impl(ctx):\n" + + " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n" + + "\n" + + " # Contains the protoc binary, as specified by `--proto_compiler`.\n" + + " protoc = proto_toolchain.compiler\n" + + "\n" + + " # Contains extra args to pass to protoc, as specified by `--protocopt`.\n" + + " compiler_options = proto_toolchain.compiler_options\n" + + "\n" + + " # Contains the strict-dependency mode to use for Protocol Buffers\n" + + " # (i.e. 'OFF`, `WARN`, `ERROR`), as specified by `--strict_proto_deps`.\n" + + " strict_deps = proto_toolchain.strict_deps\n" + + "\n" + + "my_rule = rule(\n" + + " implementation = _my_rule_impl,\n" + + " attrs = {},\n" + + " toolchains = [\n" + + " \"@rules_proto//proto:toolchain\",\n" + + " ],\n" + + ")\n" + + "
" ) public interface ProtoConfigurationApi { @SkylarkCallable( - name = "protoc_opts", - doc = "Additional options to pass to the protobuf compiler. " - + "Do not use this field, its only puprose is to help with migration of " - + "Protobuf rules to Starlark.", + // Must match the value of `_protocopt_key` + // in `@rules_proto//proto/private/rules:proto_toolchain.bzl`. + name = "protocopt_do_not_use_or_we_will_break_you_without_mercy", + doc = "Exposes the value of `--protocopt`." + + "Do not use this field directly, its only puprose is to help with " + + "migration of Protobuf rules to Starlark.
" + + "Instead, you can access the value through proto_toolchain
" + + "pre class=\"language-python\">\n" + + "def _my_rule_impl(ctx):" + + " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n" + + " compiler_options = proto_toolchain.compiler_options\n" + + "
", structField = true) ImmutableListDo not use this field directly, its only puprose is to help with " + + "migration of Protobuf rules to Starlark.
" + + "Instead, you can access the value through proto_toolchain
" + + "pre class=\"language-python\">\n" + + "def _my_rule_impl(ctx):" + + " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n" + + " strict_deps = proto_toolchain.strict_deps\n" + + "
", structField = true) String starlarkStrictDeps(); } diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java index b9e7c2cb5be6fe..f8b8438553f4ac 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java @@ -34,7 +34,7 @@ public interface ProtoModuleApi { @Deprecated @SkylarkCallable( - name = "do_not_use_has_configuration_field_protoc", + name = "has_protoc_do_not_use_or_we_will_break_you_without_mercy", doc = "Do not use this field, its only puprose is to help with migration of " + "Protobuf rules to Starlark.", structField = true) From 0f2ce4e7024e5e83d8d5271f5a0257f451dc14fb Mon Sep 17 00:00:00 2001 From: Yannic BonenbergerDo not use this field directly, its only puprose is to help with " + + "
Do not use this field directly, its only purpose is to help with " + "migration of Protobuf rules to Starlark.
" + "Instead, you can access the value through proto_toolchain
" + "pre class=\"language-python\">\n" diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java index dea1b5225e71c4..92d0e590bcdcd4 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ProtoConfigurationApi.java @@ -60,7 +60,7 @@ public interface ProtoConfigurationApi { // in `@rules_proto//proto/private/rules:proto_toolchain.bzl`. name = "protocopt_do_not_use_or_we_will_break_you_without_mercy", doc = "Exposes the value of `--protocopt`." - + "
Do not use this field directly, its only puprose is to help with " + + "
Do not use this field directly, its only purpose is to help with " + "migration of Protobuf rules to Starlark.
" + "Instead, you can access the value through proto_toolchain
" + "pre class=\"language-python\">\n" @@ -76,7 +76,7 @@ public interface ProtoConfigurationApi { // in `@rules_proto//proto/private/rules:proto_toolchain.bzl`. name = "strict_deps_do_not_use_or_we_will_break_you_without_mercy", doc = "Exposes the value of `--strict_proto_deps`." - + "
Do not use this field directly, its only puprose is to help with " + + "
Do not use this field directly, its only purpose is to help with " + "migration of Protobuf rules to Starlark.
" + "Instead, you can access the value through proto_toolchain
" + "pre class=\"language-python\">\n"
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java
index f8b8438553f4ac..90164a3a189adb 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto/ProtoModuleApi.java
@@ -35,7 +35,7 @@ public interface ProtoModuleApi {
@Deprecated
@SkylarkCallable(
name = "has_protoc_do_not_use_or_we_will_break_you_without_mercy",
- doc = "Do not use this field, its only puprose is to help with migration of "
+ doc = "Do not use this field, its only purpose is to help with migration of "
+ "Protobuf rules to Starlark.",
structField = true)
default void configurationFieldProtocExists() {}
From f4bef507bd12601f2aba3047f18a90ac52a65ba8 Mon Sep 17 00:00:00 2001
From: Yannic Bonenberger Instead, you can access them through proto_toolchain pre class=\"language-python\">\n"
+ + " Do not use this field directly, its only purpose is to help with "
+ "migration of Protobuf rules to Starlark. Instead, you can access the value through proto_toolchain pre class=\"language-python\">\n"
+ + " Do not use this field directly, its only purpose is to help with "
+ "migration of Protobuf rules to Starlark. Instead, you can access the value through proto_toolchain pre class=\"language-python\">\n"
+ + " Do not use this field directly, its only purpose is to help with "
+ "migration of Protobuf rules to Starlark. Instead, you can access the value through proto_toolchain pre class=\"language-python\">\n"
+ + "\n"
+ "def _my_rule_impl(ctx):\n"
+ " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n"
+ "\n"
@@ -63,7 +63,7 @@ public interface ProtoConfigurationApi {
+ "
\n"
+ "def _my_rule_impl(ctx):"
+ " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n"
+ " compiler_options = proto_toolchain.compiler_options\n"
@@ -79,7 +79,7 @@ public interface ProtoConfigurationApi {
+ "
\n"
+ "def _my_rule_impl(ctx):"
+ " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n"
+ " strict_deps = proto_toolchain.strict_deps\n"
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index 454f11ab322cad..2bbbd8f1af7f51 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -1501,6 +1501,23 @@ java_test(
],
)
+java_test(
+ name = "ProtoConfigurationTest",
+ srcs = ["rules/proto/ProtoConfigurationTest.java"],
+ deps = [
+ ":actions_testutil",
+ ":analysis_testutil",
+ ":guava_junit_truth",
+ ":packages_testutil",
+ "//src/main/java/com/google/devtools/build/lib:build-base",
+ "//src/main/java/com/google/devtools/build/lib:proto-rules",
+ "//src/main/java/com/google/devtools/build/lib:util",
+ "//src/main/java/com/google/devtools/build/lib/actions",
+ "//src/main/java/com/google/devtools/build/lib/cmdline",
+ "//src/test/java/com/google/devtools/build/lib:testutil",
+ ],
+)
+
java_test(
name = "BazelProtoLibraryTest",
srcs = ["rules/proto/BazelProtoLibraryTest.java"],
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoConfigurationTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoConfigurationTest.java
new file mode 100644
index 00000000000000..0f5494a138bb8c
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoConfigurationTest.java
@@ -0,0 +1,142 @@
+// Copyright 2019 The Bazel Authors. All rights reserved.
+//
+// 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.
+
+package com.google.devtools.build.lib.rules.proto;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.getFirstArtifactEndingWith;
+import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.eventbus.EventBus;
+import com.google.devtools.build.lib.actions.Action;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.util.MockProtoSupport;
+import com.google.devtools.build.lib.testutil.TestConstants;
+import com.google.devtools.build.lib.analysis.DefaultInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ProtoConfigurationTest extends BuildViewTestCase {
+ @Before
+ public void setUp() throws Exception {
+ MockProtoSupport.setupWorkspace(scratch);
+ invalidatePackages();
+
+ scratch.file("proto/BUILD", "cc_binary(name='compiler')");
+ scratch.file(
+ "proto/defs.bzl",
+ "def check_proto_common():",
+ " if not hasattr(proto_common,",
+ " 'has_protoc_do_not_use_or_we_will_break_you_without_mercy'):",
+ " fail('missing has_protoc_... attribute on proto_common')",
+ "check_proto_common()",
+ "",
+ "def _echo_protocopt_impl(ctx):",
+ " opts = ctx.fragments.proto.protocopt_do_not_use_or_we_will_break_you_without_mercy",
+ " f = ctx.actions.declare_file(ctx.attr.name)",
+ " ctx.actions.run(executable='echo',outputs=[f], arguments=opts)",
+ " return [DefaultInfo(files=depset([f]))]",
+ "echo_protocopt = rule(_echo_protocopt_impl, fragments=['proto'])",
+ "",
+ "def _echo_strict_deps_impl(ctx):",
+ " s = ctx.fragments.proto.strict_deps_do_not_use_or_we_will_break_you_without_mercy",
+ " f = ctx.actions.declare_file(ctx.attr.name)",
+ " ctx.actions.run(executable='echo',outputs=[f], arguments=[s])",
+ " return [DefaultInfo(files=depset([f]))]",
+ "echo_strict_deps = rule(_echo_strict_deps_impl, fragments=['proto'])",
+ "",
+ "def _echo_proto_compiler_impl(ctx):",
+ " return [DefaultInfo(files=depset([ctx.executable._compiler]))]",
+ "_protoc_key = 'protoc_do_not_use_or_we_will_break_you_without_mercy'",
+ "echo_proto_compiler = rule(",
+ " implementation = _echo_proto_compiler_impl,",
+ " attrs = {",
+ " '_compiler': attr.label(",
+ " executable = True,",
+ " cfg = 'host',",
+ " default = configuration_field('proto', _protoc_key),",
+ " ),",
+ " },",
+ " fragments=['proto']",
+ ")");
+ }
+
+ private Artifact getArtifact(String target, String file) throws Exception {
+ return getFirstArtifactEndingWith(getFilesToBuild(getConfiguredTarget(target)), file);
+ }
+
+ @Test
+ public void readProtocopt() throws Exception {
+ scratch.file(
+ "x/BUILD",
+ "load('//proto:defs.bzl', 'echo_protocopt')",
+ "echo_protocopt(name = 'x')");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .isEmpty();
+
+ useConfiguration("--protocopt=--foo", "--protocopt=--bar=10");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("--foo", "--bar=10");
+ }
+
+ @Test
+ public void readStrictDeps() throws Exception {
+ scratch.file(
+ "x/BUILD",
+ "load('//proto:defs.bzl', 'echo_strict_deps')",
+ "echo_strict_deps(name = 'x')");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("ERROR");
+
+ useConfiguration("--strict_proto_deps=OFF");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("OFF");
+
+ useConfiguration("--strict_proto_deps=DEFAULT");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("OFF");
+
+ useConfiguration("--strict_proto_deps=WARN");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("WARN");
+
+ useConfiguration("--strict_proto_deps=ERROR");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("ERROR");
+
+ useConfiguration("--strict_proto_deps=DEFAULT");
+ assertThat(getGeneratingSpawnAction(getArtifact("//x", "x")).getRemainingArguments())
+ .containsExactly("OFF");
+ }
+
+ @Test
+ public void readProtoCompiler() throws Exception {
+ scratch.file(
+ "x/BUILD",
+ "load('//proto:defs.bzl', 'echo_proto_compiler')",
+ "echo_proto_compiler(name = 'x')");
+
+ useConfiguration("--proto_compiler=//proto:compiler");
+ assertThat(getArtifact("//x", "compiler").getRootRelativePathString())
+ .startsWith("proto/compiler"); // Ends with `.exe` on Windows.
+ }
+}
From 63ba7e5c7741df011ebe0c83eb4591631ebe40d0 Mon Sep 17 00:00:00 2001
From: Yannic Bonenberger
\n"
+ "def _my_rule_impl(ctx):"
+ " proto_toolchain = ctx.toolchains[\"@rules_proto//proto:toolchain\"]\n"
+ " protoc = proto_toolchain.compiler\n"