From 73e1366372fb933d67cea09e97c72d9364746545 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Sun, 3 Nov 2024 23:53:27 -0800 Subject: [PATCH] Add --run_env to bazel run This allows passing through env in a similar way to doing `FOO=bar bazel run` but also allows you to put this in a `.bazelrc`, and allows you to bypass any environment filtering done when launching bazel. Closes #24068. PiperOrigin-RevId: 692853922 Change-Id: I802c31f2e0b30a738a41f24395dedbaf0b7caef1 --- .../lib/runtime/commands/RunCommand.java | 22 +++++++++++++ src/test/shell/integration/run_test.sh | 32 +++++++++++++++++++ 2 files changed, 54 insertions(+) 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 c783b2a8bcdcb3..91aa9728bf7c27 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 @@ -92,6 +92,7 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.common.options.Converters; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; @@ -164,6 +165,22 @@ public static class RunOptions extends OptionsBase { "If true, includes paths to replace in ExecRequest to make the resulting paths" + " portable.") public boolean portablePaths; + + @Option( + name = "run_env", + converter = Converters.OptionalAssignmentConverter.class, + allowMultiple = true, + defaultValue = "null", + documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS, + effectTags = {OptionEffectTag.AFFECTS_OUTPUTS}, + help = + "Specifies the set of environment variables available to actions with target" + + " configuration. Variables can be either specified by name, in which case the" + + " value will be taken from the invocation environment, or by the name=value pair" + + " which sets the value independent of the invocation environment. This option can" + + " be used multiple times; for options given for the same variable, the latest" + + " wins, options for different variables accumulate.") + public List> runEnvironment; } private static final String NO_TARGET_MESSAGE = "No targets found to run"; @@ -267,6 +284,11 @@ public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult opti // Only necessary in --batch since the command runs as a subprocess of the java server. finalRunEnv.putAll(env.getClientEnv()); } + + for (Map.Entry entry : runOptions.runEnvironment) { + finalRunEnv.put(entry.getKey(), entry.getValue()); + } + ExecRequest.Builder execRequest; try { boolean shouldRunTarget = runOptions.scriptPath == null && runOptions.runBuiltTarget; diff --git a/src/test/shell/integration/run_test.sh b/src/test/shell/integration/run_test.sh index 67b238113b94f0..0f0fbc055304f2 100755 --- a/src/test/shell/integration/run_test.sh +++ b/src/test/shell/integration/run_test.sh @@ -678,6 +678,38 @@ EOF fi } +function test_run_env() { + local -r pkg="pkg${LINENO}" + mkdir -p "${pkg}" + cat > "$pkg/BUILD" <<'EOF' +sh_binary( + name = "foo", + srcs = ["foo.sh"], + env = { + "FROMBUILD": "1", + "OVERRIDDEN_RUN_ENV": "2", + } +) +EOF + cat > "$pkg/foo.sh" <<'EOF' +#!/bin/bash + +set -euo pipefail + +echo "FROMBUILD: '$FROMBUILD'" +echo "OVERRIDDEN_RUN_ENV: '$OVERRIDDEN_RUN_ENV'" +echo "RUN_ENV_ONLY: '$RUN_ENV_ONLY'" +EOF + + chmod +x "$pkg/foo.sh" + + bazel run --run_env=OVERRIDDEN_RUN_ENV=FOO --run_env=RUN_ENV_ONLY=BAR "//$pkg:foo" >"$TEST_log" || fail "expected run to succeed" + + expect_log "FROMBUILD: '1'" + expect_log "OVERRIDDEN_RUN_ENV: 'FOO'" + expect_log "RUN_ENV_ONLY: 'BAR'" +} + # Usage: assert_starts_with PREFIX STRING_TO_CHECK. # Asserts that `$1` is a prefix of `$2`. function assert_starts_with() {