diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
9 files changed, 87 insertions, 34 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java index 2cea7155d4..037f47b1ad 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java @@ -43,6 +43,19 @@ import javax.annotation.Nullable; */ public class ActionExecutionContext implements Closeable { + /** Enum for --subcommands flag */ + public enum ShowSubcommands { + TRUE(true, false), PRETTY_PRINT(true, true), FALSE(false, false); + + private final boolean shouldShowSubcommands; + private final boolean prettyPrintArgs; + + private ShowSubcommands(boolean shouldShowSubcommands, boolean prettyPrintArgs) { + this.shouldShowSubcommands = shouldShowSubcommands; + this.prettyPrintArgs = prettyPrintArgs; + } + } + private final Executor executor; private final MetadataProvider actionInputFileCache; private final ActionInputPrefetcher actionInputPrefetcher; @@ -236,19 +249,15 @@ public class ActionExecutionContext implements Closeable { } /** - * Whether this Executor reports subcommands. If not, reportSubcommand has no effect. - * This is provided so the caller of reportSubcommand can avoid wastefully constructing the - * subcommand string. - */ - public boolean reportsSubcommands() { - return executor.reportsSubcommands(); - } - - /** * Report a subcommand event to this Executor's Reporter and, if action * logging is enabled, post it on its EventBus. */ - public void reportSubcommand(Spawn spawn) { + public void maybeReportSubcommand(Spawn spawn) { + ShowSubcommands showSubcommands = executor.reportsSubcommands(); + if (!showSubcommands.shouldShowSubcommands) { + return; + } + String reason; ActionOwner owner = spawn.getResourceOwner().getOwner(); if (owner == null) { @@ -257,7 +266,7 @@ public class ActionExecutionContext implements Closeable { reason = Label.print(owner.getLabel()) + " [" + spawn.getResourceOwner().prettyPrint() + "]"; } - String message = Spawns.asShellCommand(spawn, getExecRoot()); + String message = Spawns.asShellCommand(spawn, getExecRoot(), showSubcommands.prettyPrintArgs); getEventHandler().handle(Event.of(EventKind.SUBCOMMAND, null, "# " + reason + "\n" + message)); } diff --git a/src/main/java/com/google/devtools/build/lib/actions/Executor.java b/src/main/java/com/google/devtools/build/lib/actions/Executor.java index a2de3d6a78..2c90014454 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Executor.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Executor.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.actions; import com.google.common.eventbus.EventBus; +import com.google.devtools.build.lib.actions.ActionExecutionContext.ShowSubcommands; import com.google.devtools.build.lib.clock.Clock; import com.google.devtools.build.lib.events.ExtendedEventHandler; import com.google.devtools.build.lib.vfs.FileSystem; @@ -74,7 +75,7 @@ public interface Executor { * This is provided so the caller of reportSubcommand can avoid wastefully constructing the * subcommand string. */ - boolean reportsSubcommands(); + ShowSubcommands reportsSubcommands(); /** * An event listener to report messages to. Errors that signal a action failure should use diff --git a/src/main/java/com/google/devtools/build/lib/actions/Spawns.java b/src/main/java/com/google/devtools/build/lib/actions/Spawns.java index 3174d5b112..0ca66b71c2 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Spawns.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Spawns.java @@ -89,17 +89,29 @@ public final class Spawns { } /** Convert a spawn into a Bourne shell command. */ - public static String asShellCommand(Spawn spawn, Path workingDirectory) { - return asShellCommand(spawn.getArguments(), workingDirectory, spawn.getEnvironment()); + public static String asShellCommand(Spawn spawn, Path workingDirectory, boolean prettyPrintArgs) { + return asShellCommand( + spawn.getArguments(), + workingDirectory, + spawn.getEnvironment(), + prettyPrintArgs); } /** Convert a working dir + environment map + arg list into a Bourne shell command. */ public static String asShellCommand( - Collection<String> arguments, Path workingDirectory, Map<String, String> environment) { + Collection<String> arguments, + Path workingDirectory, + Map<String, String> environment, + boolean prettyPrintArgs) { + // We print this command out in such a way that it can safely be // copied+pasted as a Bourne shell command. This is extremely valuable for // debugging. return CommandFailureUtils.describeCommand( - CommandDescriptionForm.COMPLETE, arguments, environment, workingDirectory.getPathString()); + CommandDescriptionForm.COMPLETE, + prettyPrintArgs, + arguments, + environment, + workingDirectory.getPathString()); } } 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 0930675181..cb40215ad8 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 @@ -70,9 +70,9 @@ public abstract class AbstractSpawnStrategy implements SandboxedSpawnActionConte ActionExecutionContext actionExecutionContext, AtomicReference<Class<? extends SpawnActionContext>> writeOutputFiles) throws ExecException, InterruptedException { - if (actionExecutionContext.reportsSubcommands()) { - actionExecutionContext.reportSubcommand(spawn); - } + + actionExecutionContext.maybeReportSubcommand(spawn); + final Duration timeout = Spawns.getTimeout(spawn); SpawnExecutionContext context = new SpawnExecutionContextImpl(spawn, actionExecutionContext, writeOutputFiles, timeout); diff --git a/src/main/java/com/google/devtools/build/lib/exec/BlazeExecutor.java b/src/main/java/com/google/devtools/build/lib/exec/BlazeExecutor.java index 5786a48bb9..52b0b35b64 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/BlazeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/exec/BlazeExecutor.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.exec; import com.google.common.base.Preconditions; import com.google.common.eventbus.EventBus; import com.google.devtools.build.lib.actions.ActionContext; +import com.google.devtools.build.lib.actions.ActionExecutionContext.ShowSubcommands; import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.actions.ExecutorInitException; import com.google.devtools.build.lib.clock.Clock; @@ -44,7 +45,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public final class BlazeExecutor implements Executor { private final boolean verboseFailures; - private final boolean showSubcommands; + private final ShowSubcommands showSubcommands; private final FileSystem fileSystem; private final Path execRoot; private final Reporter reporter; @@ -123,7 +124,7 @@ public final class BlazeExecutor implements Executor { } @Override - public boolean reportsSubcommands() { + public ShowSubcommands reportsSubcommands() { return showSubcommands; } diff --git a/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java b/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java index 735832bbb1..953639932f 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java +++ b/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java @@ -14,11 +14,13 @@ package com.google.devtools.build.lib.exec; import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.ActionExecutionContext.ShowSubcommands; import com.google.devtools.build.lib.actions.ResourceSet; import com.google.devtools.build.lib.analysis.config.PerLabelOptions; import com.google.devtools.build.lib.util.OptionsUtils; import com.google.devtools.build.lib.util.RegexFilter; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.common.options.BoolOrEnumConverter; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; @@ -71,11 +73,12 @@ public class ExecutionOptions extends OptionsBase { name = "subcommands", abbrev = 's', defaultValue = "false", + converter = ShowSubcommandsConverter.class, documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, effectTags = {OptionEffectTag.UNKNOWN}, help = "Display the subcommands executed during a build." ) - public boolean showSubcommands; + public ShowSubcommands showSubcommands; @Option( name = "check_up_to_date", @@ -363,4 +366,13 @@ public class ExecutionOptions extends OptionsBase { + "This flag may be passed more than once"; } } + + /** Converter for --subcommands */ + public static class ShowSubcommandsConverter extends BoolOrEnumConverter<ShowSubcommands> { + public ShowSubcommandsConverter() { + super( + ShowSubcommands.class, "subcommand option", ShowSubcommands.TRUE, ShowSubcommands.FALSE); + } + } + } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java index 4a5849c61c..67a00b6e58 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java @@ -419,7 +419,10 @@ public class RunCommand implements BlazeCommand { if (runOptions.scriptPath != null) { String unisolatedCommand = CommandFailureUtils.describeCommand( CommandDescriptionForm.COMPLETE_UNISOLATED, - cmdLine, runEnvironment, workingDir.getPathString()); + /* prettyPrintArgs= */ false, + cmdLine, + runEnvironment, + workingDir.getPathString()); if (writeScript(env, shExecutable, runOptions.scriptPath, unisolatedCommand)) { return BlazeCommandResult.exitCode(ExitCode.SUCCESS); } else { 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 dad0d72db6..5317e818c9 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 @@ -139,17 +139,23 @@ public class CommandFailureUtils { * @param form Form of the command to generate; see the documentation of the * {@link CommandDescriptionForm} values. */ - public static String describeCommand(CommandDescriptionForm form, + public static String describeCommand( + CommandDescriptionForm form, + boolean prettyPrintArgs, Collection<String> commandLineElements, - @Nullable Map<String, String> environment, @Nullable String cwd) { + @Nullable Map<String, String> environment, + @Nullable String cwd) { + Preconditions.checkNotNull(form); final int APPROXIMATE_MAXIMUM_MESSAGE_LENGTH = 200; StringBuilder message = new StringBuilder(); int size = commandLineElements.size(); int numberRemaining = size; + if (form == CommandDescriptionForm.COMPLETE) { describeCommandImpl.describeCommandBeginIsolate(message); } + if (form != CommandDescriptionForm.ABBREVIATED) { if (cwd != null) { describeCommandImpl.describeCommandCwd(cwd, message); @@ -195,6 +201,7 @@ public class CommandFailureUtils { } } } + for (String commandElement : commandLineElements) { if (form == CommandDescriptionForm.ABBREVIATED && message.length() + commandElement.length() > APPROXIMATE_MAXIMUM_MESSAGE_LENGTH) { @@ -203,15 +210,17 @@ public class CommandFailureUtils { break; } else { if (numberRemaining < size) { - message.append(' '); + message.append(prettyPrintArgs ? " \\\n " : " "); } describeCommandImpl.describeCommandElement(message, commandElement); numberRemaining--; } } + if (form == CommandDescriptionForm.COMPLETE) { describeCommandImpl.describeCommandEndIsolate(message); } + return message.toString(); } @@ -220,14 +229,17 @@ public class CommandFailureUtils { * Currently this returns a message of the form "error executing command foo * bar baz". */ - public static String describeCommandError(boolean verbose, - Collection<String> commandLineElements, - Map<String, String> env, String cwd) { + public static String describeCommandError( + boolean verbose, + Collection<String> commandLineElements, + Map<String, String> env, + String cwd) { + CommandDescriptionForm form = verbose ? CommandDescriptionForm.COMPLETE : CommandDescriptionForm.ABBREVIATED; return "error executing command " + (verbose ? "\n " : "") - + describeCommand(form, commandLineElements, env, cwd); + + describeCommand(form, /* prettyPrintArgs= */false, commandLineElements, env, cwd); } /** @@ -235,9 +247,12 @@ public class CommandFailureUtils { * Currently this returns a message of the form "foo failed: error executing * command /dir/foo bar baz". */ - public static String describeCommandFailure(boolean verbose, - Collection<String> commandLineElements, - Map<String, String> env, String cwd) { + public static String describeCommandFailure( + boolean verbose, + Collection<String> commandLineElements, + Map<String, String> env, + String cwd) { + String commandName = commandLineElements.iterator().next(); // Extract the part of the command name after the last "/", if any. String shortCommandName = new File(commandName).getName(); diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java index 4211419531..55b0910239 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java @@ -123,6 +123,6 @@ final class WorkerKey { @Override public String toString() { - return Spawns.asShellCommand(args, execRoot, env); + return Spawns.asShellCommand(args, execRoot, env, /* prettyPrintArgs= */ false); } } |