aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BlazeWorkspace.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java77
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java82
4 files changed, 149 insertions, 40 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
index 06e895b9e7..9363daaef5 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
@@ -279,7 +279,8 @@ public class BlazeCommandDispatcher {
new CommandLineEvent.CanonicalCommandLineEvent(runtime, commandName, options);
// The initCommand call also records the start time for the timestamp granularity monitor.
- CommandEnvironment env = workspace.initCommand(commandAnnotation, options);
+ List<String> commandEnvWarnings = new ArrayList<>();
+ CommandEnvironment env = workspace.initCommand(commandAnnotation, options, commandEnvWarnings);
// Record the command's starting time for use by the commands themselves.
env.recordCommandStartTime(firstContactTime);
@@ -421,6 +422,9 @@ public class BlazeCommandDispatcher {
module.checkEnvironment(env);
}
+ for (String warning : commandEnvWarnings) {
+ reporter.handle(Event.warn(warning));
+ }
if (commonOptions.announceRcOptions) {
if (startupOptionsTaggedWithBazelRc.isPresent()) {
String lastBlazerc = "";
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeWorkspace.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeWorkspace.java
index 2a2d23edda..e682d4ef58 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeWorkspace.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeWorkspace.java
@@ -36,6 +36,7 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.common.options.OptionsProvider;
import java.io.IOException;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
@@ -186,13 +187,24 @@ public final class BlazeWorkspace {
/**
* Initializes a CommandEnvironment to execute a command in this workspace.
*
- * <p>This method should be called from the "main" thread on which the command will execute;
- * that thread will receive interruptions if a module requests an early exit.
+ * <p>This method should be called from the "main" thread on which the command will execute; that
+ * thread will receive interruptions if a module requests an early exit.
+ *
+ * @param warnings a list of warnings to which the CommandEnvironment can add any warning
+ * generated during initialization. This is needed because Blaze's output handling is not yet
+ * fully configured at this point.
*/
- public CommandEnvironment initCommand(Command command, OptionsProvider options) {
- CommandEnvironment env = new CommandEnvironment(
- runtime, this, new EventBus(eventBusExceptionHandler), Thread.currentThread(), command,
- options);
+ public CommandEnvironment initCommand(
+ Command command, OptionsProvider options, List<String> warnings) {
+ CommandEnvironment env =
+ new CommandEnvironment(
+ runtime,
+ this,
+ new EventBus(eventBusExceptionHandler),
+ Thread.currentThread(),
+ command,
+ options,
+ warnings);
skyframeExecutor.setClientEnv(env.getClientEnv());
return env;
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java
index 1976a55823..6e28665024 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java
@@ -117,15 +117,20 @@ public final class CommandEnvironment {
* Creates a new command environment which can be used for executing commands for the given
* runtime in the given workspace, which will publish events on the given eventBus. The
* commandThread passed is interrupted when a module requests an early exit.
+ *
+ * @param warnings will be filled with any warnings from command environment initialization.
*/
CommandEnvironment(
- BlazeRuntime runtime, BlazeWorkspace workspace, EventBus eventBus, Thread commandThread,
- Command command, OptionsProvider options) {
+ BlazeRuntime runtime,
+ BlazeWorkspace workspace,
+ EventBus eventBus,
+ Thread commandThread,
+ Command command,
+ OptionsProvider options,
+ List<String> warnings) {
this.runtime = runtime;
this.workspace = workspace;
this.directories = workspace.getDirectories();
- this.commandId = null; // Will be set once we get the client environment
- this.buildRequestId = null; // Will be set once we get the client environment
this.reporter = new Reporter(eventBus);
this.eventBus = eventBus;
this.commandThread = commandThread;
@@ -146,7 +151,10 @@ public final class CommandEnvironment {
workspace.getSkyframeExecutor().setEventBus(eventBus);
- updateClientEnv(options.getOptions(CommonCommandOptions.class).clientEnv);
+ CommonCommandOptions commandOptions = options.getOptions(CommonCommandOptions.class);
+ this.commandId = commandOptions.invocationId;
+ this.buildRequestId = commandOptions.buildRequestId;
+ updateClientEnv(commandOptions.clientEnv, warnings);
// actionClientEnv contains the environment where values from actionEnvironment are overridden.
actionClientEnv.putAll(clientEnv);
@@ -246,41 +254,43 @@ public final class CommandEnvironment {
return Collections.unmodifiableMap(result);
}
- private UUID getUuidFromEnvOrGenerate(String varName) {
- // Try to set the clientId from the client environment.
- String uuidString = clientEnv.getOrDefault(varName, "");
- if (!uuidString.isEmpty()) {
- try {
- return UUID.fromString(uuidString);
- } catch (IllegalArgumentException e) {
- // String was malformed, so we will resort to generating a random UUID
- }
- }
- // We have been provided with the client environment, but it didn't contain
- // the variable; hence generate our own id.
- return UUID.randomUUID();
- }
-
- private String getFromEnvOrGenerate(String varName) {
- String id = clientEnv.getOrDefault(varName, "");
- if (id.isEmpty()) {
- id = UUID.randomUUID().toString();
- }
- return id;
- }
-
- private void updateClientEnv(List<Map.Entry<String, String>> clientEnvList) {
+ private void updateClientEnv(
+ List<Map.Entry<String, String>> clientEnvList, List<String> warnings) {
Preconditions.checkState(clientEnv.isEmpty());
Collection<Map.Entry<String, String>> env = clientEnvList;
for (Map.Entry<String, String> entry : env) {
clientEnv.put(entry.getKey(), entry.getValue());
}
- if (commandId == null) {
- commandId = getUuidFromEnvOrGenerate("BAZEL_INTERNAL_INVOCATION_ID");
+
+ // TODO(b/67895628): Stop reading ids from the environment after the compatibility window has
+ // passed.
+ if (commandId == null) { // Try to set the clientId from the client environment.
+ String uuidString = clientEnv.getOrDefault("BAZEL_INTERNAL_INVOCATION_ID", "");
+ if (!uuidString.isEmpty()) {
+ try {
+ commandId = UUID.fromString(uuidString);
+ warnings.add(
+ "BAZEL_INTERNAL_INVOCATION_ID is set. This will soon be deprecated in favor of "
+ + "--invocation_id. Please switch to using the flag.");
+ } catch (IllegalArgumentException e) {
+ // String was malformed, so we will resort to generating a random UUID
+ commandId = UUID.randomUUID();
+ }
+ } else {
+ commandId = UUID.randomUUID();
+ }
}
if (buildRequestId == null) {
- buildRequestId = getFromEnvOrGenerate("BAZEL_INTERNAL_BUILD_REQUEST_ID");
+ String uuidString = clientEnv.getOrDefault("BAZEL_INTERNAL_BUILD_REQUEST_ID", "");
+ if (!uuidString.isEmpty()) {
+ buildRequestId = uuidString;
+ warnings.add(
+ "BAZEL_INTERNAL_BUILD_REQUEST_ID is set. This will soon be deprecated in favor of "
+ + "--build_request_id. Please switch to using the flag.");
+ } else {
+ buildRequestId = UUID.randomUUID().toString();
+ }
}
setCommandIdInCrashData();
}
@@ -321,7 +331,8 @@ public final class CommandEnvironment {
/**
* Returns the ID that Blaze uses to identify everything logged from the current build request.
- * TODO(olaola): this should be a UUID, but some existing clients still use arbitrary strings.
+ * TODO(olaola): this should be a prefixed UUID, but some existing clients still use arbitrary
+ * strings, so we accept these when passed by environment variable for compatibility.
*/
public String getBuildRequestId() {
return Preconditions.checkNotNull(buildRequestId);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java b/src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java
index 440271ef86..c602dcd779 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.lib.runtime;
+import static com.google.common.base.Strings.isNullOrEmpty;
+
import com.google.devtools.build.lib.runtime.CommandLineEvent.ToolCommandLineEvent;
import com.google.devtools.build.lib.util.OptionsUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -26,6 +28,7 @@ import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.logging.Level;
/**
@@ -97,6 +100,58 @@ public class CommonCommandOptions extends OptionsBase {
}
}
+ /** Converter for UUID. Accepts values as specified by {@link UUID#fromString(String)}. */
+ public static class UUIDConverter implements Converter<UUID> {
+
+ @Override
+ public UUID convert(String input) throws OptionsParsingException {
+ if (isNullOrEmpty(input)) {
+ return null;
+ }
+ try {
+ return UUID.fromString(input);
+ } catch (IllegalArgumentException e) {
+ throw new OptionsParsingException(
+ String.format("Value '%s' is not a value UUID.", input), e);
+ }
+ }
+
+ @Override
+ public String getTypeDescription() {
+ return "a UUID";
+ }
+ }
+
+ /**
+ * Converter for options (--build_request_id) that accept prefixed UUIDs. Since we do not care
+ * about the structure of this value after validation, we store it as a string.
+ */
+ public static class PrefixedUUIDConverter implements Converter<String> {
+
+ @Override
+ public String convert(String input) throws OptionsParsingException {
+ if (isNullOrEmpty(input)) {
+ return null;
+ }
+ // UUIDs that are accepted by UUID#fromString have 36 characters. Interpret the last 36
+ // characters as an UUID and the rest as a prefix. We do not check anything about the contents
+ // of the prefix.
+ try {
+ int uuidStartIndex = input.length() - 36;
+ UUID.fromString(input.substring(uuidStartIndex));
+ } catch (IllegalArgumentException | IndexOutOfBoundsException e) {
+ throw new OptionsParsingException(
+ String.format("Value '%s' does end in a valid UUID.", input), e);
+ }
+ return input;
+ }
+
+ @Override
+ public String getTypeDescription() {
+ return "An optionally prefixed UUID. The last 36 characters will be verified as a UUID.";
+ }
+ }
+
// To create a new incompatible change, see the javadoc for AllIncompatibleChangesExpansion.
@Option(
name = "all_incompatible_changes",
@@ -321,6 +376,33 @@ public class CommonCommandOptions extends OptionsBase {
)
public String toolTag;
+ // Command ID and build request ID can be set either by flag or environment variable. In most
+ // cases, the internally generated ids should be sufficient, but we allow these to be set
+ // externally if required. Option wins over environment variable, if both are set.
+ // TODO(b/67895628) Stop reading ids from the environment after the compatibility window has
+ // passed.
+ @Option(
+ name = "invocation_id",
+ defaultValue = "",
+ converter = UUIDConverter.class,
+ documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ effectTags = {OptionEffectTag.BAZEL_MONITORING, OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
+ metadataTags = {OptionMetadataTag.HIDDEN},
+ help = "Unique identifier for the command being run."
+ )
+ public UUID invocationId;
+
+ @Option(
+ name = "build_request_id",
+ defaultValue = "",
+ converter = PrefixedUUIDConverter.class,
+ documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ effectTags = {OptionEffectTag.BAZEL_MONITORING, OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION},
+ metadataTags = {OptionMetadataTag.HIDDEN},
+ help = "Unique identifier for the build being run."
+ )
+ public String buildRequestId;
+
@Option(
name = "restart_reason",
defaultValue = "no_restart",