Support mapping of Paths to URIs
Bazel-created files (like log files of test runs) are internally reported
as Paths. However, this is not always the most useful representation of the
location of that artifact for a consumer of build events. Therefore, support
a mapping of paths to more useful URIs.
--
PiperOrigin-RevId: 144843525
MOS_MIGRATED_REVID=144843525
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index cd84e57..679722b 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -300,6 +300,7 @@
name = "buildeventstream",
srcs = glob(["buildeventstream/*.java"]),
deps = [
+ ":vfs",
"//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
"//src/main/java/com/google/devtools/build/lib/causes",
"//src/main/java/com/google/devtools/build/lib/cmdline",
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutedEvent.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutedEvent.java
index 889165c..aed5bd7 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutedEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutedEvent.java
@@ -19,8 +19,10 @@
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.buildeventstream.PathConverter;
import com.google.devtools.build.lib.causes.ActionFailed;
import com.google.devtools.build.lib.causes.Cause;
+import com.google.devtools.build.lib.vfs.Path;
import java.util.Collection;
/**
@@ -30,11 +32,11 @@
public class ActionExecutedEvent implements BuildEvent {
private final Action action;
private final ActionExecutionException exception;
- private final String stdout;
- private final String stderr;
+ private final Path stdout;
+ private final Path stderr;
public ActionExecutedEvent(Action action,
- ActionExecutionException exception, String stdout, String stderr) {
+ ActionExecutionException exception, Path stdout, Path stderr) {
this.action = action;
this.exception = exception;
this.stdout = stdout;
@@ -51,11 +53,17 @@
}
public String getStdout() {
- return stdout;
+ if (stdout == null) {
+ return null;
+ }
+ return stdout.toString();
}
public String getStderr() {
- return stderr;
+ if (stderr == null) {
+ return null;
+ }
+ return stderr.toString();
}
@Override
@@ -71,7 +79,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
BuildEventStreamProtos.ActionExecuted.Builder actionBuilder =
BuildEventStreamProtos.ActionExecuted.newBuilder().setSuccess(getException() == null);
if (exception.getExitCode() != null) {
@@ -79,11 +87,17 @@
}
if (stdout != null) {
actionBuilder.setStdout(
- BuildEventStreamProtos.File.newBuilder().setName("stdout").setUri(stdout).build());
+ BuildEventStreamProtos.File.newBuilder()
+ .setName("stdout")
+ .setUri(pathConverter.apply(stdout))
+ .build());
}
if (stderr != null) {
actionBuilder.setStdout(
- BuildEventStreamProtos.File.newBuilder().setName("stderr").setUri(stderr).build());
+ BuildEventStreamProtos.File.newBuilder()
+ .setName("stderr")
+ .setUri(pathConverter.apply(stderr))
+ .build());
}
if (action.getOwner() != null) {
actionBuilder.setLabel(action.getOwner().getLabel().toString());
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java
index aa2e9b4..b4cd606 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.buildeventstream.BuildEventWithOrderConstraint;
import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -106,7 +107,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
BuildEventStreamProtos.TargetComplete complete =
BuildEventStreamProtos.TargetComplete.newBuilder().setSuccess(!failed()).build();
return GenericBuildEvent.protoChaining(this).setCompleted(complete).build();
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/AbortedEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/AbortedEvent.java
index 3421b97..fe20063 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/AbortedEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/AbortedEvent.java
@@ -33,7 +33,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
return GenericBuildEvent.protoChaining(this)
.setAborted(
BuildEventStreamProtos.Aborted.newBuilder()
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEvent.java
index 901586f..0a42d83 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEvent.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.buildeventstream;
+
/**
* Interface for objects that can be posted on the public event stream.
*
@@ -27,5 +28,5 @@
* <p>Provide a presentation of the event according to the specified binary format, as appropriate
* protocol buffer.
*/
- BuildEventStreamProtos.BuildEvent asStreamProto();
+ BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter);
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/GenericBuildEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/GenericBuildEvent.java
index 4e4e42a..613ee62 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/GenericBuildEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/GenericBuildEvent.java
@@ -52,7 +52,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
return protoChaining(this).build();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/PathConverter.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/PathConverter.java
new file mode 100644
index 0000000..e230d36
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/PathConverter.java
@@ -0,0 +1,27 @@
+// Copyright 2016 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.buildeventstream;
+
+import com.google.devtools.build.lib.vfs.Path;
+
+/**
+ * Interface for conversion of paths to URIs.
+ */
+public interface PathConverter {
+ /**
+ * Return the URI corresponding to the given path, if the path can be converted to a URI by this
+ * path converter; return {@link null} otherwise.
+ */
+ String apply(Path path);
+}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/ProgressEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/ProgressEvent.java
index c679233..3a3ab15 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/ProgressEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/ProgressEvent.java
@@ -34,7 +34,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
return GenericBuildEvent.protoChaining(this)
.setProgress(BuildEventStreamProtos.Progress.newBuilder().build())
.build();
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD
index 11b6c22..14674f5 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD
@@ -10,6 +10,7 @@
srcs = glob(["*.java"]),
deps = [
"//src/main/java/com/google/devtools/build/lib:buildeventstream",
+ "//src/main/java/com/google/devtools/build/lib:vfs",
"//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
"//src/main/java/com/google/devtools/common/options",
"//third_party:guava",
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransport.java
index c0f341e..1bf30b7 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransport.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransport.java
@@ -16,6 +16,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEvent;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
@@ -29,14 +30,17 @@
*/
public final class BinaryFormatFileTransport implements BuildEventTransport {
private final BufferedOutputStream out;
+ private final PathConverter pathConverter;
- public BinaryFormatFileTransport(String path) throws IOException {
+ public BinaryFormatFileTransport(String path, PathConverter pathConverter)
+ throws IOException {
this.out = new BufferedOutputStream(new FileOutputStream(new File(path)));
+ this.pathConverter = pathConverter;
}
@Override
public synchronized void sendBuildEvent(BuildEvent event) throws IOException {
- event.asStreamProto().writeDelimitedTo(out);
+ event.asStreamProto(pathConverter).writeDelimitedTo(out);
out.flush();
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java
index f456b18..6d8f97f 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import java.io.IOException;
/** Factory used to create a Set of BuildEventTransports from BuildEventStreamOptions. */
@@ -30,8 +31,9 @@
}
@Override
- protected BuildEventTransport create(BuildEventStreamOptions options) throws IOException {
- return new TextFormatFileTransport(options.getBuildEventTextFile());
+ protected BuildEventTransport create(BuildEventStreamOptions options,
+ PathConverter pathConverter) throws IOException {
+ return new TextFormatFileTransport(options.getBuildEventTextFile(), pathConverter);
}
},
@@ -42,8 +44,9 @@
}
@Override
- protected BuildEventTransport create(BuildEventStreamOptions options) throws IOException {
- return new BinaryFormatFileTransport(options.getBuildEventBinaryFile());
+ protected BuildEventTransport create(BuildEventStreamOptions options,
+ PathConverter pathConverter) throws IOException {
+ return new BinaryFormatFileTransport(options.getBuildEventBinaryFile(), pathConverter);
}
};
@@ -55,12 +58,12 @@
* @return A {@link ImmutableSet} of BuildEventTransports. This set may be empty.
* @throws IOException Exception propagated from a {@link BuildEventTransport} creation failure.
*/
- public static ImmutableSet<BuildEventTransport> createFromOptions(BuildEventStreamOptions options)
- throws IOException {
+ public static ImmutableSet<BuildEventTransport> createFromOptions(BuildEventStreamOptions options,
+ PathConverter pathConverter) throws IOException {
Builder<BuildEventTransport> buildEventTransportsBuilder = ImmutableSet.builder();
for (BuildEventTransportFactory transportFactory : BuildEventTransportFactory.values()) {
if (transportFactory.enabled(options)) {
- buildEventTransportsBuilder.add(transportFactory.create(options));
+ buildEventTransportsBuilder.add(transportFactory.create(options, pathConverter));
}
}
return buildEventTransportsBuilder.build();
@@ -70,5 +73,6 @@
protected abstract boolean enabled(BuildEventStreamOptions options);
/** Creates a BuildEventTransport from the specified options. */
- protected abstract BuildEventTransport create(BuildEventStreamOptions options) throws IOException;
+ protected abstract BuildEventTransport create(BuildEventStreamOptions options,
+ PathConverter pathConverter) throws IOException;
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java
index 98b7520..5f8f59d 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransport.java
@@ -16,6 +16,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEvent;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.protobuf.TextFormat;
import java.io.File;
import java.io.FileOutputStream;
@@ -28,15 +29,18 @@
*/
public final class TextFormatFileTransport implements BuildEventTransport {
private FileOutputStream out;
+ private final PathConverter pathConverter;
- public TextFormatFileTransport(String path) throws IOException {
+ public TextFormatFileTransport(String path, PathConverter pathConverter)
+ throws IOException {
this.out = new FileOutputStream(new File(path));
+ this.pathConverter = pathConverter;
}
@Override
public synchronized void sendBuildEvent(BuildEvent event) throws IOException {
if (out != null) {
- String protoTextRepresentation = TextFormat.printToString(event.asStreamProto());
+ String protoTextRepresentation = TextFormat.printToString(event.asStreamProto(pathConverter));
out.write(("event {\n" + protoTextRepresentation + "}\n\n").getBytes(StandardCharsets.UTF_8));
out.flush();
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java
index b819732..3a87b5db 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java
@@ -20,6 +20,7 @@
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.buildeventstream.PathConverter;
import com.google.devtools.build.lib.buildeventstream.ProgressEvent;
import com.google.devtools.build.lib.buildtool.BuildRequest;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
@@ -85,7 +86,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
BuildEventStreamProtos.BuildStarted.Builder started =
BuildEventStreamProtos.BuildStarted.newBuilder()
.setUuid(request.getId().toString())
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java b/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java
index 82fbcf1..94d150f 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/TargetParsingCompleteEvent.java
@@ -22,6 +22,7 @@
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.buildeventstream.PathConverter;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
@@ -122,7 +123,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
return GenericBuildEvent.protoChaining(this)
.setExpanded(BuildEventStreamProtos.PatternExpanded.newBuilder().build())
.build();
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index 434d099..07b4908 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -30,6 +30,7 @@
import com.google.devtools.build.lib.analysis.config.BinTools;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationFactory;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.OutputFilter;
import com.google.devtools.build.lib.flags.CommandNameCache;
@@ -143,6 +144,7 @@
private final String defaultsPackageContent;
private final SubscriberExceptionHandler eventBusExceptionHandler;
private final String productName;
+ private final PathConverter pathToUriConverter;
// Workspace state (currently exactly one workspace per server)
private BlazeWorkspace workspace;
@@ -163,7 +165,8 @@
ProjectFile.Provider projectFileProvider,
InvocationPolicy invocationPolicy,
Iterable<BlazeCommand> commands,
- String productName) {
+ String productName,
+ PathConverter pathToUriConverter) {
// Server state
this.blazeModules = blazeModules;
overrideCommands(commands);
@@ -188,6 +191,7 @@
CommandNameCache.CommandNameCacheInstance.INSTANCE.setCommandNameCache(
new CommandNameCacheImpl(getCommandMap()));
this.productName = productName;
+ this.pathToUriConverter = pathToUriConverter;
}
public void initWorkspace(BlazeDirectories directories, BinTools binTools)
@@ -1067,6 +1071,10 @@
return productName;
}
+ public PathConverter getPathToUriConverter() {
+ return pathToUriConverter;
+ }
+
/**
* A builder for {@link BlazeRuntime} objects. The only required fields are the {@link
* BlazeDirectories}, and the {@link RuleClassProvider} (except for testing). All other fields
@@ -1167,7 +1175,8 @@
projectFileProvider,
serverBuilder.getInvocationPolicy(),
serverBuilder.getCommands(),
- productName);
+ productName,
+ serverBuilder.getPathToUriConverter());
}
public Builder setProductName(String productName) {
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamerModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamerModule.java
index b405c79..47f5b08 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamerModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamerModule.java
@@ -23,9 +23,11 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.devtools.build.lib.buildeventstream.transports.BuildEventStreamOptions;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.ExitCode;
+import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsProvider;
import java.io.IOException;
@@ -62,11 +64,23 @@
Optional<BuildEventStreamer> tryCreateStreamer(
OptionsProvider optionsProvider, ModuleEnvironment moduleEnvironment) {
try {
+ PathConverter pathConverter;
+ if (commandEnvironment == null) {
+ pathConverter = new PathConverter() {
+ @Override
+ public String apply(Path path) {
+ return path.getPathString();
+ }
+ };
+ } else {
+ pathConverter = commandEnvironment.getRuntime().getPathToUriConverter();
+ }
BuildEventStreamOptions besOptions =
checkNotNull(
optionsProvider.getOptions(BuildEventStreamOptions.class),
"Could not get BuildEventStreamOptions");
- ImmutableSet<BuildEventTransport> buildEventTransports = createFromOptions(besOptions);
+ ImmutableSet<BuildEventTransport> buildEventTransports
+ = createFromOptions(besOptions, pathConverter);
if (!buildEventTransports.isEmpty()) {
BuildEventStreamer streamer = new BuildEventStreamer(buildEventTransports);
return Optional.of(streamer);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java b/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java
index dde7062..f8266b41 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java
@@ -17,6 +17,7 @@
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.devtools.build.lib.packages.AttributeContainer;
import com.google.devtools.build.lib.packages.PackageFactory;
import com.google.devtools.build.lib.packages.RuleClass;
@@ -27,6 +28,7 @@
import com.google.devtools.build.lib.runtime.commands.InfoItem;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.util.Preconditions;
+import com.google.devtools.build.lib.vfs.Path;
/**
* Builder class to create a {@link BlazeRuntime} instance. This class is part of the module API,
@@ -43,6 +45,8 @@
ImmutableList.builder();
private final ImmutableList.Builder<PackageFactory.EnvironmentExtension> environmentExtensions =
ImmutableList.builder();
+ private final ImmutableList.Builder<PathConverter> pathToUriConverters
+ = ImmutableList.builder();
@VisibleForTesting
public ServerBuilder() {}
@@ -86,6 +90,27 @@
}
/**
+ * Return the derived total converter from Paths to URIs. It returns the answer of the first
+ * registered converter that can convert the given path, if any. If no registered converter can
+ * convert the given path, the "file" URI scheme is used.
+ */
+ public PathConverter getPathToUriConverter() {
+ final ImmutableList<PathConverter> converters = this.pathToUriConverters.build();
+ return new PathConverter(){
+ @Override
+ public String apply(Path path) {
+ for (PathConverter converter : converters) {
+ String value = converter.apply(path);
+ if (value != null) {
+ return value;
+ }
+ }
+ return "file://" + path.getPathString();
+ }
+ };
+ }
+
+ /**
* Merges the given invocation policy into the per-server invocation policy. While this can accept
* any number of policies, the end result is order-dependent if multiple policies attempt to
* police the same options, so it's probably a good idea to not have too many modules that call
@@ -171,4 +196,12 @@
this.environmentExtensions.add(extension);
return this;
}
+
+ /**
+ * Register a new {@link PathConverter}. Contervers are tried in the order they are registered.
+ */
+ public ServerBuilder addPathToUriConverter(PathConverter converter) {
+ this.pathToUriConverters.add(converter);
+ return this;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/TestSummary.java b/src/main/java/com/google/devtools/build/lib/runtime/TestSummary.java
index 7e84395..394fa9a 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/TestSummary.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/TestSummary.java
@@ -25,6 +25,7 @@
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.buildeventstream.PathConverter;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.util.io.AnsiTerminalPrinter.Mode;
import com.google.devtools.build.lib.vfs.Path;
@@ -463,16 +464,16 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
BuildEventStreamProtos.TestSummary.Builder summaryBuilder =
BuildEventStreamProtos.TestSummary.newBuilder().setTotalRunCount(totalRuns());
for (Path path : getFailedLogs()) {
summaryBuilder.addFailed(
- BuildEventStreamProtos.File.newBuilder().setUri(path.toString()).build());
+ BuildEventStreamProtos.File.newBuilder().setUri(pathConverter.apply(path)).build());
}
for (Path path : getPassedLogs()) {
summaryBuilder.addPassed(
- BuildEventStreamProtos.File.newBuilder().setUri(path.toString()).build());
+ BuildEventStreamProtos.File.newBuilder().setUri(pathConverter.apply(path)).build());
}
return GenericBuildEvent.protoChaining(this).setTestSummary(summaryBuilder.build()).build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
index 3c3b455..bff5be7 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
@@ -1080,14 +1080,14 @@
private void reportActionExecution(Action action,
ActionExecutionException exception, FileOutErr outErr) {
- String stdout = null;
- String stderr = null;
+ Path stdout = null;
+ Path stderr = null;
if (outErr.hasRecordedStdout()) {
- stdout = outErr.getOutputPath().toString();
+ stdout = outErr.getOutputPath();
}
if (outErr.hasRecordedStderr()) {
- stderr = outErr.getErrorPath().toString();
+ stderr = outErr.getErrorPath();
}
postEvent(new ActionExecutedEvent(action, exception, stdout, stderr));
}
diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD
index 6472d8a..896cb5a 100644
--- a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD
@@ -12,6 +12,7 @@
deps = [
"//src/main/java/com/google/devtools/build/lib:buildeventstream",
"//src/main/java/com/google/devtools/build/lib:runtime",
+ "//src/main/java/com/google/devtools/build/lib:vfs",
"//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
"//src/main/java/com/google/devtools/build/lib/buildeventstream/transports",
"//src/test/java/com/google/devtools/build/lib:packages_testutil",
diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java
index e241e84..62ac3da 100644
--- a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java
@@ -22,6 +22,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildStarted;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.Progress;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.TargetComplete;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -45,6 +46,8 @@
@Mock public BuildEvent buildEvent;
+ @Mock public PathConverter pathConverter;
+
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
@@ -63,20 +66,21 @@
BuildEventStreamProtos.BuildEvent.newBuilder()
.setStarted(BuildStarted.newBuilder().setCommand("build"))
.build();
- when(buildEvent.asStreamProto()).thenReturn(started);
- BinaryFormatFileTransport transport = new BinaryFormatFileTransport(output.getAbsolutePath());
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(started);
+ BinaryFormatFileTransport transport =
+ new BinaryFormatFileTransport(output.getAbsolutePath(), pathConverter);
transport.sendBuildEvent(buildEvent);
BuildEventStreamProtos.BuildEvent progress =
BuildEventStreamProtos.BuildEvent.newBuilder().setProgress(Progress.newBuilder()).build();
- when(buildEvent.asStreamProto()).thenReturn(progress);
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(progress);
transport.sendBuildEvent(buildEvent);
BuildEventStreamProtos.BuildEvent completed =
BuildEventStreamProtos.BuildEvent.newBuilder()
.setCompleted(TargetComplete.newBuilder().setSuccess(true))
.build();
- when(buildEvent.asStreamProto()).thenReturn(completed);
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(completed);
transport.sendBuildEvent(buildEvent);
transport.close();
diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java
index 8d4aa52..58bd175 100644
--- a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java
@@ -24,6 +24,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildStarted;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import java.io.File;
import java.io.IOException;
import org.junit.After;
@@ -60,10 +61,12 @@
@Mock public BuildEvent buildEvent;
+ @Mock public PathConverter pathConverter;
+
@Before
public void before() {
MockitoAnnotations.initMocks(this);
- when(buildEvent.asStreamProto()).thenReturn(BUILD_EVENT_AS_PROTO);
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(BUILD_EVENT_AS_PROTO);
}
@After
@@ -77,7 +80,7 @@
when(options.getBuildEventTextFile()).thenReturn(textFile.getAbsolutePath());
when(options.getBuildEventBinaryFile()).thenReturn("");
ImmutableSet<BuildEventTransport> transports =
- BuildEventTransportFactory.createFromOptions(options);
+ BuildEventTransportFactory.createFromOptions(options, pathConverter);
assertThat(FluentIterable.from(transports).transform(GET_CLASS))
.containsExactly(TextFormatFileTransport.class);
sendEventsAndClose(buildEvent, transports);
@@ -90,7 +93,7 @@
when(options.getBuildEventTextFile()).thenReturn("");
when(options.getBuildEventBinaryFile()).thenReturn(binaryFile.getAbsolutePath());
ImmutableSet<BuildEventTransport> transports =
- BuildEventTransportFactory.createFromOptions(options);
+ BuildEventTransportFactory.createFromOptions(options, pathConverter);
assertThat(FluentIterable.from(transports).transform(GET_CLASS))
.containsExactly(BinaryFormatFileTransport.class);
sendEventsAndClose(buildEvent, transports);
@@ -104,7 +107,7 @@
when(options.getBuildEventTextFile()).thenReturn(textFile.getAbsolutePath());
when(options.getBuildEventBinaryFile()).thenReturn(binaryFile.getAbsolutePath());
ImmutableSet<BuildEventTransport> transports =
- BuildEventTransportFactory.createFromOptions(options);
+ BuildEventTransportFactory.createFromOptions(options, pathConverter);
assertThat(FluentIterable.from(transports).transform(GET_CLASS))
.containsExactly(TextFormatFileTransport.class, BinaryFormatFileTransport.class);
sendEventsAndClose(buildEvent, transports);
@@ -116,7 +119,7 @@
public void testCreatesNoTransports() throws IOException {
when(options.getBuildEventTextFile()).thenReturn("");
ImmutableSet<BuildEventTransport> transports =
- BuildEventTransportFactory.createFromOptions(options);
+ BuildEventTransportFactory.createFromOptions(options, pathConverter);
assertThat(transports).isEmpty();
}
diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java
index bb1d1fd..2f36d40 100644
--- a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java
@@ -24,6 +24,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildStarted;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.Progress;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.TargetComplete;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.protobuf.TextFormat;
import java.io.File;
import java.io.IOException;
@@ -47,6 +48,8 @@
@Mock public BuildEvent buildEvent;
+ @Mock public PathConverter pathConverter;
+
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
@@ -65,20 +68,21 @@
BuildEventStreamProtos.BuildEvent.newBuilder()
.setStarted(BuildStarted.newBuilder().setCommand("build"))
.build();
- when(buildEvent.asStreamProto()).thenReturn(started);
- TextFormatFileTransport transport = new TextFormatFileTransport(output.getAbsolutePath());
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(started);
+ TextFormatFileTransport transport =
+ new TextFormatFileTransport(output.getAbsolutePath(), pathConverter);
transport.sendBuildEvent(buildEvent);
BuildEventStreamProtos.BuildEvent progress =
BuildEventStreamProtos.BuildEvent.newBuilder().setProgress(Progress.newBuilder()).build();
- when(buildEvent.asStreamProto()).thenReturn(progress);
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(progress);
transport.sendBuildEvent(buildEvent);
BuildEventStreamProtos.BuildEvent completed =
BuildEventStreamProtos.BuildEvent.newBuilder()
.setCompleted(TargetComplete.newBuilder().setSuccess(true))
.build();
- when(buildEvent.asStreamProto()).thenReturn(completed);
+ when(buildEvent.asStreamProto(pathConverter)).thenReturn(completed);
transport.sendBuildEvent(buildEvent);
transport.close();
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
index a5a79d0..d03ec6b 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
@@ -24,6 +24,7 @@
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
import com.google.devtools.build.lib.buildeventstream.BuildEventWithOrderConstraint;
import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.devtools.build.lib.buildeventstream.ProgressEvent;
import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent;
import java.util.ArrayList;
@@ -84,7 +85,7 @@
}
@Override
- public BuildEventStreamProtos.BuildEvent asStreamProto() {
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter converter) {
return GenericBuildEvent.protoChaining(this).build();
}