Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow environment variables in run configurations #5885

Merged
merged 8 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.intellij.openapi.project.Project;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/** Runs a blaze command. */
Expand All @@ -38,19 +39,21 @@ BlazeBuildOutputs run(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context)
BlazeContext context,
Map<String, String> envVars)
throws BuildException;

/**
* Runs a blaze test command, parses the test results into a {@link BlazeTestResults} object using
* the given {@link BuildResultHelper}.
*/
BlazeTestResults runTest(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context)
throws BuildException;
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars)
throws BuildException;

/**
* Runs a blaze query command.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

Expand All @@ -60,13 +61,14 @@ public class CommandLineBlazeCommandRunner implements BlazeCommandRunner {

@Override
public BlazeBuildOutputs run(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context) {
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars) {

BuildResult buildResult =
issueBuild(blazeCommandBuilder, WorkspaceRoot.fromProject(project), context);
issueBuild(blazeCommandBuilder, WorkspaceRoot.fromProject(project), envVars, context);
BuildDepsStatsScope.fromContext(context)
.ifPresent(stats -> stats.setBazelExitCode(buildResult.exitCode));
if (buildResult.status == Status.FATAL_ERROR) {
Expand Down Expand Up @@ -100,9 +102,14 @@ public BlazeTestResults runTest(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context) {
BlazeContext context,
Map<String, String> envVars) {
// For tests, we have to pass the environment variables as `--test_env`, otherwise they don't get forwarded
for (Map.Entry<String, String> env: envVars.entrySet()) {
blazeCommandBuilder.addBlazeFlags(BlazeFlags.TEST_ENV, String.format("%s=%s", env.getKey(), env.getValue()));
}
BuildResult buildResult =
issueBuild(blazeCommandBuilder, WorkspaceRoot.fromProject(project), context);
issueBuild(blazeCommandBuilder, WorkspaceRoot.fromProject(project), envVars, context);
if (buildResult.status == Status.FATAL_ERROR) {
return BlazeTestResults.NO_RESULTS;
}
Expand Down Expand Up @@ -194,11 +201,12 @@ public InputStream runBlazeInfo(
}

private BuildResult issueBuild(
BlazeCommand.Builder blazeCommandBuilder, WorkspaceRoot workspaceRoot, BlazeContext context) {
BlazeCommand.Builder blazeCommandBuilder, WorkspaceRoot workspaceRoot, Map<String, String> envVars, BlazeContext context) {
blazeCommandBuilder.addBlazeFlags(getExtraBuildFlags(blazeCommandBuilder));
int retVal =
ExternalTask.builder(workspaceRoot)
.addBlazeCommand(blazeCommandBuilder.build())
.environmentVars(envVars)
.context(context)
.stderr(
LineProcessingOutputStream.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.bazel.BazelExitCodeException;
import com.google.idea.blaze.base.bazel.BuildSystem;
import com.google.idea.blaze.base.bazel.BuildSystem.BuildInvoker;
Expand Down Expand Up @@ -70,7 +71,7 @@ public AppInspectorInfo buildAppInspector(BlazeContext context, Set<Label> build
.addBlazeFlags(additionalBlazeFlags);

BlazeBuildOutputs outputs =
invoker.getCommandRunner().run(project, builder, buildResultHelper, context);
invoker.getCommandRunner().run(project, builder, buildResultHelper, context, ImmutableMap.of());
BazelExitCodeException.throwIfFailed(builder, outputs.buildResult);

return createAppInspectorInfo(outputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
Expand Down Expand Up @@ -186,7 +187,7 @@ public OutputInfo build(
buildDepsStatsBuilder.ifPresent(
stats -> stats.setBuildFlags(builder.build().toArgumentList()));
BlazeBuildOutputs outputs =
invoker.getCommandRunner().run(project, builder, buildResultHelper, context);
invoker.getCommandRunner().run(project, builder, buildResultHelper, context, ImmutableMap.of());
buildDepsStatsBuilder.ifPresent(
stats -> {
stats.setBuildIds(outputs.getBuildIds());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.bazel.BazelExitCodeException;
import com.google.idea.blaze.base.bazel.BuildSystem;
import com.google.idea.blaze.base.bazel.BuildSystem.BuildInvoker;
Expand Down Expand Up @@ -76,7 +77,7 @@ public RenderJarInfo buildRenderJar(BlazeContext context, Set<Label> buildTarget
.addBlazeFlags("--output_groups=intellij-render-resolve-android");

BlazeBuildOutputs outputs =
invoker.getCommandRunner().run(project, builder, buildResultHelper, context);
invoker.getCommandRunner().run(project, builder, buildResultHelper, context, ImmutableMap.of());
BazelExitCodeException.throwIfFailed(builder, outputs.buildResult);

return createRenderJarInfo(outputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configuration.EnvironmentVariablesData;
import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.RunProfileState;
Expand All @@ -81,6 +82,7 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -192,9 +194,16 @@ public OutputStream getProcessInput() {
private ProcessHandler getScopedProcessHandler(
Project project, BlazeCommand blazeCommand, WorkspaceRoot workspaceRoot)
throws ExecutionException {
GeneralCommandLine commandLine = new GeneralCommandLine(blazeCommand.toList());
EnvironmentVariablesData envVarState = handlerState.getUserEnvVarsState().getData();
commandLine.withEnvironment(envVarState.getEnvs());
commandLine.withParentEnvironmentType(
envVarState.isPassParentEnvs()
? GeneralCommandLine.ParentEnvironmentType.SYSTEM
: GeneralCommandLine.ParentEnvironmentType.NONE);
return new ScopedBlazeProcessHandler(
project,
new GeneralCommandLine(blazeCommand.toList()),
commandLine,
workspaceRoot,
new ScopedBlazeProcessHandler.ScopedProcessHandlerDelegate() {
@Override
Expand Down Expand Up @@ -239,13 +248,14 @@ protected ConsoleView createConsole() {
});
addConsoleFilters(consoleFilters.toArray(new Filter[0]));

@NotNull Map<String, String> envVars = handlerState.getUserEnvVarsState().getData().getEnvs();
ListenableFuture<BlazeBuildOutputs> blazeBuildOutputsListenableFuture =
BlazeExecutor.getInstance()
.submit(
() ->
invoker
.getCommandRunner()
.run(project, blazeCommandBuilder, buildResultHelper, context));
.run(project, blazeCommandBuilder, buildResultHelper, context, envVars));
Futures.addCallback(
blazeBuildOutputsListenableFuture,
new FutureCallback<BlazeBuildOutputs>() {
Expand Down Expand Up @@ -311,32 +321,43 @@ protected ConsoleView createConsole() {
context.addOutputSink(PrintOutput.class, new WritingOutputSink(consoleView));
}
addConsoleFilters(consoleFilters.toArray(new Filter[0]));
return !invoker.getCommandRunner().canUseCli()
? getCommandRunnerProcessHandler(
@NotNull Map<String, String> envVars = handlerState.getUserEnvVarsState().getData().getEnvs();

if (invoker.getCommandRunner().canUseCli()) {
// If we can use the CLI, that means we will run through Bazel (as opposed to a raw process handler)
// When running `bazel test`, bazel will not forward the environment to the tests themselves -- we need to use
// the --test_env flag for that. Therefore, we convert all the env vars to --test_env flags here.
for (Map.Entry<String, String> env: envVars.entrySet()) {
blazeCommandBuilder.addBlazeFlags(BlazeFlags.TEST_ENV, String.format("%s=%s", env.getKey(), env.getValue()));
}

return getScopedProcessHandler(project, blazeCommandBuilder.build(), workspaceRoot);
}
return getCommandRunnerProcessHandlerForTests(
project,
invoker,
buildResultHelper,
blazeCommandBuilder,
testResultFinderStrategy,
context)
: getScopedProcessHandler(project, blazeCommandBuilder.build(), workspaceRoot);
context);
}

private ProcessHandler getCommandRunnerProcessHandler(
private ProcessHandler getCommandRunnerProcessHandlerForTests(
Project project,
BuildInvoker invoker,
BuildResultHelper buildResultHelper,
BlazeCommand.Builder blazeCommandBuilder,
BlazeTestResultFinderStrategy testResultFinderStrategy,
BlazeContext context) {
ProcessHandler processHandler = getGenericProcessHandler();
@NotNull Map<String, String> envVars = handlerState.getUserEnvVarsState().getData().getEnvs();
ListenableFuture<BlazeTestResults> blazeTestResultsFuture =
BlazeExecutor.getInstance()
.submit(
() ->
invoker
.getCommandRunner()
.runTest(project, blazeCommandBuilder, buildResultHelper, context));
.runTest(project, blazeCommandBuilder, buildResultHelper, context, envVars));
Futures.addCallback(
blazeTestResultsFuture,
new FutureCallback<BlazeTestResults>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public interface ScopedProcessHandlerDelegate {
* context.
* @throws ExecutionException
*/

