aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Kristina Chodorow <kchodorow@google.com>2017-03-15 17:12:38 +0000
committerGravatar Yun Peng <pcloudy@google.com>2017-03-16 08:35:57 +0000
commitcb81292b95c903bf25c0266f8959cdb978d2b89a (patch)
treed4118dc199b511b766fa59edf2f9b836ba8a30fb /src/main/java/com/google/devtools/build/lib
parentd1f0d6e57286e0987b680aaf956226585ea965a9 (diff)
Print repository context's execute output
RELNOTES: Repository context's execute() function can print stdout/stderr while running. To enable, pass quiet=False. -- PiperOrigin-RevId: 150206218 MOS_MIGRATED_REVID=150206218
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkExecutionResult.java42
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java71
3 files changed, 70 insertions, 44 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 7843d3143a..8be69a6b48 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -715,6 +715,7 @@ java_library(
":util",
"//src/java_tools/singlejar/java/com/google/devtools/build/zip",
"//src/main/java/com/google/devtools/build/lib:build-base",
+ "//src/main/java/com/google/devtools/build/lib:io",
"//src/main/java/com/google/devtools/build/lib:packages-internal",
"//src/main/java/com/google/devtools/build/lib:shell",
"//src/main/java/com/google/devtools/build/lib:skylarkinterface",
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 b049fa8369..1d5f70c088 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
@@ -19,14 +19,17 @@ import com.google.devtools.build.lib.shell.BadExitStatusException;
import com.google.devtools.build.lib.shell.Command;
import com.google.devtools.build.lib.shell.CommandException;
import com.google.devtools.build.lib.shell.CommandResult;
+import com.google.devtools.build.lib.shell.TimeoutKillableObserver;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.util.Preconditions;
+import com.google.devtools.build.lib.util.io.DelegatingOutErr;
+import com.google.devtools.build.lib.util.io.OutErr;
+import com.google.devtools.build.lib.util.io.RecordingOutErr;
import java.io.File;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -55,15 +58,6 @@ final class SkylarkExecutionResult {
this.stderr = stderr;
}
- private SkylarkExecutionResult(CommandResult result) {
- // TODO(dmarting): if a lot of data is sent to stdout, this will use all the memory and
- // Bazel will crash. Maybe we should use custom output streams that throw an appropriate
- // exception when reaching a specific size.
- this.stdout = new String(result.getStdout(), StandardCharsets.UTF_8);
- this.stderr = new String(result.getStderr(), StandardCharsets.UTF_8);
- this.returnCode = result.getTerminationStatus().getExitCode();
- }
-
@SkylarkCallable(
name = "return_code",
structField = true,
@@ -112,6 +106,7 @@ final class SkylarkExecutionResult {
private final Map<String, String> envBuilder = Maps.newLinkedHashMap();
private long timeout = -1;
private boolean executed = false;
+ private boolean quiet;
private Builder(Map<String, String> environment) {
envBuilder.putAll(environment);
@@ -166,6 +161,11 @@ final class SkylarkExecutionResult {
return this;
}
+ Builder setQuiet(boolean quiet) {
+ this.quiet = quiet;
+ return this;
+ }
+
/**
* Execute the command specified by {@link #addArguments(Iterable)}.
*/
@@ -176,16 +176,32 @@ final class SkylarkExecutionResult {
Preconditions.checkNotNull(directory, "Directory must be set before calling execute().");
executed = true;
+ DelegatingOutErr delegator = new DelegatingOutErr();
+ RecordingOutErr recorder = new RecordingOutErr();
+ // TODO(dmarting): if a lot of data is sent to stdout, this will use all the memory and
+ // Bazel will crash. Maybe we should use custom output streams that throw an appropriate
+ // exception when reaching a specific size.
+ delegator.addSink(recorder);
+ if (!quiet) {
+ delegator.addSink(OutErr.create(System.out, System.err));
+ }
try {
String[] argsArray = new String[args.size()];
for (int i = 0; i < args.size(); i++) {
argsArray[i] = args.get(i);
}
Command command = new Command(argsArray, envBuilder, directory);
- CommandResult result = command.execute(new byte[]{}, timeout, false);
- return new SkylarkExecutionResult(result);
+ CommandResult result = command.execute(
+ new byte[]{}, new TimeoutKillableObserver(timeout),
+ delegator.getOutputStream(), delegator.getErrorStream());
+ return new SkylarkExecutionResult(
+ result.getTerminationStatus().getExitCode(),
+ recorder.outAsLatin1(),
+ recorder.errAsLatin1());
} catch (BadExitStatusException e) {
- return new SkylarkExecutionResult(e.getResult());
+ return new SkylarkExecutionResult(
+ e.getResult().getTerminationStatus().getExitCode(), recorder.outAsLatin1(),
+ recorder.errAsLatin1());
} catch (CommandException e) {
// 256 is outside of the standard range for exit code on Unixes. We are not guaranteed that
// on all system it would be outside of the standard range.
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 60f23eb627..deff590162 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
@@ -361,39 +361,47 @@ public class SkylarkRepositoryContext {
}
@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. The <code>environment</code> map can be used to override some environment"
- + " variables to be passed to the process.",
- parameters = {
- @Param(
- name = "arguments",
- type = SkylarkList.class,
- doc =
- "List of arguments, the first element should be the path to the program to "
- + "execute."
- ),
- @Param(
- name = "timeout",
- type = Integer.class,
- named = true,
- defaultValue = "600",
- doc = "maximum duration of the command in seconds (default is 600 seconds)."
- ),
- @Param(
- name = "environment",
- type = SkylarkDict.class,
- defaultValue = "{}",
- named = true,
- doc = "force some environment variables to be set to be passed to the process."
- ),
- }
+ 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. The <code>environment</code> map can be used to override some"
+ + " environment variables to be passed to the process.",
+ parameters = {
+ @Param(
+ name = "arguments",
+ type = SkylarkList.class,
+ doc =
+ "List of arguments, the first element should be the path to the program to "
+ + "execute."
+ ),
+ @Param(
+ name = "timeout",
+ type = Integer.class,
+ named = true,
+ defaultValue = "600",
+ doc = "maximum duration of the command in seconds (default is 600 seconds)."
+ ),
+ @Param(
+ name = "environment",
+ type = SkylarkDict.class,
+ defaultValue = "{}",
+ named = true,
+ doc = "force some environment variables to be set to be passed to the process."
+ ),
+ @Param(
+ name = "quiet",
+ type = Boolean.class,
+ defaultValue = "True",
+ named = true,
+ doc = "If stdout and stderr should be printed to the terminal."
+ ),
+ }
)
public SkylarkExecutionResult execute(
- SkylarkList<Object> arguments, Integer timeout, SkylarkDict<String, String> environment)
+ SkylarkList<Object> arguments, Integer timeout, SkylarkDict<String, String> environment,
+ boolean quiet)
throws EvalException, RepositoryFunctionException {
createDirectory(outputDirectory);
return SkylarkExecutionResult.builder(osObject.getEnvironmentVariables())
@@ -401,6 +409,7 @@ public class SkylarkRepositoryContext {
.setDirectory(outputDirectory.getPathFile())
.addEnvironmentVariables(environment)
.setTimeout(timeout.longValue() * 1000)
+ .setQuiet(quiet)
.execute();
}