From 88f141c2776916dce38139499afd85840deaee83 Mon Sep 17 00:00:00 2001 From: Alexander Koshevoy Date: Wed, 22 Oct 2025 00:19:36 +0200 Subject: [PATCH] [jps] IJPL-178632 Transfer specific jdk.table.xml and applicationLibraries.xml applicable to build environment GitOrigin-RevId: 25d4720032f25c39540879659c122eadf3cb1018 --- .../compiler/server/BuildManager.java | 4 +- .../server/OptionsDirectoryProcessor.kt | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 java/compiler/impl/src/com/intellij/compiler/server/OptionsDirectoryProcessor.kt diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 18299ccbe113..67b36341c757 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -152,7 +152,6 @@ import java.util.stream.Collectors; import static com.intellij.ide.impl.ProjectUtil.getProjectForComponent; import static com.intellij.openapi.diagnostic.InMemoryHandler.IN_MEMORY_LOGGER_ADVANCED_SETTINGS_NAME; import static com.intellij.platform.eel.provider.EelNioBridgeServiceKt.asEelPath; -import static com.intellij.platform.eel.provider.utils.EelPathUtils.transferLocalContentToRemote; import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope; public final class BuildManager implements Disposable { @@ -915,8 +914,7 @@ public final class BuildManager implements Disposable { String optionsPath = PathManager.getOptionsPath(); if (canUseEel() && !EelPathUtils.isProjectLocal(project)) { - optionsPath = asEelPath( - transferLocalContentToRemote(Path.of(optionsPath), new EelPathUtils.TransferTarget.Temporary(eelDescriptor))).toString(); + optionsPath = asEelPath(OptionsDirectoryProcessor.transferOptionsToRemote(PathManager.getOptionsDir(), eelDescriptor)).toString(); } else { optionsPath = pathMapper.apply(optionsPath); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/OptionsDirectoryProcessor.kt b/java/compiler/impl/src/com/intellij/compiler/server/OptionsDirectoryProcessor.kt new file mode 100644 index 000000000000..f066cd07ad7a --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/server/OptionsDirectoryProcessor.kt @@ -0,0 +1,61 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +@file:JvmName("OptionsDirectoryProcessor") +@file:OptIn(ExperimentalPathApi::class) + +package com.intellij.compiler.server + +import com.intellij.openapi.util.registry.Registry +import com.intellij.platform.eel.EelDescriptor +import com.intellij.platform.eel.provider.EelProvider.Companion.EP_NAME +import com.intellij.platform.eel.provider.utils.EelPathUtils +import com.intellij.platform.eel.provider.utils.EelPathUtils.transferLocalContentToRemote +import java.nio.file.Files +import java.nio.file.Path +import kotlin.io.path.* + +private val ENVIRONMENT_ASSOCIATED_FILENAMES = setOf("jdk.table.xml", "applicationLibraries.xml") + +internal fun transferOptionsToRemote(optionsDir: Path, eelDescriptor: EelDescriptor): Path { + if (!Registry.`is`("ide.workspace.model.per.environment.model.separation", true)) { + return transferLocalContentToRemote(optionsDir, EelPathUtils.TransferTarget.Temporary(eelDescriptor)) + } + val machine = eelDescriptor.machine + val internalName = EP_NAME.extensionList.firstNotNullOfOrNull { provider -> + provider.getInternalName(machine) + } + if (internalName == null) { + return transferLocalContentToRemote(optionsDir, EelPathUtils.TransferTarget.Temporary(eelDescriptor)) + } + val parentForProcessedOptionsDir = Files.createTempDirectory(internalName) + try { + prepareOptionsDirForEnvironment(optionsDir, parentForProcessedOptionsDir, internalName) + return transferLocalContentToRemote(parentForProcessedOptionsDir, EelPathUtils.TransferTarget.Temporary(eelDescriptor)) + } + finally { + runCatching { parentForProcessedOptionsDir.deleteRecursively() } + } +} + +private fun prepareOptionsDirForEnvironment( + originalOptionsDir: Path, + parentForProcessedOptionsDir: Path, + internalEnvironmentName: String, +) { + val processedOptionsDir = originalOptionsDir.copyToRecursively( + target = parentForProcessedOptionsDir, + followLinks = false, + copyAction = copyAction(skipFiles = ENVIRONMENT_ASSOCIATED_FILENAMES) + ) + for (filename in ENVIRONMENT_ASSOCIATED_FILENAMES) { + val originalFile = originalOptionsDir.resolve(internalEnvironmentName).resolve(filename) + if (Files.exists(originalFile)) { + originalFile.copyTo(processedOptionsDir.resolve(filename), overwrite = true) + } + } +} + +@Suppress("SameParameterValue") +private fun copyAction(skipFiles: Set): CopyActionContext.(source: Path, target: Path) -> CopyActionResult = { src, dst -> + if (src.name !in skipFiles) src.copyToIgnoringExistingDirectory(dst, followLinks = false) + else CopyActionResult.CONTINUE +} \ No newline at end of file