CR-IC-2619 (custom shell environment loader)

This commit is contained in:
Roman Shevchenko
2013-10-02 19:33:32 +02:00
parent 80da277229
commit f88239e481
3 changed files with 36 additions and 32 deletions
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/python
# Dumps environment variables into specified file.
# Format: zero-separated "name=value" pairs in platform encoding.
import os
import sys
if len(sys.argv) != 2:
raise Error('Exactly one argument expected')
with open(sys.argv[1], 'w') as f:
for key, value in os.environ.items():
f.writelines([key, '=', value, '\0'])
@@ -15,9 +15,8 @@
*/
package com.intellij.util;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.intellij.execution.process.UnixProcessManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.NotNullLazyValue;
@@ -144,9 +143,18 @@ public class EnvironmentUtil {
throw new Exception("shell:" + shell);
}
File reader = FileUtil.findFirstThatExist(
PathManager.getBinPath() + "/printenv.py",
PathManager.getHomePath() + "/community/bin/mac/printenv.py",
PathManager.getHomePath() + "/bin/mac/printenv.py"
);
if (reader == null) {
throw new Exception("bin:" + PathManager.getBinPath());
}
File envFile = FileUtil.createTempFile("intellij-shell-env", null, false);
try {
String[] command = {shell, "-l", "-c", "/usr/bin/printenv > '" + envFile.getAbsolutePath() + "'"};
String[] command = {shell, "-l", "-c", "'" + reader.getAbsolutePath() + "' '" + envFile.getAbsolutePath() + "'"};
LOG.info("loading shell env: " + StringUtil.join(command, " "));
Process process = Runtime.getRuntime().exec(command);
@@ -155,9 +163,9 @@ public class EnvironmentUtil {
int rv = process.waitFor();
processKiller.stopWaiting();
List<String> lines = Files.readLines(envFile, Charsets.UTF_8);
String lines = FileUtil.loadFile(envFile);
if (rv != 0 || lines.isEmpty()) {
throw new Exception("rv:" + rv + " lines:" + lines.size());
throw new Exception("rv:" + rv + " text:" + lines.length());
}
return parseEnv(lines);
}
@@ -166,25 +174,16 @@ public class EnvironmentUtil {
}
}
private static Map<String, String> parseEnv(List<String> lines) throws Exception {
private static Map<String, String> parseEnv(String text) throws Exception {
Set<String> toIgnore = new HashSet<String>(Arrays.asList("_", "PWD", "SHLVL"));
Map<String, String> env = System.getenv();
Map<String, String> newEnv = new HashMap<String, String>();
int size = lines.size();
String prevVarName = null;
String[] lines = text.split("\0");
for (String line : lines) {
int pos = line.indexOf('=');
if (pos <= 0) {
String oldValue = newEnv.get(prevVarName);
if (oldValue == null) {
LOG.warn("malformed:" + line);
}
else {
newEnv.put(prevVarName, oldValue + "\n" + line);
size--;
}
continue;
throw new Exception("malformed:" + line);
}
String name = line.substring(0, pos);
if (!toIgnore.contains(name)) {
@@ -193,12 +192,6 @@ public class EnvironmentUtil {
else if (env.containsKey(name)) {
newEnv.put(name, env.get(name));
}
prevVarName = name;
}
if (newEnv.size() < size - toIgnore.size()) {
// some lines weren't parsed - we're better to fall back to original environment than use possibly incomplete one
throw new Exception("env:" + newEnv.size() + " lines:" + size);
}
LOG.info("shell environment loaded (" + newEnv.size() + " vars)");
@@ -286,7 +279,7 @@ public class EnvironmentUtil {
}
@TestOnly
static Map<String, String> testParser(@NotNull List<String> lines) {
static Map<String, String> testParser(@NotNull String lines) {
try {
return parseEnv(lines);
}
@@ -18,13 +18,9 @@ package com.intellij.util;
import com.intellij.openapi.util.SystemInfo;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
/**
@@ -48,12 +44,13 @@ public class EnvironmentUtilTest {
@Test
public void parse() {
List<String> lines = Arrays.asList("V1=single line", "V2=multiple", "lines", "V3=single line");
Map<String, String> map = EnvironmentUtil.testParser(lines);
assertEquals(3, map.size());
String text = "V1=single line\0V2=multiple\nlines\0V3=single line\0PWD=?\0";
Map<String, String> map = EnvironmentUtil.testParser(text);
assertEquals(4, map.size());
assertEquals("single line", map.get("V1"));
assertEquals("multiple\nlines", map.get("V2"));
assertEquals("single line", map.get("V3"));
assertEquals(System.getenv("PWD"), map.get("PWD"));
}
@Test(timeout = 30000)