From 4162cc54ba0b128b616c0bd05b65bf9ad5e66f2e Mon Sep 17 00:00:00 2001 From: Yannic Date: Mon, 13 Jan 2020 03:45:41 -0800 Subject: [PATCH] proto_lang_toolchain: Add original sources of ProtoInfo to blacklistedProtos Fixes #10484 Closes #10493. PiperOrigin-RevId: 289411825 --- .../lib/rules/cpp/proto/CcProtoAspect.java | 2 +- .../build/lib/rules/proto/ProtoCommon.java | 17 +++- .../build/lib/rules/proto/ProtoInfo.java | 17 ++-- .../lib/rules/proto/ProtoLangToolchain.java | 4 +- .../proto/ProtoCompileActionBuilderTest.java | 4 +- .../rules/proto/ProtoLangToolchainTest.java | 98 ++++++++++++++++--- 6 files changed, 115 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java index 1014c3977619f4..417a766dd83411 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java @@ -276,7 +276,7 @@ private static class Impl { private boolean areSrcsBlacklisted() { return !new ProtoSourceFileBlacklist( ruleContext, getProtoToolchainProvider().blacklistedProtos()) - .checkSrcs(protoInfo.getOriginalDirectProtoSources(), "cc_proto_library"); + .checkSrcs(protoInfo.getOriginalTransitiveProtoSources(), "cc_proto_library"); } private FeatureConfiguration getFeatureConfiguration() { diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java index b75ec62ccb2243..a7e8dcd22a21f6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java @@ -127,6 +127,19 @@ private static NestedSet computeTransitiveProtoSources( return result.build(); } + private static NestedSet computeTransitiveOriginalProtoSources( + RuleContext ruleContext, ImmutableList originalProtoSources) { + NestedSetBuilder result = NestedSetBuilder.naiveLinkOrder(); + + result.addAll(originalProtoSources); + + for (ProtoInfo dep : ruleContext.getPrerequisites("deps", Mode.TARGET, ProtoInfo.PROVIDER)) { + result.addTransitive(dep.getOriginalTransitiveProtoSources()); + } + + return result.build(); + } + static NestedSet computeDependenciesDescriptorSets(RuleContext ruleContext) { NestedSetBuilder result = NestedSetBuilder.stableOrder(); @@ -462,6 +475,8 @@ public static ProtoInfo createProtoInfo( NestedSet transitiveProtoSources = computeTransitiveProtoSources(ruleContext, library.getSources()); + NestedSet transitiveOriginalProtoSources = + computeTransitiveOriginalProtoSources(ruleContext, directProtoSources); NestedSet transitiveProtoSourceRoots = computeTransitiveProtoSourceRoots(ruleContext, library.getSourceRoot()); @@ -491,8 +506,8 @@ public static ProtoInfo createProtoInfo( ProtoInfo protoInfo = new ProtoInfo( library.getSources(), - directProtoSources, library.getSourceRoot(), + transitiveOriginalProtoSources, transitiveProtoSources, transitiveProtoSourceRoots, strictImportableProtosForDependents, diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoInfo.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoInfo.java index f9a9280e539b39..7621e22c74602a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoInfo.java @@ -54,7 +54,7 @@ public Provider() { public static final String LEGACY_SKYLARK_NAME = "proto"; private final ImmutableList directProtoSources; - private final ImmutableList originalDirectProtoSources; + private final NestedSet originalTransitiveProtoSources; private final String directProtoSourceRoot; private final NestedSet transitiveProtoSources; private final NestedSet transitiveProtoSourceRoots; @@ -71,8 +71,8 @@ public Provider() { @AutoCodec.Instantiator public ProtoInfo( ImmutableList directProtoSources, - ImmutableList originalDirectProtoSources, String directProtoSourceRoot, + NestedSet originalTransitiveProtoSources, NestedSet transitiveProtoSources, NestedSet transitiveProtoSourceRoots, NestedSet strictImportableProtoSourcesForDependents, @@ -86,7 +86,7 @@ public ProtoInfo( Location location) { super(PROVIDER, location); this.directProtoSources = directProtoSources; - this.originalDirectProtoSources = originalDirectProtoSources; + this.originalTransitiveProtoSources = originalTransitiveProtoSources; this.directProtoSourceRoot = directProtoSourceRoot; this.transitiveProtoSources = transitiveProtoSources; this.transitiveProtoSourceRoots = transitiveProtoSourceRoots; @@ -103,17 +103,18 @@ public ProtoInfo( /** * The proto source files that are used in compiling this {@code proto_library}. - * - *

