mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Workaround for IDEA-99154 Mac IDE launcher doesn't pass correct environment variables
This commit is contained in:
-21
@@ -9,7 +9,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -67,24 +66,4 @@ public class PathEnvironmentVariableUtil {
|
||||
return StringUtil.join(paths, File.pathSeparator);
|
||||
}
|
||||
|
||||
public static void setPathEnvVarAtProcessLevel() {
|
||||
if (ourFixedMacPathEnvVarValue != null) {
|
||||
UnixProcessManager.setEnv(PATH_ENV_VAR_NAME, ourFixedMacPathEnvVarValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setPathEnvVarInSystemEnv() {
|
||||
try {
|
||||
Map<String, String> unmodifiable = System.getenv();
|
||||
Class<?> cu = unmodifiable.getClass();
|
||||
Field m = cu.getDeclaredField("m");
|
||||
m.setAccessible(true);
|
||||
Map<String, String> map = (Map<String, String>)m.get(unmodifiable);
|
||||
if (ourFixedMacPathEnvVarValue != null) {
|
||||
map.put(PATH_ENV_VAR_NAME, ourFixedMacPathEnvVarValue);
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
@@ -29,6 +30,8 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Elena Shaverdova
|
||||
* @author Nikolay Matveev
|
||||
@@ -94,6 +97,100 @@ public final class ScriptRunnerUtil {
|
||||
return outputBuilder.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static File getShell() {
|
||||
final String shell = System.getenv("SHELL");
|
||||
if (shell != null && (shell.contains("bash") || shell.contains("zsh"))) {
|
||||
File file = new File(shell);
|
||||
if (file.isAbsolute() && file.isFile() && file.canExecute()) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a process with given parameters.
|
||||
* This method tries to work around the following error:
|
||||
* <pre>Cannot run program ...: error=2, No such file or directory</pre>
|
||||
* that occurs when {@code exePath} isn't absolute path, so {@code exePath} is searched in PATH environment variable. <p/>
|
||||
*
|
||||
* There is OSX specific issue that environment variables aren't passed to IDE, if the IDE isn't launched from Terminal.
|
||||
* See <a href="http://youtrack.jetbrains.com/issue/IDEA-99154">IDEA-99154</a> . <p/>
|
||||
*
|
||||
* The workaround for OSX is to execute the command inside shell.
|
||||
* For example if {@code exePath} is {@code "nodemon"}, standby command would be:
|
||||
* <pre>
|
||||
* /bin/bash -c "nodemon"
|
||||
* </pre>
|
||||
*
|
||||
* This method is to be removed as IDEA-99154 is fixed.
|
||||
*
|
||||
* @param exePath path to executable (it must not be absolute)
|
||||
* @param workingDirectory
|
||||
* @param scriptFile
|
||||
* @param parameters
|
||||
* @return
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
@NotNull
|
||||
public static OSProcessHandler executeSafelyOnMac(@NotNull String exePath,
|
||||
@Nullable String workingDirectory,
|
||||
@Nullable VirtualFile scriptFile,
|
||||
@NotNull String[] parameters) throws ExecutionException {
|
||||
if (!SystemInfo.isMac) {
|
||||
return execute(exePath, workingDirectory, scriptFile, parameters);
|
||||
}
|
||||
ExecutionException firstException;
|
||||
try {
|
||||
return execute(exePath, workingDirectory, scriptFile, parameters);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
firstException = e;
|
||||
}
|
||||
File shell = getShell();
|
||||
if (shell == null) {
|
||||
throw firstException;
|
||||
}
|
||||
try {
|
||||
GeneralCommandLine appCommandLine = new GeneralCommandLine();
|
||||
appCommandLine.setExePath(exePath);
|
||||
if (scriptFile != null) {
|
||||
appCommandLine.addParameter(scriptFile.getPresentableUrl());
|
||||
}
|
||||
appCommandLine.addParameters(parameters);
|
||||
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setPassParentEnvs(true);
|
||||
commandLine.setExePath(shell.getAbsolutePath());
|
||||
commandLine.addParameter("-c");
|
||||
commandLine.addParameter(appCommandLine.getCommandLineString());
|
||||
|
||||
if (workingDirectory != null) {
|
||||
commandLine.setWorkDirectory(workingDirectory);
|
||||
}
|
||||
|
||||
LOG.info("Standby command line: " + commandLine.getCommandLineString());
|
||||
|
||||
final OSProcessHandler processHandler = new ColoredProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString(),
|
||||
EncodingManager.getInstance().getDefaultCharset());
|
||||
if (LOG.isDebugEnabled()) {
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
LOG.debug(outputType + ": " + event.getText());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return processHandler;
|
||||
} catch (ExecutionException e) {
|
||||
LOG.info("Standby command failed", e);
|
||||
throw firstException;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OSProcessHandler execute(@NotNull String exePath,
|
||||
@Nullable String workingDirectory,
|
||||
@Nullable VirtualFile scriptFile,
|
||||
|
||||
@@ -88,21 +88,6 @@ public class UnixProcessManager {
|
||||
C_LIB.kill(pid, signal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds or changes an environment variable.
|
||||
* @param name string that contains the name of the environment variable to be added or changed
|
||||
* @param value the value of the environment variable
|
||||
* @param overwrite change the existing entry. If {@code name} has already been defined and exists in the environment variable table,
|
||||
* its value will be updated with {@code value}. If {@code name} was previously undefined, it will be appended to the table.
|
||||
*/
|
||||
public static void setEnv(@NotNull String name, @NotNull String value, boolean overwrite) {
|
||||
if (C_LIB != null) {
|
||||
checkCLib();
|
||||
C_LIB.setenv(name, value, overwrite ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCLib() {
|
||||
if (C_LIB == null) {
|
||||
throw new IllegalStateException("System is not unix(couldn't load c library)");
|
||||
@@ -308,7 +293,6 @@ public class UnixProcessManager {
|
||||
private interface CLib extends Library {
|
||||
int getpid();
|
||||
int kill(int pid, int signal);
|
||||
int setenv(String name, String value, int overwrite);
|
||||
}
|
||||
|
||||
public static class ProcessInfo {
|
||||
|
||||
Reference in New Issue
Block a user