IDEA-214809 Users which had old Mac OS keymap get switched to new keymap silently

GitOrigin-RevId: 7d416d0fa913fa862bfe0bdd7970f40bfa156f34
This commit is contained in:
Vladimir Krivosheev
2019-05-27 11:05:49 +03:00
committed by intellij-monorepo-bot
parent 0569fb37b8
commit 1f9adbbbbd
2 changed files with 80 additions and 13 deletions
@@ -7,12 +7,10 @@ import com.intellij.openapi.application.ConfigImportHelper
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.diagnostic.logger
import com.intellij.testFramework.ApplicationRule
import com.intellij.testFramework.rules.InMemoryFsRule
import com.intellij.util.io.createDirectories
import com.intellij.util.io.directoryStreamIfExists
import com.intellij.util.io.exists
import com.intellij.util.io.write
import com.intellij.util.io.*
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.description.Description
@@ -23,6 +21,8 @@ import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.attribute.FileTime
private val LOG = logger<ConfigImportHelperTest>()
class ConfigImportHelperTest {
companion object {
@JvmField
@@ -156,6 +156,39 @@ class ConfigImportHelperTest {
10""".trimIndent())
}
@Test
fun `set keymap - old version`() {
doKeyMapTest("2016.4", isMigrationExpected = true)
doKeyMapTest("2019.1", isMigrationExpected = true)
}
@Test
fun `set keymap - new version`() {
doKeyMapTest("2019.2", isMigrationExpected = false)
doKeyMapTest("2019.3", isMigrationExpected = false)
}
private fun doKeyMapTest(version: String, isMigrationExpected: Boolean) {
val oldConfigDir = fsRule.fs.getPath("/data/" + (constructConfigPath(version, true, "DataGrip")))
oldConfigDir.createDirectories()
val newConfigDir = fsRule.fs.getPath("/data/" + (constructConfigPath("2019.2", true, "DataGrip")))
ConfigImportHelper.setKeymapIfNeeded(oldConfigDir, newConfigDir, LOG)
val optionFile = newConfigDir.resolve("options/keymap.xml")
if (isMigrationExpected) {
assertThat(optionFile.readText()).isEqualTo("""
<application>
<component name="KeymapManager">
<active_keymap name="Mac OS X" />
</component>
</application>
""".trimIndent())
}
else {
assertThat(optionFile).doesNotExist()
}
}
private fun writeStorageFile(version: String, lastModified: Long, isMacOs: Boolean) {
val dir = fsRule.fs.getPath("/data/" + (constructConfigPath(version, isMacOs)))
val file = dir.resolve(PathManager.OPTIONS_DIRECTORY + '/' + StoragePathMacros.NON_ROAMABLE_FILE)
@@ -9,7 +9,7 @@ import com.intellij.idea.Main;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -19,6 +19,7 @@ import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.Decompressor;
import com.intellij.util.io.PathKt;
import com.intellij.util.text.VersionComparatorUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +28,7 @@ import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -68,7 +70,7 @@ public class ConfigImportHelper {
System.setProperty(FIRST_SESSION_KEY, Boolean.TRUE.toString());
ConfigImportSettings settings = getConfigImportSettings();
List<Path> guessedOldConfigDirs = findConfigDirectories(newConfigDir, SystemInfo.isMac, true);
List<Path> guessedOldConfigDirs = findConfigDirectories(newConfigDir, SystemInfoRt.isMac, true);
ImportOldConfigsPanel dialog = new ImportOldConfigsPanel(guessedOldConfigDirs, f -> findConfigDirectoryByPath(f));
dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
@@ -142,9 +144,7 @@ public class ConfigImportHelper {
List<Path> homes = new ArrayList<>(2);
homes.add((isMacOs ? newConfigDir : newConfigDir.getParent()).getParent());
String nameWithSelector = StringUtil.notNullize(
PathManager.getPathsSelector(),
(isMacOs ? newConfigDir : newConfigDir.getParent()).getFileName().toString());
String nameWithSelector = StringUtil.notNullize(PathManager.getPathsSelector(), getNameWithVersion(newConfigDir, isMacOs));
String prefix = getPrefixFromSelector(nameWithSelector, isMacOs);
String defaultPrefix = StringUtil.replace(StringUtil.notNullize(
@@ -206,6 +206,11 @@ public class ConfigImportHelper {
return result;
}
@NotNull
private static String getNameWithVersion(@NotNull Path configDir, boolean isMacOs) {
return (isMacOs ? configDir : configDir.getParent()).getFileName().toString();
}
@Nullable
private static String getPrefixFromSelector(@NotNull String nameWithSelector, boolean isMacOs) {
Matcher m = Pattern.compile("\\.?([^\\d]+)\\d+(\\.\\d+)?").matcher(nameWithSelector);
@@ -227,7 +232,7 @@ public class ConfigImportHelper {
return pair(config, null);
}
if (Files.isDirectory(selectedDir.resolve(SystemInfo.isMac ? CONTENTS : BIN))) {
if (Files.isDirectory(selectedDir.resolve(SystemInfoRt.isMac ? CONTENTS : BIN))) {
Path configDir = getSettingsPath(selectedDir, PathManager.PROPERTY_CONFIG_PATH, PathManager::getDefaultConfigPathFor);
if (configDir != null && isConfigDirectory(configDir)) {
return pair(configDir, selectedDir);
@@ -240,7 +245,7 @@ public class ConfigImportHelper {
@Nullable
private static Path getSettingsPath(@NotNull Path ideHome, String propertyName, Function<? super String, String> pathBySelector) {
List<Path> files = new ArrayList<>();
if (SystemInfo.isMac) {
if (SystemInfoRt.isMac) {
files.add(ideHome.resolve(CONTENTS + '/' + BIN + '/' + PathManager.PROPERTIES_FILE_NAME));
files.add(ideHome.resolve(CONTENTS + '/' + PLIST));
}
@@ -370,9 +375,13 @@ public class ConfigImportHelper {
// the filter prevents web token reuse and accidental overwrite of files already created by this instance (port/lock/tokens etc.)
FileUtil.copyDir(oldConfigDir.toFile(), newConfigDir.toFile(), path -> !blockImport(path.toPath(), oldConfigDir, newConfigDir));
if (SystemInfoRt.isMac) {
setKeymapIfNeeded(oldConfigDir, newConfigDir, log);
}
// on macOS, plugins are normally not under the config directory
Path oldPluginsDir = oldConfigDir.resolve(PLUGINS);
if (SystemInfo.isMac && !Files.isDirectory(oldPluginsDir)) {
if (SystemInfoRt.isMac && !Files.isDirectory(oldPluginsDir)) {
oldPluginsDir = null;
if (oldIdeHome != null) {
oldPluginsDir = getSettingsPath(oldIdeHome, PathManager.PROPERTY_PLUGINS_PATH, PathManager::getDefaultPluginPathFor);
@@ -393,7 +402,7 @@ public class ConfigImportHelper {
oldSystemDir = getSettingsPath(oldIdeHome, PathManager.PROPERTY_SYSTEM_PATH, PathManager::getDefaultSystemPathFor);
}
if (oldSystemDir == null) {
String selector = SystemInfo.isMac ? oldConfigDir.getFileName().toString() : StringUtil.trimLeading(oldConfigDir.getParent().getFileName().toString(), '.');
String selector = SystemInfoRt.isMac ? oldConfigDir.getFileName().toString() : StringUtil.trimLeading(oldConfigDir.getParent().getFileName().toString(), '.');
oldSystemDir = Paths.get(PathManager.getDefaultSystemPathFor(selector));
}
Path script = oldSystemDir.resolve(PLUGINS + '/' + StartupActionScriptManager.ACTION_SCRIPT_FILE); // PathManager#getPluginTempPath
@@ -412,6 +421,31 @@ public class ConfigImportHelper {
}
}
public static void setKeymapIfNeeded(@NotNull Path oldConfigDir, @NotNull Path newConfigDir, @NotNull Logger log) {
String nameWithVersion = getNameWithVersion(oldConfigDir, true);
Matcher m = Pattern.compile("\\.?[^\\d]+(\\d+\\.\\d+)?").matcher(nameWithVersion);
if (!m.matches() || VersionComparatorUtil.compare("2019.1", m.group(1)) < 0) {
return;
}
Path keymapOptionFile = newConfigDir.resolve("options/keymap.xml");
if (Files.exists(keymapOptionFile)) {
return;
}
try {
Files.createDirectories(keymapOptionFile.getParent());
Files.write(keymapOptionFile, ("<application>\n" +
" <component name=\"KeymapManager\">\n" +
" <active_keymap name=\"Mac OS X\" />\n" +
" </component>\n" +
"</application>").getBytes(StandardCharsets.UTF_8));
}
catch (IOException e) {
log.error("Cannot set keymap", e);
}
}
/**
* Fix VM options in the custom *.vmoptions file which don't work with the current IDE version.
*/