diff --git a/modules/products/goland/src/main/java/net/ashald/envfile/products/goland/GolandRunConfigurationExtension.java b/modules/products/goland/src/main/java/net/ashald/envfile/products/goland/GolandRunConfigurationExtension.java index 967beb3..a7b8af0 100644 --- a/modules/products/goland/src/main/java/net/ashald/envfile/products/goland/GolandRunConfigurationExtension.java +++ b/modules/products/goland/src/main/java/net/ashald/envfile/products/goland/GolandRunConfigurationExtension.java @@ -1,10 +1,13 @@ package net.ashald.envfile.products.goland; import com.goide.execution.GoRunConfigurationBase; +import com.goide.execution.GoRunningState; import com.goide.execution.extension.GoRunConfigurationExtension; +import com.goide.util.GoExecutor; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.SettingsEditor; import net.ashald.envfile.platform.EnvFileEnvironmentVariables; import net.ashald.envfile.platform.ui.EnvFileConfigurationEditor; @@ -12,16 +15,20 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.Map; public class GolandRunConfigurationExtension extends GoRunConfigurationExtension { + private static final Logger LOG = Logger.getInstance(GolandRunConfigurationExtension.class); + @Nullable @Override protected String getEditorTitle() { return EnvFileConfigurationEditor.getEditorTitle(); } + // Local runs: GoLand builds a GeneralCommandLine and invokes this legacy hook. @Override protected void patchCommandLine( @NotNull GoRunConfigurationBase goRunConfigurationBase, @@ -48,6 +55,55 @@ protected void patchCommandLine( generalCommandLine.getEnvironment().putAll(newEnv); } + // Target runs (WSL / remote): GoLand bypasses the GeneralCommandLine hook above and goes through the + // Targets API. The executor-level hook below fires for those runs (confirmed for WSL), so we inject the + // EnvFile variables into the GoExecutor here. We add only the delta over the (Windows) parent environment + // to avoid leaking host-only variables (PATH, ProgramFiles, ...) into the target (e.g. Linux under WSL). + @Override + protected void patchExecutor( + @NotNull GoRunConfigurationBase configuration, + @Nullable RunnerSettings runnerSettings, + @NotNull GoExecutor executor, + @NotNull String runnerId, + @NotNull GoRunningState> state, + @NotNull GoRunningState.CommandLineType commandLineType + ) + throws ExecutionException + { + if (commandLineType != GoRunningState.CommandLineType.RUN) { + return; + } + + Map newEnv = new EnvFileEnvironmentVariables( + EnvFileConfigurationEditor.getEnvFileSetting(configuration) + ) + .render( + configuration.getProject(), + configuration.getCustomEnvironment(), + configuration.isPassParentEnvironment() + ); + + if (newEnv == null) { + return; + } + + Map parentEnv = new GeneralCommandLine() + .withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE) + .getParentEnvironment(); + + Map delta = new HashMap<>(); + for (Map.Entry entry : newEnv.entrySet()) { + if (!entry.getValue().equals(parentEnv.get(entry.getKey()))) { + delta.put(entry.getKey(), entry.getValue()); + } + } + + executor.withUserDefinedEnvironment(delta); + + LOG.debug("EnvFile: injected " + delta.size() + + " variable(s) into GoExecutor for target run: " + delta.keySet()); + } + @Override protected void validateConfiguration(@NotNull GoRunConfigurationBase configuration, boolean isExecution) throws Exception { EnvFileConfigurationEditor.validateConfiguration(configuration, isExecution);