public ScopedBlazeProcessHandler(
Project project,
GeneralCommandLine command,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,20 @@ public class BlazeCommandRunConfigurationCommonState extends RunConfigurationCom
protected final BlazeCommandState command;
protected final RunConfigurationFlagsState blazeFlags;
protected final RunConfigurationFlagsState exeFlags;
protected final EnvironmentVariablesState envVars;
protected final BlazeBinaryState blazeBinary;

public BlazeCommandRunConfigurationCommonState(BuildSystemName buildSystemName) {
command = new BlazeCommandState();
blazeFlags = new RunConfigurationFlagsState(USER_BLAZE_FLAG_TAG, buildSystemName + " flags:");
exeFlags = new RunConfigurationFlagsState(USER_EXE_FLAG_TAG, "Executable flags:");
envVars = new EnvironmentVariablesState();
blazeBinary = new BlazeBinaryState();
}

@Override
protected ImmutableList<RunConfigurationState> initializeStates() {
return ImmutableList.of(command, blazeFlags, exeFlags, blazeBinary);
return ImmutableList.of(command, blazeFlags, exeFlags, envVars, blazeBinary);
}

/** @return The list of blaze flags that the user specified manually. */
Expand All @@ -63,6 +65,11 @@ public RunConfigurationFlagsState getExeFlagsState() {
return exeFlags;
}

/** @return The environment variables the user specified manually. */
public EnvironmentVariablesState getUserEnvVarsState() {
return envVars;
}

public BlazeBinaryState getBlazeBinaryState() {
return blazeBinary;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
*/
package com.google.idea.blaze.base.run.state;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.execution.configuration.EnvironmentVariablesData;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import javax.swing.JComponent;
import org.jdom.Element;
import java.util.Map;

/** State for user-defined environment variables. */
public class EnvironmentVariablesState implements RunConfigurationState {
Expand All @@ -32,10 +35,20 @@ public class EnvironmentVariablesState implements RunConfigurationState {
private EnvironmentVariablesData data =
EnvironmentVariablesData.create(ImmutableMap.of(), /* passParentEnvs= */ true);

public EnvironmentVariablesState() {}

public EnvironmentVariablesData getData() {
return data;
}

public ImmutableList<String> asBlazeTestEnvFlags() {
ImmutableList.Builder<String> flags = ImmutableList.builder();
for (Map.Entry<String, String> env: data.getEnvs().entrySet()) {
flags.add(BlazeFlags.TEST_ENV, String.format("%s=%s", env.getKey(), env.getValue()));
}
return flags.build();
}

@Override
public void readExternal(Element element) throws InvalidDataException {
Element child = element.getChild(ELEMENT_TAG);
Expand All @@ -57,6 +70,10 @@ public RunConfigurationStateEditor getEditor(Project project) {
return new Editor();
}

public void setEnvVars(Map<String, String> vars) {
mai93 marked this conversation as resolved.
Show resolved Hide resolved
data = data.with(vars);
}

private static class Editor implements RunConfigurationStateEditor {
private final EnvironmentVariablesComponent component = new EnvironmentVariablesComponent();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ private static BlazeBuildOutputs runBuildForTargets(
aspectStrategy.addAspectAndOutputGroups(
builder, outputGroups, activeLanguages, onlyDirectDeps);

return invoker.getCommandRunner().run(project, builder, buildResultHelper, context);
return invoker.getCommandRunner().run(project, builder, buildResultHelper, context, ImmutableMap.of());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
Expand Down Expand Up @@ -88,6 +89,7 @@ public void testReadAndWriteMatches() throws Exception {
state.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
state.getExeFlagsState().setRawFlags(ImmutableList.of("--exeFlag1"));
state.getBlazeBinaryState().setBlazeBinary("/usr/bin/blaze");
state.getUserEnvVarsState().setEnvVars(ImmutableMap.of("HELLO", "world"));

Element element = new Element("test");
configuration.writeExternal(element);
Expand All @@ -107,6 +109,7 @@ public void testReadAndWriteMatches() throws Exception {
.inOrder();
assertThat(readState.getExeFlagsState().getRawFlags()).containsExactly("--exeFlag1");
assertThat(readState.getBlazeBinaryState().getBlazeBinary()).isEqualTo("/usr/bin/blaze");
assertThat(readState.getUserEnvVarsState().getData().getEnvs()).isEqualTo(ImmutableMap.of("HELLO", "world"));
}

@Test
Expand Down Expand Up @@ -155,6 +158,8 @@ public void testEditorApplyToAndResetFromMatches() throws ConfigurationException
.isEqualTo(state.getExeFlagsState().getRawFlags());
assertThat(readState.getBlazeBinaryState().getBlazeBinary())
.isEqualTo(state.getBlazeBinaryState().getBlazeBinary());
assertThat(readState.getUserEnvVarsState().getData().getEnvs())
.isEqualTo(state.getUserEnvVarsState().getData().getEnvs());
blorente marked this conversation as resolved.
Show resolved Hide resolved

Disposer.dispose(editor);
}
Expand Down Expand Up @@ -185,6 +190,7 @@ public void testEditorApplyToAndResetFromHandlesNulls() throws ConfigurationExce
readState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
readState.getExeFlagsState().setRawFlags(ImmutableList.of("--exeFlag1"));
readState.getBlazeBinaryState().setBlazeBinary("/usr/bin/blaze");
readState.getUserEnvVarsState().setEnvVars(ImmutableMap.of("HELLO", "world"));

editor.applyEditorTo(readConfiguration);

Expand All @@ -201,6 +207,8 @@ public void testEditorApplyToAndResetFromHandlesNulls() throws ConfigurationExce
.isEqualTo(state.getExeFlagsState().getRawFlags());
assertThat(readState.getBlazeBinaryState().getBlazeBinary())
.isEqualTo(state.getBlazeBinaryState().getBlazeBinary());
assertThat(readState.getUserEnvVarsState().getData().getEnvs())
.isEqualTo(state.getUserEnvVarsState().getData().getEnvs());

Disposer.dispose(editor);
}
Expand Down
Loading