Automated rollback of commit bcc9812e27d172d964dd728b70651fe0b972df0e.
Fixes #8832.
*** Reason for rollback ***
Breaks internal tests
*** Original change description ***
Create a virtual proto import directory for proto_library rules with generated sources and ones with proto_source_root= set.
Fixes #7157.
RELNOTES: None.
PiperOrigin-RevId: 257179608
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java
index 8f44434..5933d06 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java
@@ -31,7 +31,7 @@
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws ActionConflictException {
- ProtoInfo protoInfo = ProtoCommon.createProtoInfo(ruleContext, true);
+ ProtoInfo protoInfo = ProtoCommon.createProtoInfo(ruleContext);
if (ruleContext.hasErrors()) {
return null;
}
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 195ca3d..1463bbf 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
@@ -194,22 +194,29 @@
// TODO(lberki): This should really be a PathFragment. Unfortunately, it's on the Starlark API of
// ProtoInfo so it's not an easy change :(
@Nullable
- private static Library createLibraryWithoutVirtualSourceRoot(
+ private static Library getProtoSourceRoot(
RuleContext ruleContext, ImmutableList<Artifact> directSources) {
- String protoSourceRoot =
+ String protoSourceRoot = computeEffectiveProtoSourceRoot(ruleContext);
+ if (ruleContext.hasErrors()) {
+ return null;
+ }
+
+ // This is the same as getPackageIdentifier().getPathUnderExecRoot() due to the check above for
+ // protoSourceRoot == package name, but it's a bit more future-proof.
+ String result =
ruleContext
.getLabel()
.getPackageIdentifier()
.getRepository()
.getPathUnderExecRoot()
+ .getRelative(protoSourceRoot)
.getPathString();
ImmutableList.Builder<Pair<Artifact, String>> builder = ImmutableList.builder();
for (Artifact protoSource : directSources) {
builder.add(new Pair<Artifact, String>(protoSource, null));
}
- return new Library(
- directSources, protoSourceRoot.isEmpty() ? "." : protoSourceRoot, builder.build());
+ return new Library(directSources, result.isEmpty() ? "." : result, builder.build());
}
private static PathFragment getPathFragmentAttribute(
@@ -236,36 +243,18 @@
* Returns the {@link Library} representing this <code>proto_library</code> rule if import prefix
* munging is done. Otherwise, returns null.
*/
- private static Library createLibraryWithVirtualSourceRootMaybe(
- RuleContext ruleContext,
- ImmutableList<Artifact> protoSources,
- boolean virtualImportsWithGeneratedProtoFiles) {
+ private static Library createVirtualImportDirectoryMaybe(
+ RuleContext ruleContext, ImmutableList<Artifact> protoSources) {
PathFragment importPrefixAttribute = getPathFragmentAttribute(ruleContext, "import_prefix");
PathFragment stripImportPrefixAttribute =
getPathFragmentAttribute(ruleContext, "strip_import_prefix");
- PathFragment protoSourceRootAttribute =
- getPathFragmentAttribute(ruleContext, "proto_source_root");
- boolean hasGeneratedSources = false;
- if (virtualImportsWithGeneratedProtoFiles) {
- for (Artifact protoSource : protoSources) {
- if (!protoSource.isSourceArtifact()) {
- hasGeneratedSources = true;
- break;
- }
- }
- }
-
- if (importPrefixAttribute == null
- && stripImportPrefixAttribute == null
- && protoSourceRootAttribute == null
- && !hasGeneratedSources) {
+ if (importPrefixAttribute == null && stripImportPrefixAttribute == null) {
// Simple case, no magic required.
return null;
}
- if (protoSourceRootAttribute != null
- && (importPrefixAttribute != null || stripImportPrefixAttribute != null)) {
+ if (!ruleContext.attributes().get("proto_source_root", STRING).isEmpty()) {
ruleContext.ruleError(
"the 'proto_source_root' attribute is incompatible with "
+ "'strip_import_prefix' and 'import_prefix");
@@ -273,62 +262,30 @@
}
PathFragment stripImportPrefix;
+ if (stripImportPrefixAttribute == null) {
+ stripImportPrefix = PathFragment.create(ruleContext.getLabel().getWorkspaceRoot());
+ } else if (stripImportPrefixAttribute.isAbsolute()) {
+ stripImportPrefix =
+ ruleContext
+ .getLabel()
+ .getPackageIdentifier()
+ .getRepository()
+ .getSourceRoot()
+ .getRelative(stripImportPrefixAttribute.toRelative());
+ } else {
+ stripImportPrefix = ruleContext.getPackageDirectory().getRelative(stripImportPrefixAttribute);
+ }
+
PathFragment importPrefix;
-
- if (stripImportPrefixAttribute != null || importPrefixAttribute != null) {
- if (stripImportPrefixAttribute == null) {
- stripImportPrefix = PathFragment.create(ruleContext.getLabel().getWorkspaceRoot());
- } else if (stripImportPrefixAttribute.isAbsolute()) {
- stripImportPrefix =
- ruleContext
- .getLabel()
- .getPackageIdentifier()
- .getRepository()
- .getSourceRoot()
- .getRelative(stripImportPrefixAttribute.toRelative());
- } else {
- stripImportPrefix =
- ruleContext.getPackageDirectory().getRelative(stripImportPrefixAttribute);
- }
-
- if (importPrefixAttribute != null) {
- importPrefix = importPrefixAttribute;
- } else {
- importPrefix = PathFragment.EMPTY_FRAGMENT;
- }
-
- if (importPrefix.isAbsolute()) {
- ruleContext.attributeError("import_prefix", "should be a relative path");
- return null;
- }
- } else if (protoSourceRootAttribute != null) {
- if (!ruleContext.getFragment(ProtoConfiguration.class).enableProtoSourceroot()) {
- ruleContext.attributeError("proto_source_root", "this attribute is not supported anymore");
- return null;
- }
-
- if (!ruleContext.getLabel().getPackageFragment().equals(protoSourceRootAttribute)) {
- ruleContext.attributeError(
- "proto_source_root",
- "proto_source_root must be the same as the package name ("
- + ruleContext.getLabel().getPackageName()
- + ")."
- + " not '"
- + protoSourceRootAttribute
- + "'.");
-
- return null;
- }
-
- stripImportPrefix = ruleContext.getPackageDirectory();
+ if (importPrefixAttribute == null) {
importPrefix = PathFragment.EMPTY_FRAGMENT;
} else {
- // Has generated sources, but neither strip_import_prefix nor import_prefix nor
- // proto_source_root.
- stripImportPrefix =
- ruleContext.getLabel().getPackageIdentifier().getRepository().getPathUnderExecRoot();
+ importPrefix = importPrefixAttribute;
+ }
- importPrefix = PathFragment.EMPTY_FRAGMENT;
+ if (importPrefix.isAbsolute()) {
+ ruleContext.attributeError("import_prefix", "should be a relative path");
+ return null;
}
ImmutableList.Builder<Artifact> symlinks = ImmutableList.builder();
@@ -351,9 +308,7 @@
symlinks.add(importsPair.second);
if (!ruleContext.getFragment(ProtoConfiguration.class).doNotUseBuggyImportPath()
- && stripImportPrefixAttribute == null
- && protoSourceRootAttribute == null
- && !hasGeneratedSources) {
+ && stripImportPrefixAttribute == null) {
Pair<PathFragment, Artifact> oldImportsPair =
computeImports(
ruleContext,
@@ -440,6 +395,29 @@
return getProtoSourceRootsOfAttribute(ruleContext, currentProtoSourceRoot, "exports");
}
+ private static String computeEffectiveProtoSourceRoot(RuleContext ruleContext) {
+ if (!ruleContext.attributes().isAttributeValueExplicitlySpecified("proto_source_root")) {
+ return "";
+ }
+
+ if (!ruleContext.getFragment(ProtoConfiguration.class).enableProtoSourceroot()) {
+ ruleContext.attributeError("proto_source_root", "this attribute is not supported anymore");
+ return "";
+ }
+
+ String protoSourceRoot = ruleContext.attributes().get("proto_source_root", STRING);
+ if (!ruleContext.getLabel().getPackageName().equals(protoSourceRoot)) {
+ ruleContext.attributeError(
+ "proto_source_root",
+ "proto_source_root must be the same as the package name ("
+ + ruleContext.getLabel().getPackageName() + ")."
+ + " not '" + protoSourceRoot + "'."
+ );
+ }
+
+ return protoSourceRoot;
+ }
+
/**
* Check that .proto files in sources are from the same package. This is done to avoid clashes
* with the generated sources.
@@ -464,20 +442,21 @@
* Creates the {@link ProtoInfo} for the {@code proto_library} rule associated with {@code
* ruleContext}.
*/
- public static ProtoInfo createProtoInfo(
- RuleContext ruleContext, boolean virtualImportsWithGeneratedProtoFiles) {
+ public static ProtoInfo createProtoInfo(RuleContext ruleContext) {
checkSourceFilesAreInSamePackage(ruleContext);
ImmutableList<Artifact> directProtoSources =
ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET).list();
- Library library =
- createLibraryWithVirtualSourceRootMaybe(
- ruleContext, directProtoSources, virtualImportsWithGeneratedProtoFiles);
+ Library library = createVirtualImportDirectoryMaybe(ruleContext, directProtoSources);
if (ruleContext.hasErrors()) {
return null;
}
if (library == null) {
- library = createLibraryWithoutVirtualSourceRoot(ruleContext, directProtoSources);
+ library = getProtoSourceRoot(ruleContext, directProtoSources);
+ }
+
+ if (ruleContext.hasErrors()) {
+ return null;
}
NestedSet<Artifact> transitiveProtoSources =
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoInfoStarlarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoInfoStarlarkTest.java
index 0815636..2f22ae2 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoInfoStarlarkTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoInfoStarlarkTest.java
@@ -164,7 +164,7 @@
public void testProtoSourceRootExportedInStarlark() throws Exception {
scratch.file(
- "foo/myTestRule.bzl",
+ "foo/myTsetRule.bzl",
"load('//myinfo:myinfo.bzl', 'MyInfo')",
"",
"def _my_test_rule_impl(ctx):",
@@ -180,7 +180,7 @@
scratch.file(
"foo/BUILD",
"",
- "load(':myTestRule.bzl', 'my_test_rule')",
+ "load(':myTsetRule.bzl', 'my_test_rule')",
"my_test_rule(",
" name = 'myRule',",
" protodep = ':myProto',",
@@ -193,8 +193,7 @@
ConfiguredTarget ct = getConfiguredTarget("//foo:myRule");
String protoSourceRoot = (String) getMyInfoFromTarget(ct).getValue("fetched_proto_source_root");
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
- assertThat(protoSourceRoot).isEqualTo(genfiles + "/foo/_virtual_imports/myProto");
+ assertThat(protoSourceRoot).isEqualTo("foo");
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java
index 803b514..225134e 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java
@@ -261,13 +261,11 @@
);
ConfiguredTarget protoTarget = getConfiguredTarget("//x/foo:nodeps");
ProtoInfo sourcesProvider = protoTarget.get(ProtoInfo.PROVIDER);
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
+ assertThat(sourcesProvider.getTransitiveProtoSourceRoots()).containsExactly("x/foo");
- assertThat(sourcesProvider.getTransitiveProtoSourceRoots())
- .containsExactly(genfiles + "/x/foo/_virtual_imports/nodeps");
- assertThat(
- getGeneratingSpawnAction(getDescriptorOutput("//x/foo:nodeps")).getRemainingArguments())
- .contains("--proto_path=" + genfiles + "/x/foo/_virtual_imports/nodeps");
+ assertThat(getGeneratingSpawnAction(getDescriptorOutput("//x/foo:nodeps"))
+ .getRemainingArguments())
+ .contains("--proto_path=x/foo");
}
@Test
@@ -310,18 +308,11 @@
);
ConfiguredTarget protoTarget = getConfiguredTarget("//x/foo:withdeps");
ProtoInfo sourcesProvider = protoTarget.get(ProtoInfo.PROVIDER);
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
- assertThat(sourcesProvider.getTransitiveProtoSourceRoots())
- .containsExactly(
- genfiles + "/x/foo/_virtual_imports/dep",
- genfiles + "/x/foo/_virtual_imports/withdeps");
+ assertThat(sourcesProvider.getTransitiveProtoSourceRoots()).containsExactly("x/foo");
- assertThat(
- getGeneratingSpawnAction(getDescriptorOutput("//x/foo:withdeps"))
- .getRemainingArguments())
- .containsAtLeast(
- "--proto_path=" + genfiles + "/x/foo/_virtual_imports/withdeps",
- "--proto_path=" + genfiles + "/x/foo/_virtual_imports/dep");
+ assertThat(getGeneratingSpawnAction(getDescriptorOutput("//x/foo:withdeps"))
+ .getRemainingArguments())
+ .contains("--proto_path=x/foo");
}
@Test
@@ -349,42 +340,8 @@
);
ConfiguredTarget protoTarget = getConfiguredTarget("//x/foo:withdeps");
ProtoInfo sourcesProvider = protoTarget.get(ProtoInfo.PROVIDER);
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
assertThat(sourcesProvider.getTransitiveProtoSourceRoots())
- .containsExactly(
- genfiles + "/x/foo/_virtual_imports/withdeps",
- genfiles + "/x/bar/_virtual_imports/dep",
- ".");
- }
-
- @Test
- public void testExternalRepoWithGeneratedProto() throws Exception {
- if (!isThisBazel()) {
- return;
- }
-
- FileSystemUtils.appendIsoLatin1(
- scratch.resolve("WORKSPACE"), "local_repository(name = 'foo', path = '/foo')");
- invalidatePackages();
-
- scratch.file("/foo/WORKSPACE");
- scratch.file(
- "/foo/x/BUILD",
- "proto_library(name='x', srcs=['generated.proto'])",
- "genrule(name='g', srcs=[], outs=['generated.proto'], cmd='')");
-
- scratch.file("a/BUILD", "proto_library(name='a', srcs=['a.proto'], deps=['@foo//x:x'])");
-
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
- ConfiguredTarget a = getConfiguredTarget("//a:a");
- ProtoInfo aInfo = a.get(ProtoInfo.PROVIDER);
- assertThat(aInfo.getTransitiveProtoSourceRoots())
- .containsExactly(".", genfiles + "/external/foo/x/_virtual_imports/x");
-
- ConfiguredTarget x = getConfiguredTarget("@foo//x:x");
- ProtoInfo xInfo = x.get(ProtoInfo.PROVIDER);
- assertThat(xInfo.getTransitiveProtoSourceRoots())
- .containsExactly(genfiles + "/external/foo/x/_virtual_imports/x");
+ .containsExactly("x/foo", "x/bar", ".");
}
@Test
@@ -423,9 +380,7 @@
// exported proto source roots should be the source root of the rule and the direct source roots
// of its exports and nothing else (not the exports of its exports or the deps of its exports
// or the exports of its deps)
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
- assertThat(c.get(ProtoInfo.PROVIDER).getExportedProtoSourceRoots())
- .containsExactly(genfiles + "/a/_virtual_imports/a", genfiles + "/c/_virtual_imports/c");
+ assertThat(c.get(ProtoInfo.PROVIDER).getExportedProtoSourceRoots()).containsExactly("a", "c");
}
@Test
@@ -441,10 +396,7 @@
ConfiguredTarget protoTarget = getConfiguredTarget("//x/foo:banana");
ProtoInfo sourcesProvider = protoTarget.get(ProtoInfo.PROVIDER);
- String genfiles = getTargetConfiguration().getGenfilesFragment().toString();
-
- assertThat(sourcesProvider.getDirectProtoSourceRoot())
- .isEqualTo(genfiles + "/x/foo/_virtual_imports/banana");
+ assertThat(sourcesProvider.getDirectProtoSourceRoot()).isEqualTo("x/foo");
}
@Test
diff --git a/src/test/shell/bazel/bazel_proto_library_test.sh b/src/test/shell/bazel/bazel_proto_library_test.sh
index 9075736..f211683 100755
--- a/src/test/shell/bazel/bazel_proto_library_test.sh
+++ b/src/test/shell/bazel/bazel_proto_library_test.sh
@@ -121,7 +121,6 @@
$proto_library_name(
name = "phonenumber_proto",
srcs = ["phonenumber/phonenumber.proto"],
- $proto_source_root
)
EOF
@@ -382,7 +381,7 @@
function test_proto_source_root() {
write_workspace ""
write_setup "proto_library" "proto_source_root = 'x/person'" ""
- bazel build --verbose_failures //x/person:person_proto > "$TEST_log" || fail "Expected success"
+ bazel build //x/person:person_proto > "$TEST_log" || fail "Expected success"
}
function test_proto_source_root_fails() {
@@ -416,6 +415,13 @@
bazel build //proto_library/src:all >& "$TEST_log" || fail "Expected success"
}
+function test_proto_source_root_glob() {
+ write_workspace ""
+ write_regression_setup
+ bazel build //proto_library/src:all --strict_proto_deps=off >& "$TEST_log" \
+ || fail "Expected success"
+}
+
function test_proto_source_root_multiple_workspaces() {
write_workspace "a/b/"
write_workspace "c/d/"