Add DescribableExecutionUnit interface to allow centralizing command failure descriptions.
PiperOrigin-RevId: 398323043
diff --git a/src/main/java/com/google/devtools/build/lib/actions/BUILD b/src/main/java/com/google/devtools/build/lib/actions/BUILD
index b859a4a..6d292df 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/actions/BUILD
@@ -101,6 +101,7 @@
"//src/main/java/com/google/devtools/build/lib/unsafe:string",
"//src/main/java/com/google/devtools/build/lib/util",
"//src/main/java/com/google/devtools/build/lib/util:command",
+ "//src/main/java/com/google/devtools/build/lib/util:describable_execution_unit",
"//src/main/java/com/google/devtools/build/lib/util:detailed_exit_code",
"//src/main/java/com/google/devtools/build/lib/util:exit_code",
"//src/main/java/com/google/devtools/build/lib/util:filetype",
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Spawn.java b/src/main/java/com/google/devtools/build/lib/actions/Spawn.java
index 479a5a8..faa1213 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Spawn.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Spawn.java
@@ -18,16 +18,16 @@
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.util.DescribableExecutionUnit;
import java.util.Collection;
import javax.annotation.Nullable;
/**
- * An object representing a subprocess to be invoked, including its command and
- * arguments, its working directory, its environment, a boolean indicating
- * whether remote execution is appropriate for this command, and if so, the set
- * of files it is expected to read and write.
+ * An object representing a subprocess to be invoked, including its command and arguments, its
+ * working directory, its environment, a boolean indicating whether remote execution is appropriate
+ * for this command, and if so, the set of files it is expected to read and write.
*/
-public interface Spawn {
+public interface Spawn extends DescribableExecutionUnit {
/**
* Out-of-band data for this spawn. This can be used to signal hints (hardware requirements, local
* vs. remote) to the execution subsystem. This data can come from multiple places e.g. tags, hard
diff --git a/src/main/java/com/google/devtools/build/lib/exec/AbstractSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/exec/AbstractSpawnStrategy.java
index a56b839..5b9df88 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/AbstractSpawnStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/AbstractSpawnStrategy.java
@@ -199,12 +199,7 @@
String message =
!Strings.isNullOrEmpty(resultMessage)
? resultMessage
- : CommandFailureUtils.describeCommandFailure(
- verboseFailures,
- spawn.getArguments(),
- spawn.getEnvironment(),
- cwd,
- spawn.getExecutionPlatform());
+ : CommandFailureUtils.describeCommandFailure(verboseFailures, cwd, spawn);
throw new SpawnExecException(message, spawnResult, /*forciblyRunRemotely=*/false);
}
return ImmutableList.of(spawnResult);
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java
index 7272343..1769a81 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/AbstractSandboxSpawnRunner.java
@@ -159,18 +159,10 @@
private String makeFailureMessage(Spawn originalSpawn, SandboxedSpawn sandbox) {
if (sandboxOptions.sandboxDebug) {
return CommandFailureUtils.describeCommandFailure(
- true,
- sandbox.getArguments(),
- sandbox.getEnvironment(),
- sandbox.getSandboxExecRoot().getPathString(),
- null);
+ true, sandbox.getSandboxExecRoot().getPathString(), sandbox);
} else {
return CommandFailureUtils.describeCommandFailure(
- verboseFailures,
- originalSpawn.getArguments(),
- originalSpawn.getEnvironment(),
- sandbox.getSandboxExecRoot().getPathString(),
- originalSpawn.getExecutionPlatform())
+ verboseFailures, sandbox.getSandboxExecRoot().getPathString(), originalSpawn)
+ SANDBOX_DEBUG_SUGGESTION;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/BUILD b/src/main/java/com/google/devtools/build/lib/sandbox/BUILD
index 8701c24..4ceba33 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/BUILD
@@ -41,6 +41,7 @@
"//src/main/java/com/google/devtools/build/lib/util",
"//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
"//src/main/java/com/google/devtools/build/lib/util:command",
+ "//src/main/java/com/google/devtools/build/lib/util:describable_execution_unit",
"//src/main/java/com/google/devtools/build/lib/util:detailed_exit_code",
"//src/main/java/com/google/devtools/build/lib/util:os",
"//src/main/java/com/google/devtools/build/lib/util:process",
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java
index 088924f..8c58418 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxedSpawn.java
@@ -14,8 +14,7 @@
package com.google.devtools.build.lib.sandbox;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.util.DescribableExecutionUnit;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import javax.annotation.Nullable;
@@ -27,16 +26,10 @@
* so that a process running inside the directory can access the files. It also handles moving the
* output files generated by the process out of the directory into a destination directory.
*/
-interface SandboxedSpawn {
+interface SandboxedSpawn extends DescribableExecutionUnit {
/** The path in which to execute the subprocess. */
Path getSandboxExecRoot();
- /** The command-line of the subprocess. */
- ImmutableList<String> getArguments();
-
- /** The environment variables to be set for the subprocess. */
- ImmutableMap<String, String> getEnvironment();
-
/** Returns {@code true}, if the runner should use the Subprocess timeout feature. */
default boolean useSubprocessTimeout() {
return false;
diff --git a/src/main/java/com/google/devtools/build/lib/util/BUILD b/src/main/java/com/google/devtools/build/lib/util/BUILD
index 4d26a69..497deb8 100644
--- a/src/main/java/com/google/devtools/build/lib/util/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/util/BUILD
@@ -77,6 +77,16 @@
)
java_library(
+ name = "describable_execution_unit",
+ srcs = ["DescribableExecutionUnit.java"],
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib/analysis/platform",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ ],
+)
+
+java_library(
name = "command",
srcs = [
"CommandBuilder.java",
@@ -85,6 +95,7 @@
"CommandUtils.java",
],
deps = [
+ ":describable_execution_unit",
":os",
":shell_escaper",
"//src/main/java/com/google/devtools/build/lib/analysis/platform",
diff --git a/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java b/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java
index 00c4244..18e791b 100644
--- a/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java
@@ -280,7 +280,7 @@
boolean verbose,
Collection<String> commandLineElements,
Map<String, String> env,
- String cwd,
+ @Nullable String cwd,
@Nullable PlatformInfo executionPlatform) {
String commandName = commandLineElements.iterator().next();
@@ -290,4 +290,14 @@
+ " failed: "
+ describeCommandError(verbose, commandLineElements, env, cwd, executionPlatform);
}
+
+ public static String describeCommandFailure(
+ boolean verboseFailures, @Nullable String cwd, DescribableExecutionUnit command) {
+ return describeCommandFailure(
+ verboseFailures,
+ command.getArguments(),
+ command.getEnvironment(),
+ cwd,
+ command.getExecutionPlatform());
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/util/DescribableExecutionUnit.java b/src/main/java/com/google/devtools/build/lib/util/DescribableExecutionUnit.java
new file mode 100644
index 0000000..e54cbd1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/util/DescribableExecutionUnit.java
@@ -0,0 +1,40 @@
+// Copyright 2021 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.util;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
+import javax.annotation.Nullable;
+
+/**
+ * Something executable that can be described by {@link CommandFailureUtils#describeCommandFailure}.
+ */
+public interface DescribableExecutionUnit {
+
+ /** Returns the command (the first element) and its arguments. */
+ ImmutableList<String> getArguments();
+
+ /**
+ * Returns the initial environment of the process. If null, the environment is inherited from the
+ * parent process.
+ */
+ ImmutableMap<String, String> getEnvironment();
+
+ /** Returns the execution platform for the command, if any. */
+ @Nullable
+ default PlatformInfo getExecutionPlatform() {
+ return null;
+ }
+}