From 9105bd038a70cdbbe6131028da5be994573f80d9 Mon Sep 17 00:00:00 2001 From: Nikolay Chashnikov Date: Thu, 19 Jun 2025 12:37:09 +0200 Subject: [PATCH] [remote dev] store the list of plugins disabled in the frontend process in a separate file (IJPL-192491) The frontend process now stores the list of disabled plugins in a disabled_plugins_frontend.txt file instead of disabled_plugins.txt used by a regular IDE. When settings are imported from a previous version, the frontend imports data from disabled_plugins_frontend.txt if it is present, and otherwise imports disabled_plugins.txt to ensure that plugins which were disabled in a regular IDE will be disabled in the frontend process by default. 'installPerProcessInstanceSupportImplementation' calls are moved before 'PerProcessPathCustomization.prepareConfig' to ensure that P3Support is already initialized inside the latter. (cherry picked from commit c60a152321d0d725d6c6f4ac249a00b4cfe9fb09) IJ-CR-166284 GitOrigin-RevId: c0c9ab1a5603d28bfa13f1d4b58d011564ab26aa --- .../startup/multiProcess/ClientP3Support.kt | 9 ++++++++- .../multiProcess/CustomConfigFiles.java | 6 +++++- .../FrontendProcessPathCustomizer.java | 3 ++- .../startup/multiProcess/P3PathCustomizer.kt | 2 +- .../platform-impl/api-dump-experimental.txt | 1 + .../application/ConfigImportHelper.java | 19 +++++++++++++++---- .../openapi/project/impl/P3Support.kt | 15 ++++++++++++++- .../impl/shared/P3SharedConfigFolder.kt | 4 +++- 8 files changed, 49 insertions(+), 10 deletions(-) diff --git a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/ClientP3Support.kt b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/ClientP3Support.kt index 0c8d4754f97d..72b9cb90fcd7 100644 --- a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/ClientP3Support.kt +++ b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/ClientP3Support.kt @@ -2,9 +2,13 @@ package com.intellij.platform.ide.impl.startup.multiProcess import com.intellij.openapi.project.impl.P3Support +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.annotations.VisibleForTesting import java.nio.file.Path -internal class ClientP3Support : P3Support { +@VisibleForTesting +@ApiStatus.Internal +class ClientP3Support : P3Support { override fun isEnabled(): Boolean = true override fun canBeOpenedInThisProcess(projectStoreBaseDir: Path): Boolean = true @@ -12,4 +16,7 @@ internal class ClientP3Support : P3Support { override suspend fun openInChildProcess(projectStoreBaseDir: Path) { throw UnsupportedOperationException() } + + override val disabledPluginsFileName: String + get() = "disabled_plugins_frontend.txt" } \ No newline at end of file diff --git a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/CustomConfigFiles.java b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/CustomConfigFiles.java index fd8a4b715af9..3be13ab521b6 100644 --- a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/CustomConfigFiles.java +++ b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/CustomConfigFiles.java @@ -3,6 +3,7 @@ package com.intellij.platform.ide.impl.startup.multiProcess; import com.intellij.ide.plugins.DisabledPluginsState; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.project.impl.P3SupportKt; import com.intellij.openapi.util.registry.EarlyAccessRegistryManager; import org.jetbrains.annotations.NotNull; @@ -30,7 +31,10 @@ public final class CustomConfigFiles { */ public static void prepareConfigDir(@NotNull Path currentConfigDir, @NotNull Path originalConfigDir) throws IOException { for (String fileName : FILE_NAMES) { - Path sourceFile = originalConfigDir.resolve(fileName); + String sourceFileName = + DisabledPluginsState.DISABLED_PLUGINS_FILENAME.equals(fileName) ? P3SupportKt.processPerProjectSupport().getDisabledPluginsFileName() + : fileName; + Path sourceFile = originalConfigDir.resolve(sourceFileName); Path targetFile = currentConfigDir.resolve(fileName); if (Files.exists(sourceFile)) { Files.createDirectories(targetFile.getParent()); diff --git a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/FrontendProcessPathCustomizer.java b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/FrontendProcessPathCustomizer.java index 5fc080696671..289e198f743e 100644 --- a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/FrontendProcessPathCustomizer.java +++ b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/FrontendProcessPathCustomizer.java @@ -82,6 +82,8 @@ public final class FrontendProcessPathCustomizer implements PathCustomizer { cleanDirectory(newConfig); cleanDirectory(newSystem); + P3SupportInstaller.INSTANCE.installPerProcessInstanceSupportImplementation(new ClientP3Support()); + String originalPluginsPath = PathManager.getPluginsPath(); boolean customizePluginsPath = useCustomPluginsPath(originalPluginsPath); String pluginsPath = customizePluginsPath ? originalPluginsPath + File.separator + "frontend" : originalPluginsPath; @@ -89,7 +91,6 @@ public final class FrontendProcessPathCustomizer implements PathCustomizer { PerProcessPathCustomization.prepareConfig(newConfig, PathManager.getConfigDir(), migratePlugins); Path startupScriptDir = PerProcessPathCustomization.getStartupScriptDir().resolve("frontend"); - P3SupportInstaller.INSTANCE.installPerProcessInstanceSupportImplementation(new ClientP3Support()); enabled = true; return new CustomPaths(newConfig.toString(), newSystem.toString(), pluginsPath, newLog.toString(), startupScriptDir); } diff --git a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/P3PathCustomizer.kt b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/P3PathCustomizer.kt index f41b256226ed..d57d422a60a3 100644 --- a/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/P3PathCustomizer.kt +++ b/platform/bootstrap/src/com/intellij/platform/ide/impl/startup/multiProcess/P3PathCustomizer.kt @@ -38,6 +38,7 @@ class P3PathCustomizer : PathCustomizer { val paths = P3PathsEx(projectStoreBaseDir) Files.createDirectories(paths.getConfigDir()) + P3SupportInstaller.installPerProcessInstanceSupportImplementation(P3SupportImpl(projectStoreBaseDir)) PerProcessPathCustomization.prepareConfig(paths.getConfigDir(), PathManager.getConfigDir(), false) if (ApplicationManagerEx.isInIntegrationTest()) { @@ -51,7 +52,6 @@ class P3PathCustomizer : PathCustomizer { thisLogger().info("current pid: $pid, has been written to pids tile: $file") } - P3SupportInstaller.installPerProcessInstanceSupportImplementation(P3SupportImpl(projectStoreBaseDir)) return PathCustomizer.CustomPaths( paths.getConfigDir().toCanonicalPath(), paths.getSystemDir().toCanonicalPath(), diff --git a/platform/platform-impl/api-dump-experimental.txt b/platform/platform-impl/api-dump-experimental.txt index 47f630f9c7c9..4ee4923c9566 100644 --- a/platform/platform-impl/api-dump-experimental.txt +++ b/platform/platform-impl/api-dump-experimental.txt @@ -235,6 +235,7 @@ a:com.intellij.openapi.fileEditor.ex.IdeDocumentHistory - a:handleUpdate():V *:com.intellij.openapi.project.impl.P3Support - a:canBeOpenedInThisProcess(java.nio.file.Path):Z +- getDisabledPluginsFileName():java.lang.String - a:isEnabled():Z - a:openInChildProcess(java.nio.file.Path,kotlin.coroutines.Continuation):java.lang.Object f:com.intellij.openapi.project.impl.P3SupportKt 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 503a95a033c3..f82fded6de6e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -29,6 +29,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.project.impl.P3SupportKt; import com.intellij.openapi.project.impl.shared.P3DynamicPluginSynchronizerKt; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.updateSettings.impl.PluginDownloader; @@ -176,9 +177,14 @@ public final class ConfigImportHelper { vmOptionsLines = Files.readAllLines(newConfigDir.resolve(VMOptions.getFileName()), VMOptions.getFileCharset()); vmOptionFileChanged = false; } - if (Files.isRegularFile(newConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME))){ - currentlyDisabledPlugins = Files.readAllLines(newConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME)); - } + String disabledPluginsFileName = P3SupportKt.processPerProjectSupport().getDisabledPluginsFileName(); + if (Files.isRegularFile(newConfigDir.resolve(disabledPluginsFileName))) { + currentlyDisabledPlugins = Files.readAllLines(newConfigDir.resolve(disabledPluginsFileName)); + } + else if (!DisabledPluginsState.DISABLED_PLUGINS_FILENAME.equals(disabledPluginsFileName) && + Files.isRegularFile(newConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME))){ + currentlyDisabledPlugins = Files.readAllLines(newConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME)); + } } tempBackup = backupCurrentConfigToTempAndDelete(newConfigDir, log, true, settings); importScenarioStatistics = IMPORT_SETTINGS_ACTION; @@ -255,7 +261,7 @@ public final class ConfigImportHelper { setConfigImportedInThisSession(); if (currentlyDisabledPlugins != null) { try { - Path newDisablePluginsFile = newConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME); + Path newDisablePluginsFile = newConfigDir.resolve(P3SupportKt.processPerProjectSupport().getDisabledPluginsFileName()); Set newDisabledPlugins = new LinkedHashSet<>(); if (Files.isRegularFile(newDisablePluginsFile)) { newDisabledPlugins.addAll(Files.readAllLines(newDisablePluginsFile, CharsetToolkit.getPlatformCharset())); @@ -1037,6 +1043,11 @@ public final class ConfigImportHelper { return FileVisitResult.CONTINUE; } }); + String disabledPluginsFileName = P3SupportKt.processPerProjectSupport().getDisabledPluginsFileName(); + if (!disabledPluginsFileName.equals(DisabledPluginsState.DISABLED_PLUGINS_FILENAME) && + Files.exists(oldConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME)) && !Files.exists(newConfigDir.resolve(disabledPluginsFileName))) { + Files.copy(oldConfigDir.resolve(DisabledPluginsState.DISABLED_PLUGINS_FILENAME), newConfigDir.resolve(disabledPluginsFileName)); + } List actionCommands = loadStartupActionScript(oldConfigDir, oldIdeHome, oldPluginsDir); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/P3Support.kt b/platform/platform-impl/src/com/intellij/openapi/project/impl/P3Support.kt index 72fee0a50e47..852993ef04f5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/P3Support.kt +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/P3Support.kt @@ -1,9 +1,11 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.project.impl +import com.intellij.ide.plugins.DisabledPluginsState import com.intellij.openapi.diagnostic.logger import org.jetbrains.annotations.ApiStatus.Experimental import org.jetbrains.annotations.ApiStatus.Internal +import org.jetbrains.annotations.TestOnly import java.nio.file.Path import java.util.concurrent.atomic.AtomicReference @@ -39,6 +41,12 @@ interface P3Support { * @throws UnsupportedOperationException if the operation is not supported or if the method is called inappropriately. */ suspend fun openInChildProcess(projectStoreBaseDir: Path) + + /** + * Specifies the name of the file in the shared config directory where the list of disabled plugins is stored. + */ + open val disabledPluginsFileName: String + get() = DisabledPluginsState.DISABLED_PLUGINS_FILENAME } @Internal @@ -56,7 +64,7 @@ object DisabledP3Support : P3Support { @Internal @Experimental object P3SupportInstaller { - val atomicSupport = AtomicReference() + internal val atomicSupport = AtomicReference() fun installPerProcessInstanceSupportImplementation(support: P3Support) { if (!atomicSupport.compareAndSet(null, support)) { @@ -67,6 +75,11 @@ object P3SupportInstaller { fun seal() { atomicSupport.compareAndSet(null, DisabledP3Support) } + + @TestOnly + fun installPerProcessInstanceSupportTemporarily(support: P3Support?): P3Support? { + return atomicSupport.getAndSet(support) + } } @Experimental diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/shared/P3SharedConfigFolder.kt b/platform/platform-impl/src/com/intellij/openapi/project/impl/shared/P3SharedConfigFolder.kt index 330e74e0d62c..ca8c867082ae 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/shared/P3SharedConfigFolder.kt +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/shared/P3SharedConfigFolder.kt @@ -97,7 +97,9 @@ private class ProcessPerProjectSharedConfigFolderApplicationInitializedListener private fun syncCustomConfigFile(originalConfigDir: Path, fileName: String) { val sourceFile = PathManager.getConfigDir().resolve(fileName) - val targetFile = originalConfigDir.resolve(fileName) + val targetFileName = fileName.takeIf { it != DisabledPluginsState.DISABLED_PLUGINS_FILENAME } + ?: processPerProjectSupport().disabledPluginsFileName + val targetFile = originalConfigDir.resolve(targetFileName) if (sourceFile.exists()) { SharedConfigFolderUtil.writeToSharedFile(targetFile, sourceFile.readBytes()) }