From a69ef6b1de3ed33df76002e86a7086a142dd43ca Mon Sep 17 00:00:00 2001 From: Semyon Kolton Date: Thu, 21 Dec 2017 12:06:03 +0300 Subject: [PATCH] Fix EnvironmentUtil.inlineParentOccurrences() for Windows (ignore case) --- .../com/intellij/util/EnvironmentUtil.java | 31 +++++++++--- .../intellij/util/EnvironmentUtilTest.java | 50 +++++++++++++++++++ 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 55e9a9bd2977..6b7a47bf5a95 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -54,6 +54,13 @@ public class EnvironmentUtil { private static final Future> ourEnvGetter; + /** + * String that is used as a delimiter for referencing parent environment variable. + * "%" on Microsoft Windows; + * "$" on Unix systems + */ + public static final String PARENT_ENV_KEY_DELIMITER = SystemInfo.isWindows ? "%" : "$"; + static { if (SystemInfo.isMac && "unlocked".equals(System.getProperty("__idea.mac.env.lock")) && @@ -374,7 +381,7 @@ public class EnvironmentUtil { } public static void inlineParentOccurrences(@NotNull Map envs) { - inlineParentOccurrences(envs, new HashMap(System.getenv())); + inlineParentOccurrences(envs, getEnvironmentMap()); } public static void inlineParentOccurrences(@NotNull Map envs, @NotNull Map parentEnv) { @@ -382,18 +389,26 @@ public class EnvironmentUtil { String key = entry.getKey(); String value = entry.getValue(); if (value != null) { - String parentVal = parentEnv.get(key); - if (parentVal != null && containsEnvKeySubstitution(key, value)) { - envs.put(key, value.replace("$" + key + "$", parentVal)); + final String parentVal = parentEnv.get(key); + if (parentVal != null) { + StringBuilder newValue = new StringBuilder(); + final String keySubstitution = PARENT_ENV_KEY_DELIMITER + key + PARENT_ENV_KEY_DELIMITER; + for (String part : StringUtil.split(value, File.pathSeparator)) { + if (SystemInfo.isWindows) { + newValue.append(part.equalsIgnoreCase(keySubstitution) ? parentVal : part); + } + else { + newValue.append(part.equals(keySubstitution) ? parentVal : part); + } + newValue.append(File.pathSeparator); + } + newValue.trimToSize(); + envs.put(key, newValue.substring(0, newValue.length() - File.pathSeparator.length())); } } } } - private static boolean containsEnvKeySubstitution(final String envKey, final String val) { - return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1; - } - @TestOnly static Map testLoader() { try { diff --git a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java index 17afc9565792..b2aa057c93b1 100644 --- a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java @@ -3,6 +3,9 @@ package com.intellij.util; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import java.io.File; @@ -46,6 +49,53 @@ public class EnvironmentUtilTest { } } + @Test + public void inlineParentOccurrences() { + Map parentEnv = SystemInfo.isWindows ? + ContainerUtil.newTroveMap(CaseInsensitiveStringHashingStrategy.INSTANCE) : + ContainerUtil.newHashMap(); + parentEnv.put("Foo", "foo/bar"); + parentEnv.put("smth", "another()thing"); + parentEnv.put("tmp", "tempo#rary"); + parentEnv.put("123", "50m37h1ng"); + + Map childEnv = ContainerUtil.newHashMap(); + childEnv.put("no parent", "no parent indeed"); + childEnv.put("Foo", "have parent but no parent reference"); + childEnv.put("smth", "have parent and reference" + File.pathSeparator + + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "smth" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + + File.pathSeparator + "flavor text"); + childEnv.put("TMP", "case sensitive" + + File.pathSeparator + + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "Tmp" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER); + + EnvironmentUtil.inlineParentOccurrences(childEnv, parentEnv); + + assertEnvVariable(childEnv, "no parent", "no parent indeed"); + assertEnvVariable(childEnv, "Foo", "have parent but no parent reference"); + assertEnvVariable(childEnv, "smth", "have parent and reference" + File.pathSeparator + + "another()thing" + + File.pathSeparator + "flavor text"); + if (SystemInfo.isWindows) { + assertEnvVariable(childEnv, "TMP", "case sensitive" + + File.pathSeparator + "tempo#rary"); + } + else { + assertEnvVariable(childEnv, "TMP", "case sensitive" + + File.pathSeparator + + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "Tmp" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER); + } + assertNull(childEnv.get("123")); + } + + private static void assertEnvVariable(@NotNull Map env, + @NotNull String expectedKey, + @NotNull String expectedValue) { + String actualValue = env.get(expectedKey); + assertNotNull(actualValue); + assertEquals(expectedValue, actualValue); + } + @Test(timeout = 30000) public void load() { assumeTrue(SystemInfo.isUnix);