Different from {@link #getOriginalDirectProtoSources()} when a virtual import root is used. */ @Override public ImmutableList getDirectProtoSources() { return directProtoSources; } - /** The proto sources of the {@code proto_library} declaring this provider. */ - public ImmutableList getOriginalDirectProtoSources() { - return originalDirectProtoSources; + /** + * The non-virtual transitive proto source files. Different from {@link + * #getTransitiveProtoSources()} if a transitive dependency has {@code import_prefix} or the like. + */ + public NestedSet getOriginalTransitiveProtoSources() { + return originalTransitiveProtoSources; } /** The source root of the current library. */ diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java index ea124b56ee52cb..7c16d8d3989abd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java @@ -44,8 +44,10 @@ public ConfiguredTarget create(RuleContext ruleContext) ProtoInfo protoInfo = protos.get(ProtoInfo.PROVIDER); // TODO(cushon): it would be nice to make this mandatory and stop adding files to build too if (protoInfo != null) { - blacklistedProtos.addTransitive(protoInfo.getTransitiveProtoSources()); + blacklistedProtos.addTransitive(protoInfo.getOriginalTransitiveProtoSources()); } else { + // Only add files from FileProvider if |protos| is not a proto_library to avoid adding + // the descriptor_set of proto_library to the list of blacklisted files. blacklistedProtos.addTransitive(protos.getProvider(FileProvider.class).getFilesToBuild()); } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java index 72c0dc66b6ccc1..6d4fd31cc601c2 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilderTest.java @@ -65,8 +65,8 @@ private ProtoInfo protoInfo( NestedSet> exportedProtos) { return new ProtoInfo( directProtos, - directProtos, - "", + /* directProtoSourceRoot= */ "", + transitiveProtos, transitiveProtos, transitiveProtoSourceRoots, /* strictImportableProtosForDependents */ NestedSetBuilder.emptySet(Order.STABLE_ORDER), diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java index dd09ca1189405c..3ae72eb0315409 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java @@ -39,10 +39,27 @@ public void setUp() throws Exception { invalidatePackages(); } + private void validateProtoLangToolchain(ProtoLangToolchainProvider toolchain) throws Exception { + assertThat(toolchain.commandLine()).isEqualTo("cmd-line"); + assertThat(toolchain.pluginExecutable().getExecutable().getRootRelativePathString()) + .isEqualTo("third_party/x/plugin"); + + TransitiveInfoCollection runtimes = toolchain.runtime(); + assertThat(runtimes.getLabel()) + .isEqualTo(Label.parseAbsolute("//third_party/x:runtime", ImmutableMap.of())); + + assertThat(prettyArtifactNames(toolchain.blacklistedProtos())) + .containsExactly( + "third_party/x/metadata.proto", + "third_party/x/descriptor.proto", + "third_party/x/any.proto"); + } + @Test public void protoToolchain() throws Exception { scratch.file( - "x/BUILD", + "third_party/x/BUILD", + "licenses(['unencumbered'])", "cc_binary(name = 'plugin', srcs = ['plugin.cc'])", "cc_library(name = 'runtime', srcs = ['runtime.cc'])", "filegroup(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])", @@ -52,29 +69,82 @@ public void protoToolchain() throws Exception { scratch.file( "foo/BUILD", TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, + "licenses(['unencumbered'])", "proto_lang_toolchain(", " name = 'toolchain',", " command_line = 'cmd-line',", - " plugin = '//x:plugin',", - " runtime = '//x:runtime',", - " blacklisted_protos = ['//x:blacklist']", + " plugin = '//third_party/x:plugin',", + " runtime = '//third_party/x:runtime',", + " blacklisted_protos = ['//third_party/x:blacklist']", ")"); update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus()); - ProtoLangToolchainProvider toolchain = - getConfiguredTarget("//foo:toolchain").getProvider(ProtoLangToolchainProvider.class); + validateProtoLangToolchain( + getConfiguredTarget("//foo:toolchain").getProvider(ProtoLangToolchainProvider.class)); + } - assertThat(toolchain.commandLine()).isEqualTo("cmd-line"); - assertThat(toolchain.pluginExecutable().getExecutable().getRootRelativePathString()) - .isEqualTo("x/plugin"); + @Test + public void protoToolchainBlacklistProtoLibraries() throws Exception { + scratch.file( + "third_party/x/BUILD", + TestConstants.LOAD_PROTO_LIBRARY, + "licenses(['unencumbered'])", + "cc_binary(name = 'plugin', srcs = ['plugin.cc'])", + "cc_library(name = 'runtime', srcs = ['runtime.cc'])", + "proto_library(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])", + "proto_library(name = 'any', srcs = ['any.proto'], strip_import_prefix = '/third_party')"); - TransitiveInfoCollection runtimes = toolchain.runtime(); - assertThat(runtimes.getLabel()) - .isEqualTo(Label.parseAbsolute("//x:runtime", ImmutableMap.of())); + scratch.file( + "foo/BUILD", + TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, + "proto_lang_toolchain(", + " name = 'toolchain',", + " command_line = 'cmd-line',", + " plugin = '//third_party/x:plugin',", + " runtime = '//third_party/x:runtime',", + " blacklisted_protos = ['//third_party/x:descriptors', '//third_party/x:any']", + ")"); - assertThat(prettyArtifactNames(toolchain.blacklistedProtos())) - .containsExactly("x/metadata.proto", "x/descriptor.proto", "x/any.proto"); + update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus()); + + validateProtoLangToolchain( + getConfiguredTarget("//foo:toolchain").getProvider(ProtoLangToolchainProvider.class)); + } + + @Test + public void protoToolchainMixedBlacklist() throws Exception { + scratch.file( + "third_party/x/BUILD", + TestConstants.LOAD_PROTO_LIBRARY, + "licenses(['unencumbered'])", + "cc_binary(name = 'plugin', srcs = ['plugin.cc'])", + "cc_library(name = 'runtime', srcs = ['runtime.cc'])", + "proto_library(name = 'metadata', srcs = ['metadata.proto'])", + "proto_library(", + " name = 'descriptor',", + " srcs = ['descriptor.proto'],", + " strip_import_prefix = '/third_party')", + "filegroup(name = 'any', srcs = ['any.proto'])"); + + scratch.file( + "foo/BUILD", + TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, + "proto_lang_toolchain(", + " name = 'toolchain',", + " command_line = 'cmd-line',", + " plugin = '//third_party/x:plugin',", + " runtime = '//third_party/x:runtime',", + " blacklisted_protos = [", + " '//third_party/x:metadata',", + " '//third_party/x:descriptor',", + " '//third_party/x:any']", + ")"); + + update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus()); + + validateProtoLangToolchain( + getConfiguredTarget("//foo:toolchain").getProvider(ProtoLangToolchainProvider.class)); } @Test