BEP: report visibility errors
On finding a visibility error, report it directly for that target, instead of
relying on the implict "abort" message for targets that have not been built.
Change-Id: I5e45722a1117afca3bc8eeebd05179425b995172
PiperOrigin-RevId: 157592518
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 2afd928..08f2703 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -666,6 +666,7 @@
":bazel-repository",
":build-base",
":build-info",
+ ":buildeventstream",
":collect",
":concurrent",
":events",
@@ -678,6 +679,7 @@
":util",
":vfs",
"//src/main/java/com/google/devtools/build/lib/actions",
+ "//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
"//src/main/java/com/google/devtools/build/lib/query2:query-output",
"//src/main/java/com/google/devtools/build/lib/rules/apple",
"//src/main/java/com/google/devtools/build/lib/rules/apple/cpp",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 2077a887..02fb3e5 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -52,6 +52,7 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.ExtendedEventHandler.Postable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.AspectDescriptor;
import com.google.devtools.build.lib.packages.Attribute;
@@ -1780,6 +1781,10 @@
return mapBuilder.build();
}
+ public void post(Postable event) {
+ reporter.post(event);
+ }
+
public void reportError(Location location, String message) {
reporter.reportError(location, message);
}
@@ -2127,6 +2132,10 @@
env.getEventHandler().handle(Event.error(location, message));
}
+ public void post(Postable event) {
+ env.getEventHandler().post(event);
+ }
+
@Override
public void ruleError(String message) {
reportError(rule.getLocation(), prefixRuleMessage(message));
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java
index 49d8f8f..81c097f 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java
@@ -48,22 +48,28 @@
.getPackageIdentifier()
.equals(AliasProvider.getDependencyLabel(prerequisite).getPackageIdentifier())
&& !context.isVisible(prerequisite)) {
+ String errorMessage;
if (!context.getConfiguration().checkVisibility()) {
- context.ruleWarning(
+ errorMessage =
String.format(
"Target '%s' violates visibility of target "
+ "%s. Continuing because --nocheck_visibility is active",
- rule.getLabel(), AliasProvider.printLabelWithAliasChain(prerequisite)));
+ rule.getLabel(), AliasProvider.printLabelWithAliasChain(prerequisite));
+ context.ruleWarning(errorMessage);
} else {
// Oddly enough, we use reportError rather than ruleError here.
- context.reportError(
- rule.getLocation(),
+ errorMessage =
String.format(
"Target %s is not visible from target '%s'. Check "
+ "the visibility declaration of the former target if you think "
+ "the dependency is legitimate",
- AliasProvider.printLabelWithAliasChain(prerequisite), rule.getLabel()));
+ AliasProvider.printLabelWithAliasChain(prerequisite), rule.getLabel());
+ context.reportError(rule.getLocation(), errorMessage);
}
+ // We can always post the visibility error as, regardless of the value of keep going,
+ // that target will not be built.
+ context.post(
+ new VisibilityErrorEvent(context.getConfiguration(), rule.getLabel(), errorMessage));
}
if (prerequisiteTarget instanceof PackageGroup && !attrName.equals("visibility")) {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java
new file mode 100644
index 0000000..a2c51a8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java
@@ -0,0 +1,61 @@
+// Copyright 2017 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.bazel.rules;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.config.BuildEventWithConfiguration;
+import com.google.devtools.build.lib.buildeventstream.BuildEventConverters;
+import com.google.devtools.build.lib.buildeventstream.BuildEventId;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
+import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
+import com.google.devtools.build.lib.cmdline.Label;
+import java.util.Collection;
+
+/** Class reporting that a configured target will not be built due an error in the analysis phase */
+public class VisibilityErrorEvent implements BuildEventWithConfiguration {
+ BuildConfiguration configuration;
+ Label label;
+ String errorMessage;
+
+ VisibilityErrorEvent(BuildConfiguration configuration, Label label, String errorMessage) {
+ this.configuration = configuration;
+ this.label = label;
+ this.errorMessage = errorMessage;
+ }
+
+ @Override
+ public BuildEventId getEventId() {
+ return BuildEventId.targetCompleted(label, configuration.getEventId());
+ }
+
+ @Override
+ public Collection<BuildEventId> getChildrenEvents() {
+ return ImmutableList.<BuildEventId>of();
+ }
+
+ @Override
+ public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) {
+ return GenericBuildEvent.protoChaining(this)
+ .setAnalysisFailed(
+ BuildEventStreamProtos.AnalysisFailure.newBuilder().setDetails(errorMessage).build())
+ .build();
+ }
+
+ @Override
+ public Collection<BuildConfiguration> getConfigurations() {
+ return ImmutableList.of(configuration);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
index 6d150d5..0dc3d12 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
@@ -204,6 +204,13 @@
string details = 1;
}
+// Payload of an event indicating that an expected event will not come, as
+// something went wrong during analysis. If the analysis of a target failed,
+// the id of the event will be the corresponding TargetCompletedId.
+message AnalysisFailure {
+ string details = 1;
+}
+
// Payload of an event indicating the beginning of a new build. Usually, events
// of those type start a new build-event stream. The target pattern requested
// to be build is contained in one of the announced child events; it is an
@@ -464,6 +471,7 @@
Progress progress = 3;
Aborted aborted = 4;
LoadingFailure loading_failed = 11;
+ AnalysisFailure analysis_failed = 19;
BuildStarted started = 5;
CommandLine command_line = 12;
OptionsParsed options_parsed = 13;