aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2016-06-06 09:49:06 +0000
committerGravatar Yun Peng <pcloudy@google.com>2016-06-06 16:41:40 +0000
commit25a98e16731a2a0cbb59449a6e7d395bd204d04c (patch)
tree8cefb07f14f06fdb837a4f586eeb526ffad50315 /src/main/java/com/google/devtools/build/lib
parent3ae59125807c2ba1a4a238703b0fc9780f96c32e (diff)
repository_ctx.execute: execute from the external repository root and allow to override the environment variables.
Fixes #1130 Fixes #1242 -- MOS_MIGRATED_REVID=124118789
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkExecutionResult.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java48
2 files changed, 77 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkExecutionResult.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkExecutionResult.java
index b4181aa449..ad2e7b60a8 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkExecutionResult.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkExecutionResult.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.bazel.repository.skylark;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.shell.BadExitStatusException;
import com.google.devtools.build.lib.shell.Command;
@@ -23,9 +24,11 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.util.Preconditions;
+import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* A structure callable from Skylark that stores the result of repository_ctx.execute() method. It
@@ -89,9 +92,12 @@ final class SkylarkExecutionResult {
/**
* Returns a Builder that can be used to execute a command and build an execution result.
+ *
+ * @param environment pass through the list of environment variables from the client to be passed
+ * to the execution environment.
*/
- public static Builder builder() {
- return new Builder();
+ public static Builder builder(Map<String, String> environment) {
+ return new Builder(environment);
}
/**
@@ -100,9 +106,15 @@ final class SkylarkExecutionResult {
static final class Builder {
private final List<String> args = new ArrayList<>();
+ private File directory = null;
+ private final ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
private long timeout = -1;
private boolean executed = false;
+ private Builder(Map<String, String> environment) {
+ envBuilder.putAll(environment);
+ }
+
/**
* Adds arguments to the list of arguments to pass to the command. The first argument is
* expected to be the binary to execute. The subsequent arguments are the arguments passed
@@ -125,6 +137,25 @@ final class SkylarkExecutionResult {
}
/**
+ * Set the path to the directory to execute the result process. This method must be called
+ * before calling {@link #execute()}.
+ */
+ Builder setDirectory(File path) throws EvalException {
+ this.directory = path;
+ return this;
+ }
+
+ /**
+ * Add an environment variables to be added to the list of environment variables. For all
+ * key <code>k</code> of <code>variables</code>, the resulting process will have the variable
+ * <code>k=variables.get(k)</code> defined.
+ */
+ Builder addEnvironmentVariables(Map<String, String> variables) {
+ this.envBuilder.putAll(variables);
+ return this;
+ }
+
+ /**
* Sets the timeout, in milliseconds, after which the executed command will be terminated.
*/
Builder setTimeout(long timeout) {
@@ -140,6 +171,7 @@ final class SkylarkExecutionResult {
Preconditions.checkArgument(timeout > 0, "Timeout must be set prior to calling execute().");
Preconditions.checkArgument(!args.isEmpty(), "No command specified.");
Preconditions.checkState(!executed, "Command was already executed, cannot re-use builder.");
+ Preconditions.checkNotNull(directory, "Directory must be set before calling execute().");
executed = true;
try {
@@ -147,7 +179,8 @@ final class SkylarkExecutionResult {
for (int i = 0; i < args.size(); i++) {
argsArray[i] = args.get(i);
}
- CommandResult result = new Command(argsArray).execute(new byte[]{}, timeout, false);
+ Command command = new Command(argsArray, envBuilder.build(), directory);
+ CommandResult result = command.execute(new byte[]{}, timeout, false);
return new SkylarkExecutionResult(result);
} catch (BadExitStatusException e) {
return new SkylarkExecutionResult(e.getResult());
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
index e4dd0293c8..35b4e71556 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
@@ -293,23 +293,57 @@ public class SkylarkRepositoryContext {
return osObject;
}
+ private void createOutputDirectory() throws RepositoryFunctionException {
+ try {
+ if (!outputDirectory.exists()) {
+ makeDirectories(outputDirectory);
+ outputDirectory.createDirectory();
+ }
+ } catch (IOException e) {
+ throw new RepositoryFunctionException(e, Transience.TRANSIENT);
+ }
+ }
+
@SkylarkCallable(
name = "execute",
doc =
"Executes the command given by the list of arguments. The execution time of the command"
+ " is limited by <code>timeout</code> (in seconds, default 600 seconds). This method"
+ " returns an <code>exec_result</code> structure containing the output of the"
- + " command."
+ + " command. The <code>environment</code> map can be used to override some environment"
+ + " variables to be passed to the process."
)
- public SkylarkExecutionResult execute(List<Object> arguments, long timeout) throws EvalException {
- return SkylarkExecutionResult.builder()
- .addArguments(arguments).setTimeout(timeout / 1000).execute();
+ public SkylarkExecutionResult execute(List<Object> arguments, Integer timeout,
+ Map<String, String> environment) throws EvalException, RepositoryFunctionException {
+ createOutputDirectory();
+ return SkylarkExecutionResult.builder(osObject.getEnvironmentVariables())
+ .addArguments(arguments)
+ .setDirectory(outputDirectory.getPathFile())
+ .addEnvironmentVariables(environment)
+ .setTimeout(timeout.longValue() * 1000)
+ .execute();
+ }
+
+ @SkylarkCallable(name = "execute", documented = false)
+ public SkylarkExecutionResult execute(List<Object> arguments)
+ throws EvalException, RepositoryFunctionException {
+ createOutputDirectory();
+ return SkylarkExecutionResult.builder(osObject.getEnvironmentVariables())
+ .setDirectory(outputDirectory.getPathFile())
+ .addArguments(arguments)
+ .setTimeout(600000)
+ .execute();
}
@SkylarkCallable(name = "execute", documented = false)
- public SkylarkExecutionResult execute(List<Object> arguments) throws EvalException {
- return SkylarkExecutionResult.builder()
- .addArguments(arguments).setTimeout(600000).execute();
+ public SkylarkExecutionResult execute(List<Object> arguments, Integer timeout)
+ throws EvalException, RepositoryFunctionException {
+ createOutputDirectory();
+ return SkylarkExecutionResult.builder(osObject.getEnvironmentVariables())
+ .setDirectory(outputDirectory.getPathFile())
+ .addArguments(arguments)
+ .setTimeout(timeout.longValue() * 1000)
+ .execute();
}
@SkylarkCallable(