From 1f9adbbbbd549a62975a52a1489e684a3a05321b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 May 2019 09:16:29 +0200 Subject: [PATCH] IDEA-214809 Users which had old Mac OS keymap get switched to new keymap silently GitOrigin-RevId: 7d416d0fa913fa862bfe0bdd7970f40bfa156f34 --- .../testSrc/ConfigImportHelperTest.kt | 41 +++++++++++++-- .../application/ConfigImportHelper.java | 52 +++++++++++++++---- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/ConfigImportHelperTest.kt b/platform/configuration-store-impl/testSrc/ConfigImportHelperTest.kt index 5c89d26c9999..9c5b277b4f94 100644 --- a/platform/configuration-store-impl/testSrc/ConfigImportHelperTest.kt +++ b/platform/configuration-store-impl/testSrc/ConfigImportHelperTest.kt @@ -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() + 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(""" + + + + + + """.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) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index 52be8de8fef2..0f7a2293ebf7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -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 guessedOldConfigDirs = findConfigDirectories(newConfigDir, SystemInfo.isMac, true); + List 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 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 pathBySelector) { List 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, ("\n" + + " \n" + + " \n" + + " \n" + + "").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. */