diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/BUILD index 0fe03e3831053c..42200666dc38cb 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/BUILD @@ -141,6 +141,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception", "//src/main/java/com/google/devtools/build/lib/util:detailed_exit_code", "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", "//src/main/protobuf:failure_details_java_proto", "//third_party:guava", "//third_party:jsr305", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java b/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java index d19819c9327cb0..3f8faf797b0f06 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.util.AbruptExitException; import com.google.devtools.build.lib.util.DetailedExitCode; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; import java.io.IOException; import javax.annotation.Nullable; @@ -94,11 +95,10 @@ private void initOutputs(CommandEnvironment env) throws IOException { return; } - Path workingDirectory = env.getWorkingDirectory(); Path outputBase = env.getOutputBase(); if (executionOptions.executionLogCompactFile != null) { - outputPath = workingDirectory.getRelative(executionOptions.executionLogCompactFile); + outputPath = getAbsolutePath(executionOptions.executionLogCompactFile, env); try { spawnLogContext = @@ -121,10 +121,10 @@ private void initOutputs(CommandEnvironment env) throws IOException { if (executionOptions.executionLogBinaryFile != null) { encoding = Encoding.BINARY; - outputPath = workingDirectory.getRelative(executionOptions.executionLogBinaryFile); + outputPath = getAbsolutePath(executionOptions.executionLogBinaryFile, env); } else if (executionOptions.executionLogJsonFile != null) { encoding = Encoding.JSON; - outputPath = workingDirectory.getRelative(executionOptions.executionLogJsonFile); + outputPath = getAbsolutePath(executionOptions.executionLogJsonFile, env); } // Use a well-known temporary path to avoid accumulation of potentially large files in /tmp @@ -144,6 +144,25 @@ private void initOutputs(CommandEnvironment env) throws IOException { } } + /** + * If the given path is absolute path, leave it as it is. If the given path is a relative path, it + * is relative to the current working directory. If the given path starts with '%workspace%, it is + * relative to the workspace root, which is the output of `bazel info workspace`. + * + * @return Absolute Path + */ + private Path getAbsolutePath(PathFragment path, CommandEnvironment env) { + String pathString = path.getPathString(); + if (env.getWorkspace() != null) { + pathString = pathString.replace("%workspace%", env.getWorkspace().getPathString()); + } + if (!PathFragment.isAbsolute(pathString)) { + return env.getWorkingDirectory().getRelative(pathString); + } + + return env.getRuntime().getFileSystem().getPath(pathString); + } + @Override public void registerActionContexts( ModuleActionContextRegistry.Builder registryBuilder, diff --git a/src/test/shell/bazel/bazel_execlog_test.sh b/src/test/shell/bazel/bazel_execlog_test.sh index ff435795abca82..660fb1639d2293 100755 --- a/src/test/shell/bazel/bazel_execlog_test.sh +++ b/src/test/shell/bazel/bazel_execlog_test.sh @@ -183,6 +183,26 @@ EOF grep "listedOutputs" output.json || fail "log does not contain listed outputs" } +function test_nested_directory() { + mkdir d + cat > d/BUILD <<'EOF' +genrule( + name = "action", + outs = ["out.txt"], + cmd = "echo hello > $(location out.txt)", + tags = ["no-remote-cache"], +) +EOF + + cd d + bazel build //d:action --execution_log_json_file=%workspace%/output.json 2>&1 >> $TEST_log || fail "could not build" + [[ -e ../output.json ]] || fail "no json log produced" + bazel build //d:action --execution_log_binary_file=%workspace%/output.binary 2>&1 >> $TEST_log || fail "could not build" + [[ -e ../output.binary ]] || fail "no binary log produced" + bazel build //d:action --execution_log_compact_file=%workspace%/output.compact 2>&1 >> $TEST_log || fail "could not build" + [[ -e ../output.compact ]] || fail "no compact log produced" +} + function test_no_remote_cache() { cat > BUILD <<'EOF' genrule(