diff --git a/java/idea-ui/testSrc/com/intellij/ui/ProjectWizardJdkComboBoxTest.kt b/java/idea-ui/testSrc/com/intellij/ui/ProjectWizardJdkComboBoxTest.kt index bd9a1306412f..fc44e0446d13 100644 --- a/java/idea-ui/testSrc/com/intellij/ui/ProjectWizardJdkComboBoxTest.kt +++ b/java/idea-ui/testSrc/com/intellij/ui/ProjectWizardJdkComboBoxTest.kt @@ -9,7 +9,6 @@ import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.SimpleJavaSdkType import com.intellij.openapi.util.Disposer -import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.LocalEelDescriptor import com.intellij.platform.eel.provider.utils.EelPathUtils @@ -25,7 +24,7 @@ import java.nio.file.Path @TestApplication class ProjectWizardJdkComboBoxTest { - val eelFixture = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) + val eelFixture = eelFixture(EelPath.OS.UNIX) @Test fun `changing eel changes available sdks`(@TestDisposable disposable: Disposable): Unit = timeoutRunBlocking { diff --git a/platform/eel-impl/src/com/intellij/platform/eel/impl/fs/LocalEelFileSystemApi.kt b/platform/eel-impl/src/com/intellij/platform/eel/impl/fs/LocalEelFileSystemApi.kt index 7963b71e8109..19a268d1a9c0 100644 --- a/platform/eel-impl/src/com/intellij/platform/eel/impl/fs/LocalEelFileSystemApi.kt +++ b/platform/eel-impl/src/com/intellij/platform/eel/impl/fs/LocalEelFileSystemApi.kt @@ -27,6 +27,8 @@ import kotlin.io.path.fileStore import kotlin.streams.asSequence abstract class NioBasedEelFileSystemApi(@VisibleForTesting val fs: FileSystem) : EelFileSystemApi { + abstract val pathOs: EelPath.OS + protected fun EelPath.toNioPath(): Path = fs.getPath(toString()) @@ -335,6 +337,7 @@ abstract class PosixNioBasedEelFileSystemApi( fs: FileSystem, override val user: EelUserPosixInfo, ) : NioBasedEelFileSystemApi(fs), LocalEelFileSystemPosixApi { + override val pathOs: EelPath.OS = EelPath.OS.UNIX override suspend fun createDirectory( path: EelPath, @@ -404,6 +407,7 @@ abstract class WindowsNioBasedEelFileSystemApi( fs: FileSystem, override val user: EelUserWindowsInfo, ) : NioBasedEelFileSystemApi(fs), LocalEelFileSystemWindowsApi { + override val pathOs: EelPath.OS = EelPath.OS.WINDOWS override suspend fun getRootDirectories(): Collection = FileSystems.getDefault().rootDirectories.map { path -> diff --git a/platform/eel-impl/src/com/intellij/platform/eel/impl/local/LocalEelApiImpl.kt b/platform/eel-impl/src/com/intellij/platform/eel/impl/local/LocalEelApiImpl.kt index 26df3598bb47..e30a773d39fd 100644 --- a/platform/eel-impl/src/com/intellij/platform/eel/impl/local/LocalEelApiImpl.kt +++ b/platform/eel-impl/src/com/intellij/platform/eel/impl/local/LocalEelApiImpl.kt @@ -62,11 +62,19 @@ class LocalPosixEelApiImpl(private val nioFs: FileSystem = FileSystems.getDefaul check(SystemInfo.isUnix) } - override val platform: EelPlatform.Posix = when { - SystemInfo.isMac -> EelPlatform.Darwin(CpuArch.CURRENT.toEelArch()) - SystemInfo.isFreeBSD -> EelPlatform.FreeBSD(CpuArch.CURRENT.toEelArch()) - else -> EelPlatform.Linux(CpuArch.CURRENT.toEelArch()) - } + override val platform: EelPlatform.Posix + get() { + val arch = CpuArch.CURRENT.toEelArch() + return when { + SystemInfo.isMac -> EelPlatform.Darwin(arch) + SystemInfo.isLinux -> EelPlatform.Linux(arch) + SystemInfo.isFreeBSD -> EelPlatform.FreeBSD(arch) + else -> { + LOG.info("Eel is not supported on current platform") + EelPlatform.Linux(arch) + } + } + } override val tunnels: EelTunnelsPosixApi get() = EelLocalTunnelsApiImpl override val descriptor: EelDescriptor get() = LocalEelDescriptor @@ -80,6 +88,7 @@ class LocalPosixEelApiImpl(private val nioFs: FileSystem = FileSystems.getDefaul } override val fs: LocalEelFileSystemPosixApi = object : PosixNioBasedEelFileSystemApi(nioFs, userInfo) { + override val pathOs: EelPath.OS = EelPath.OS.UNIX override val descriptor: EelDescriptor get() = LocalEelDescriptor override suspend fun createTemporaryDirectory( diff --git a/platform/eel/api-dump-experimental.txt b/platform/eel/api-dump-experimental.txt index dcbaaee08335..283345a06c45 100644 --- a/platform/eel/api-dump-experimental.txt +++ b/platform/eel/api-dump-experimental.txt @@ -393,13 +393,6 @@ f:com.intellij.platform.eel.channels.EelSendChannelKt - a:toString():java.lang.String *f:com.intellij.platform.eel.path.EelPath$Companion - f:parse(java.lang.String,com.intellij.platform.eel.EelDescriptor):com.intellij.platform.eel.path.EelPath -*e:com.intellij.platform.eel.path.EelPath$OS -- java.lang.Enum -- sf:UNIX:com.intellij.platform.eel.path.EelPath$OS -- sf:WINDOWS:com.intellij.platform.eel.path.EelPath$OS -- s:getEntries():kotlin.enums.EnumEntries -- s:valueOf(java.lang.String):com.intellij.platform.eel.path.EelPath$OS -- s:values():com.intellij.platform.eel.path.EelPath$OS[] *f:com.intellij.platform.eel.path.EelPathException - java.lang.RuntimeException - (java.lang.String,java.lang.String):V diff --git a/platform/eel/src/com/intellij/platform/eel/EelApi.kt b/platform/eel/src/com/intellij/platform/eel/EelApi.kt index ab61c018c542..b9e9bd2d19f5 100644 --- a/platform/eel/src/com/intellij/platform/eel/EelApi.kt +++ b/platform/eel/src/com/intellij/platform/eel/EelApi.kt @@ -18,7 +18,6 @@ interface EelApi { @get:ApiStatus.Experimental val descriptor: EelDescriptor - // TODO: should it be extension property? val platform: EelPlatform /** Docs: [EelFileSystemApi] */ diff --git a/platform/eel/src/com/intellij/platform/eel/EelDescriptor.kt b/platform/eel/src/com/intellij/platform/eel/EelDescriptor.kt index 118878f16806..c0a62f32c521 100644 --- a/platform/eel/src/com/intellij/platform/eel/EelDescriptor.kt +++ b/platform/eel/src/com/intellij/platform/eel/EelDescriptor.kt @@ -51,7 +51,7 @@ interface EelDescriptorWithoutNativeFileChooserSupport : EelDescriptor */ @ApiStatus.Experimental interface EelDescriptor { - @Deprecated("Use platform instead", ReplaceWith("platform")) + @Deprecated("Use osFamily instead", ReplaceWith("platform")) @get:ApiStatus.Internal val operatingSystem: OS get() = when (osFamily) { diff --git a/platform/eel/src/com/intellij/platform/eel/fs/EelFileSystemApi.kt b/platform/eel/src/com/intellij/platform/eel/fs/EelFileSystemApi.kt index 9509cad01af3..29fc58d9f050 100644 --- a/platform/eel/src/com/intellij/platform/eel/fs/EelFileSystemApi.kt +++ b/platform/eel/src/com/intellij/platform/eel/fs/EelFileSystemApi.kt @@ -9,6 +9,14 @@ import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.CheckReturnValue import java.nio.ByteBuffer +@get:ApiStatus.Internal +val EelFileSystemApi.pathOs: EelPath.OS + get() = when (this) { + is EelFileSystemPosixApi -> EelPath.OS.UNIX + is EelFileSystemWindowsApi -> EelPath.OS.WINDOWS + else -> throw UnsupportedOperationException("Unsupported OS: ${this::class.java}") + } + @get:ApiStatus.Internal val EelFileSystemApi.pathSeparator: String get() = when (this) { diff --git a/platform/eel/src/com/intellij/platform/eel/path/ArrayListEelAbsolutePath.kt b/platform/eel/src/com/intellij/platform/eel/path/ArrayListEelAbsolutePath.kt index b8117485ffe9..939b5dcee5b1 100644 --- a/platform/eel/src/com/intellij/platform/eel/path/ArrayListEelAbsolutePath.kt +++ b/platform/eel/src/com/intellij/platform/eel/path/ArrayListEelAbsolutePath.kt @@ -3,7 +3,6 @@ package com.intellij.platform.eel.path import com.intellij.platform.eel.EelDescriptor import com.intellij.platform.eel.EelOsFamily -import com.intellij.platform.eel.directorySeparators internal class ArrayListEelAbsolutePath private constructor( override val descriptor: EelDescriptor, @@ -53,7 +52,7 @@ internal class ArrayListEelAbsolutePath private constructor( } override fun resolve(other: String): EelPath { - val delimiters = this.platform.directorySeparators + val delimiters = this.os.directorySeparators val otherParts = other.split(*delimiters).filter(String::isNotEmpty) for (name in otherParts) { if (name.isNotEmpty()) { @@ -117,6 +116,12 @@ internal class ArrayListEelAbsolutePath private constructor( return nameCount - other.nameCount } + override val os: EelPath.OS + get() = when (this._root) { + Root.Unix -> EelPath.OS.UNIX + is Root.Windows -> EelPath.OS.WINDOWS + } + override fun equals(other: Any?): Boolean = other is EelPath && nameCount == other.nameCount && diff --git a/platform/eel/src/com/intellij/platform/eel/path/EelPath.kt b/platform/eel/src/com/intellij/platform/eel/path/EelPath.kt index 83ae5b71f814..f9bbdb72907a 100644 --- a/platform/eel/src/com/intellij/platform/eel/path/EelPath.kt +++ b/platform/eel/src/com/intellij/platform/eel/path/EelPath.kt @@ -3,6 +3,8 @@ package com.intellij.platform.eel.path import com.intellij.platform.eel.EelDescriptor import com.intellij.platform.eel.EelOsFamily +import com.intellij.platform.eel.EelPlatform +import com.intellij.platform.eel.path.EelPath.OS import org.jetbrains.annotations.ApiStatus @get:ApiStatus.Internal @@ -135,6 +137,17 @@ sealed interface EelPath { /** See [java.nio.file.Path.endsWith] */ fun endsWith(suffix: List): Boolean + /** + * Returns [EelPath.OS] that corresponds to this path. + * + * ```kotlin + * EelPath.parse("/abc/").os == EelPath.OS.UNIX + * EelPath.parse("C:\\abc\").os == EelPath.OS.WINDOWS + * ``` + */ + @get:ApiStatus.Internal + val os: OS + /** * ```kotlin * EelPath.parse("/abc", OS.UNIX).getChild("..") == EelPath.parse("abc/..", false) @@ -154,7 +167,7 @@ sealed interface EelPath { */ override fun toString(): String - @Deprecated("Use EelPlatform instead, will be removed soon") + @ApiStatus.Internal enum class OS { WINDOWS, UNIX } @@ -165,3 +178,27 @@ operator fun EelPath.div(part: String): EelPath = resolve(part) @ApiStatus.Experimental class EelPathException(val raw: String, val reason: String) : RuntimeException("`$raw`: $reason") + +@get:ApiStatus.Internal +val OS.pathSeparator: String + get() = when (this) { + OS.UNIX -> ":" + OS.WINDOWS -> ";" + } + +@get:ApiStatus.Internal +val EelPlatform.pathOs: OS + get() = when (this) { + is EelPlatform.Posix -> OS.UNIX + is EelPlatform.Windows -> OS.WINDOWS + } + +private val UNIX_DIRECTORY_SEPARATORS = charArrayOf('/') +private val WINDOWS_DIRECTORY_SEPARATORS = charArrayOf('/', '\\') + +@get:ApiStatus.Internal +val OS.directorySeparators: CharArray + get() = when (this) { + OS.UNIX -> UNIX_DIRECTORY_SEPARATORS + OS.WINDOWS -> WINDOWS_DIRECTORY_SEPARATORS + } \ No newline at end of file diff --git a/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioFileSystem.kt b/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioFileSystem.kt index 24418dd2ff2b..b3a064e8fa22 100644 --- a/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioFileSystem.kt +++ b/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioFileSystem.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.ijent.community.impl.nio import com.intellij.platform.eel.directorySeparators @@ -67,6 +67,10 @@ class IjentNioFileSystem internal constructor( } override fun getPath(first: String, vararg more: String): IjentNioPath { + val os = when (ijentFs) { + is IjentFileSystemPosixApi -> EelPath.OS.UNIX + is IjentFileSystemWindowsApi -> EelPath.OS.WINDOWS + } return try { more.fold(EelPath.parse(first, ijentFs.descriptor)) { path, newPart -> path.resolve(newPart) }.toNioPath() } diff --git a/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioPath.kt b/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioPath.kt index 4eb8363dc546..e0fb8856bc53 100644 --- a/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioPath.kt +++ b/platform/ijent/impl/src/com/intellij/platform/ijent/community/impl/nio/IjentNioPath.kt @@ -2,10 +2,8 @@ package com.intellij.platform.ijent.community.impl.nio import com.intellij.platform.core.nio.fs.BasicFileAttributesHolder2 -import com.intellij.platform.eel.EelOsFamily import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.path.EelPathException -import com.intellij.platform.eel.path.platform import com.intellij.platform.eel.provider.utils.getOrThrowFileSystemException import org.jetbrains.annotations.ApiStatus import java.net.URI @@ -156,9 +154,9 @@ internal class AbsoluteIjentNioPath(val eelPath: EelPath, nioFs: IjentNioFileSys } override fun toUri(): URI { - val prefix = when (eelPath.platform) { - EelOsFamily.Windows -> "/" + eelPath.root.toString().replace('\\', '/') - EelOsFamily.Posix -> null + val prefix = when (eelPath.os) { + EelPath.OS.WINDOWS -> "/" + eelPath.root.toString().replace('\\', '/') + EelPath.OS.UNIX -> null } val allParts = listOfNotNull(prefix) + eelPath.parts return allParts.fold(nioFs.uri, URI::resolve) diff --git a/platform/ijent/src/com/intellij/platform/ijent/EelPlatformEx.kt b/platform/ijent/src/com/intellij/platform/ijent/EelPlatformEx.kt index e4e2d9a8c0cd..7128e384bde8 100644 --- a/platform/ijent/src/com/intellij/platform/ijent/EelPlatformEx.kt +++ b/platform/ijent/src/com/intellij/platform/ijent/EelPlatformEx.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.ijent import com.intellij.platform.eel.EelPlatform diff --git a/platform/ijent/src/com/intellij/platform/ijent/spi/IjentDeployingOverShellProcessStrategy.kt b/platform/ijent/src/com/intellij/platform/ijent/spi/IjentDeployingOverShellProcessStrategy.kt index 79a160488138..ae521f3b9f4f 100644 --- a/platform/ijent/src/com/intellij/platform/ijent/spi/IjentDeployingOverShellProcessStrategy.kt +++ b/platform/ijent/src/com/intellij/platform/ijent/spi/IjentDeployingOverShellProcessStrategy.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.ijent.spi import com.intellij.execution.CommandLineUtil.posixQuote @@ -58,16 +58,12 @@ abstract class IjentDeployingOverShellProcessStrategy(scope: CoroutineScope) : I context } - private val myTargetPlatform = scope.async(start = CoroutineStart.LAZY) { - myContext.await().execCommand { + override suspend fun getTargetPlatform(): EelPlatform.Posix { + return myContext.await().execCommand { getTargetPlatform() } } - override suspend fun getTargetPlatform(): EelPlatform.Posix { - return myTargetPlatform.await() - } - final override suspend fun createProcess(binaryPath: String): IjentSessionMediator { return myContext.await().execCommand { execIjent(binaryPath) diff --git a/platform/lang-impl/testSources/com/intellij/openapi/projectRoots/ProjectJdkEelTest.kt b/platform/lang-impl/testSources/com/intellij/openapi/projectRoots/ProjectJdkEelTest.kt index 16ba237a7a11..1fb2bfd81f18 100644 --- a/platform/lang-impl/testSources/com/intellij/openapi/projectRoots/ProjectJdkEelTest.kt +++ b/platform/lang-impl/testSources/com/intellij/openapi/projectRoots/ProjectJdkEelTest.kt @@ -6,7 +6,6 @@ import com.intellij.openapi.application.edtWriteAction import com.intellij.openapi.roots.ui.configuration.SdkTestCase.TestSdkGenerator.SdkInfo import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel import com.intellij.openapi.roots.ui.configuration.testSdkFixture -import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.utils.EelPathUtils import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture @@ -26,7 +25,7 @@ import java.nio.file.Files @TestApplication class ProjectJdkEelTest { - val eel = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) + val eel = eelFixture(EelPath.OS.UNIX) val localProject = projectFixture(openAfterCreation = true) diff --git a/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggleStrategy.kt b/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggleStrategy.kt index 08685b28539c..a79b84fa22b2 100644 --- a/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggleStrategy.kt +++ b/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggleStrategy.kt @@ -5,10 +5,8 @@ import com.intellij.execution.wsl.WSLDistribution import com.intellij.execution.wsl.WslDistributionManager import com.intellij.execution.wsl.WslIjentManager import com.intellij.openapi.diagnostic.logger -import com.intellij.openapi.progress.runBlockingMaybeCancellable import com.intellij.platform.eel.provider.EelNioBridgeService import com.intellij.platform.ide.impl.wsl.ijent.nio.IjentWslNioFileSystemProvider -import com.intellij.platform.ijent.IjentPosixApi import com.intellij.platform.ijent.community.impl.IjentFailSafeFileSystemPosixApi import com.intellij.platform.ijent.community.impl.nio.IjentNioFileSystemProvider import com.intellij.platform.ijent.community.impl.nio.telemetry.TracingFileSystemProvider @@ -22,19 +20,14 @@ import java.net.URI import java.nio.file.FileSystem import java.nio.file.FileSystemAlreadyExistsException import java.nio.file.spi.FileSystemProvider -import java.util.concurrent.ConcurrentHashMap import java.util.function.BiConsumer -private suspend fun WSLDistribution.getIjent(): IjentPosixApi { - return WslIjentManager.instanceAsync().getIjentApi(this, null, false) -} - @ApiStatus.Internal @VisibleForTesting class IjentWslNioFsToggleStrategy( private val coroutineScope: CoroutineScope, ) { - internal val enabledInDistros: MutableMap = ConcurrentHashMap() + internal val enabledInDistros: MutableSet = ContainerUtil.newConcurrentSet() private val providersCache = ContainerUtil.createConcurrentWeakMap() @@ -67,27 +60,23 @@ class IjentWslNioFsToggleStrategy( } private fun handleWslDistributionAddition(distro: WSLDistribution) { + enabledInDistros += distro switchToIjentFs(distro) } private fun handleWslDistributionDeletion(distro: WSLDistribution) { - val descriptor = enabledInDistros.remove(distro) - - if (descriptor != null) { - recomputeEel(descriptor) { _, actualFs -> - actualFs - } + enabledInDistros -= distro + recomputeEel(distro) { _, actualFs -> + actualFs } } fun switchToIjentFs(distro: WSLDistribution) { val ijentFsProvider = TracingFileSystemProvider(IjentNioFileSystemProvider.getInstance()) - val descriptor = runBlockingMaybeCancellable { distro.getIjent() }.descriptor as WslEelDescriptor - - enabledInDistros[distro] = descriptor - try { - val ijentFs = IjentFailSafeFileSystemPosixApi(coroutineScope) { distro.getIjent() } + val ijentFs = IjentFailSafeFileSystemPosixApi(coroutineScope) { + WslIjentManager.instanceAsync().getIjentApi(distro, null, false) + } ijentFsProvider.newFileSystem( URI("ijent", "wsl", "/${distro.id}", null, null), IjentNioFileSystemProvider.newFileSystemMap(ijentFs), @@ -97,7 +86,7 @@ class IjentWslNioFsToggleStrategy( // Nothing. } - recomputeEel(descriptor) { underlyingProvider, _ -> + recomputeEel(distro) { underlyingProvider, _ -> val fileSystemProvider = providersCache.computeIfAbsent(distro.id) { IjentWslNioFileSystemProvider( wslDistribution = distro, @@ -111,9 +100,9 @@ class IjentWslNioFsToggleStrategy( } } - fun switchToTracingWsl9pFs(descriptor: WslEelDescriptor) { - recomputeEel(descriptor) { underlyingProvider, previousFs -> - LOG.info("Switching $descriptor to the original file system but with tracing") + fun switchToTracingWsl9pFs(distro: WSLDistribution) { + recomputeEel(distro) { underlyingProvider, previousFs -> + LOG.info("Switching $distro to the original file system but with tracing") try { previousFs?.close() @@ -129,11 +118,14 @@ class IjentWslNioFsToggleStrategy( fun unregisterAll() { val service = EelNioBridgeService.getInstanceSync() - enabledInDistros.entries.forEachGuaranteed { (_, descriptor) -> - service.unregister(descriptor) + val distros = mutableListOf() + enabledInDistros.removeIf { + distros += it + true + } + for (distro in distros) { + service.unregister(WslEelDescriptor(distro)) } - - enabledInDistros.clear() } } @@ -152,12 +144,13 @@ private val WSLDistribution.roots: Set } private fun recomputeEel( - descriptor: WslEelDescriptor, + distro: WSLDistribution, action: (underlyingProvider: FileSystemProvider, previousFs: FileSystem?) -> FileSystem?, ) { val service = EelNioBridgeService.getInstanceSync() + val descriptor = WslEelDescriptor(distro) - descriptor.distribution.roots.forEachGuaranteed { localRoot -> - service.register(localRoot, descriptor, descriptor.distribution.id, false, false, action) + distro.roots.forEachGuaranteed { localRoot -> + service.register(localRoot, descriptor, distro.id, false, false, action) } } \ No newline at end of file diff --git a/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt b/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt index dc5e771e5f4c..e135aadf8886 100644 --- a/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt +++ b/platform/platform-impl/eel/src/com/intellij/platform/ide/impl/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt @@ -48,14 +48,15 @@ class IjentWslNioFsToggler(private val coroutineScope: CoroutineScope) { fun switchToIjentFs(distro: WSLDistribution) { logErrorIfNotWindows() strategy ?: error("Not available") + strategy.enabledInDistros.add(distro) strategy.switchToIjentFs(distro) } @TestOnly - fun switchToTracingWsl9pFs(descriptor: WslEelDescriptor) { + fun switchToTracingWsl9pFs(distro: WSLDistribution) { logErrorIfNotWindows() strategy ?: error("Not available") - strategy.switchToTracingWsl9pFs(descriptor) + strategy.switchToTracingWsl9pFs(distro) } @TestOnly diff --git a/platform/testFramework/junit5/eel/src/fixture/fixtures.kt b/platform/testFramework/junit5/eel/src/fixture/fixtures.kt index f841f00f4e2c..44ac7a6fcbda 100644 --- a/platform/testFramework/junit5/eel/src/fixture/fixtures.kt +++ b/platform/testFramework/junit5/eel/src/fixture/fixtures.kt @@ -3,7 +3,7 @@ package com.intellij.platform.testFramework.junit5.eel.fixture import com.intellij.platform.eel.EelApi import com.intellij.platform.eel.EelDescriptor -import com.intellij.platform.eel.EelPlatform +import com.intellij.platform.eel.EelOsFamily import com.intellij.platform.eel.path.EelPath import com.intellij.platform.testFramework.junit5.eel.impl.currentOs import com.intellij.platform.testFramework.junit5.eel.impl.eelInitializer @@ -39,7 +39,11 @@ interface IsolatedFileSystem { * The local file system would not be able to recognize these paths, so you can test whether your feature is eel-agnostic. */ @TestOnly -fun eelFixture(os: EelPlatform = currentOs): TestFixture { +fun eelFixture(os: EelPath.OS = currentOs): TestFixture { + val os = when (os) { + EelPath.OS.WINDOWS -> EelOsFamily.Windows + EelPath.OS.UNIX -> EelOsFamily.Posix + } return testFixture("eel-test-fixture", eelInitializer(os)) } diff --git a/platform/testFramework/junit5/eel/src/impl/nio/EelUnitTestFileSystem.kt b/platform/testFramework/junit5/eel/src/impl/nio/EelUnitTestFileSystem.kt index 660eeb41b391..7d826d85f116 100644 --- a/platform/testFramework/junit5/eel/src/impl/nio/EelUnitTestFileSystem.kt +++ b/platform/testFramework/junit5/eel/src/impl/nio/EelUnitTestFileSystem.kt @@ -1,19 +1,14 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.testFramework.junit5.eel.impl.nio import com.intellij.openapi.util.SystemInfo -import com.intellij.platform.eel.EelPlatform -import com.intellij.platform.eel.path.EelPath +import com.intellij.platform.eel.EelOsFamily import java.io.File -import java.nio.file.FileStore -import java.nio.file.FileSystem -import java.nio.file.Path -import java.nio.file.PathMatcher -import java.nio.file.WatchService +import java.nio.file.* import java.nio.file.attribute.UserPrincipalLookupService import java.nio.file.spi.FileSystemProvider -internal class EelUnitTestFileSystem(val provider: FileSystemProvider, val os: EelPlatform, val rootDirectory: Path, val fakeLocalRoot: String) : FileSystem() { +internal class EelUnitTestFileSystem(val provider: FileSystemProvider, val os: EelOsFamily, val rootDirectory: Path, val fakeLocalRoot: String) : FileSystem() { val root: EelUnitTestPath = EelUnitTestPath(this, rootDirectory) override fun provider(): FileSystemProvider { diff --git a/platform/testFramework/junit5/eel/src/impl/util.kt b/platform/testFramework/junit5/eel/src/impl/util.kt index 3c1eaa3b2e60..f414d0dc4489 100644 --- a/platform/testFramework/junit5/eel/src/impl/util.kt +++ b/platform/testFramework/junit5/eel/src/impl/util.kt @@ -5,11 +5,9 @@ package com.intellij.platform.testFramework.junit5.eel.impl import com.intellij.openapi.util.SystemInfo import com.intellij.platform.core.nio.fs.MultiRoutingFileSystem -import com.intellij.platform.eel.EelApi -import com.intellij.platform.eel.EelDescriptor -import com.intellij.platform.eel.EelPlatform +import com.intellij.platform.eel.* import com.intellij.platform.eel.fs.createTemporaryDirectory -import com.intellij.platform.eel.getOrThrow +import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.EelNioBridgeService import com.intellij.platform.eel.provider.asNioPath import com.intellij.platform.testFramework.junit5.eel.fixture.IsolatedFileSystem @@ -28,31 +26,26 @@ import kotlin.io.path.name internal const val FAKE_WINDOWS_ROOT = "\\\\dummy-ij-root\\test-eel\\" -private val EelPlatform.name: String get() = when (this) { - is EelPlatform.Posix -> "posix" - is EelPlatform.Windows -> "windows" -} - -internal val currentOs: EelPlatform +internal val currentOs: EelPath.OS get() = if (SystemInfo.isWindows) { - EelPlatform.Windows(EelPlatform.Arch.Unknown) + EelPath.OS.WINDOWS } else { - EelPlatform.Linux(EelPlatform.Arch.Unknown) + EelPath.OS.UNIX } -internal fun eelApiByOs(fileSystem: EelUnitTestFileSystem, descriptor: EelTestDescriptor, os: EelPlatform): EelApi { +internal fun eelApiByOs(fileSystem: EelUnitTestFileSystem, descriptor: EelTestDescriptor, os: EelOsFamily): EelApi { return when (os) { - is EelPlatform.Posix -> EelTestPosixApi(descriptor, fileSystem, fileSystem.fakeLocalRoot) - is EelPlatform.Windows -> EelTestWindowsApi(descriptor, fileSystem, fileSystem.fakeLocalRoot) + EelOsFamily.Posix -> EelTestPosixApi(descriptor, fileSystem, fileSystem.fakeLocalRoot) + EelOsFamily.Windows -> EelTestWindowsApi(descriptor, fileSystem, fileSystem.fakeLocalRoot) } } internal data class IsolatedFileSystemImpl(override val storageRoot: Path, override val eelDescriptor: EelDescriptor, override val eelApi: EelApi) : IsolatedFileSystem -internal fun eelInitializer(os: EelPlatform): TestFixtureInitializer = TestFixtureInitializer { initialized -> +internal fun eelInitializer(os: EelOsFamily): TestFixtureInitializer = TestFixtureInitializer { initialized -> checkMultiRoutingFileSystem() - val meaningfulDirName = "eel-fixture-${os.name}" + val meaningfulDirName = "eel-fixture-${os.name.lowercase()}" val directory = Files.createTempDirectory(meaningfulDirName) val fakeRoot = if (SystemInfo.isUnix) { @@ -67,8 +60,8 @@ internal fun eelInitializer(os: EelPlatform): TestFixtureInitializer(null) - val descriptor = EelTestDescriptor(Ksuid.generate().toString(), os.osFamily, apiRef::get) - service.register(fakeRoot, descriptor, descriptor.id, true, (os is EelPlatform.Windows)) { _, _ -> + val descriptor = EelTestDescriptor(Ksuid.generate().toString(), os, apiRef::get) + service.register(fakeRoot, descriptor, descriptor.id, true, (os.isWindows)) { _, _ -> fakeLocalFileSystem } val eelApi = eelApiByOs(fakeLocalFileSystem, descriptor, os) diff --git a/platform/testFramework/junit5/eel/test/showcase/EelFsShowcase.kt b/platform/testFramework/junit5/eel/test/showcase/EelFsShowcase.kt index 087f5581acb0..f0fa6ff57aec 100644 --- a/platform/testFramework/junit5/eel/test/showcase/EelFsShowcase.kt +++ b/platform/testFramework/junit5/eel/test/showcase/EelFsShowcase.kt @@ -1,15 +1,14 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.testFramework.junit5.eel.showcase import com.intellij.openapi.util.io.OSAgnosticPathUtil -import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.asEelPath import com.intellij.platform.eel.provider.asNioPath import com.intellij.platform.eel.provider.utils.EelPathUtils -import com.intellij.testFramework.junit5.TestApplication import com.intellij.platform.testFramework.junit5.eel.fixture.IsolatedFileSystem import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture +import com.intellij.testFramework.junit5.TestApplication import com.intellij.testFramework.junit5.fixture.TestFixture import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -20,13 +19,13 @@ import java.nio.file.Path @TestApplication class EelFsShowcase { - val fsAndEelUnix: TestFixture = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) + val fsAndEelUnix: TestFixture = eelFixture(EelPath.OS.UNIX) - val fsAndEelWindows: TestFixture = eelFixture(EelPlatform.Windows(EelPlatform.Arch.Unknown)) + val fsAndEelWindows: TestFixture = eelFixture(EelPath.OS.WINDOWS) - fun EelPlatform.osDependentFixture(): TestFixture = when (this) { - is EelPlatform.Windows -> fsAndEelWindows - is EelPlatform.Posix -> fsAndEelUnix + fun EelPath.OS.osDependentFixture(): TestFixture = when (this) { + EelPath.OS.WINDOWS -> fsAndEelWindows + EelPath.OS.UNIX -> fsAndEelUnix } @Test @@ -60,16 +59,15 @@ class EelFsShowcase { Assertions.assertEquals(eelNio, eelNioEel) } - @Test - fun `uri validity`() { - for (eel in listOf(fsAndEelUnix, fsAndEelWindows)) { - val root = eel.get().storageRoot - val path = root.resolve("a/b/c/d/e") - val uri = EelPathUtils.getUriLocalToEel(path) - Assertions.assertEquals("file", uri.scheme) - Assertions.assertNull(uri.authority) - Assertions.assertTrue(uri.path.contains("a/b/c/d/e")) - } + @ParameterizedTest + @EnumSource(EelPath.OS::class) + fun `uri validity`(os: EelPath.OS) { + val root = os.osDependentFixture().get().storageRoot + val path = root.resolve("a/b/c/d/e") + val uri = EelPathUtils.getUriLocalToEel(path) + Assertions.assertEquals("file", uri.scheme) + Assertions.assertNull(uri.authority) + Assertions.assertTrue(uri.path.contains("a/b/c/d/e")) } @Test diff --git a/platform/testFramework/junit5/eel/test/showcase/EelProjectShowcase.kt b/platform/testFramework/junit5/eel/test/showcase/EelProjectShowcase.kt index 2e157d48ecd4..32a1b84905d4 100644 --- a/platform/testFramework/junit5/eel/test/showcase/EelProjectShowcase.kt +++ b/platform/testFramework/junit5/eel/test/showcase/EelProjectShowcase.kt @@ -1,13 +1,12 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.testFramework.junit5.eel.showcase -import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.asEelPath import com.intellij.platform.eel.provider.utils.EelPathUtils -import com.intellij.testFramework.junit5.TestApplication import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture import com.intellij.platform.testFramework.junit5.eel.fixture.tempDirFixture +import com.intellij.testFramework.junit5.TestApplication import com.intellij.testFramework.junit5.fixture.projectFixture import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -15,7 +14,7 @@ import java.nio.file.Path @TestApplication class EelProjectShowcase { - val eel = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) + val eel = eelFixture(EelPath.OS.UNIX) val tempDir = eel.tempDirFixture() val project = projectFixture(tempDir, openAfterCreation = true) diff --git a/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/GlobalWorkspaceModelEelTest.kt b/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/GlobalWorkspaceModelEelTest.kt index 8940442a4c18..27a95418a31d 100644 --- a/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/GlobalWorkspaceModelEelTest.kt +++ b/platform/workspace/jps/tests/testSrc/com/intellij/workspaceModel/ide/GlobalWorkspaceModelEelTest.kt @@ -6,7 +6,6 @@ import com.intellij.openapi.application.edtWriteAction import com.intellij.openapi.components.service import com.intellij.openapi.util.registry.Registry import com.intellij.platform.backend.workspace.GlobalWorkspaceModelCache -import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.getEelDescriptor import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture @@ -26,7 +25,7 @@ import org.junit.jupiter.api.Test @TestApplication class GlobalWorkspaceModelEelTest { - val eel = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) + val eel = eelFixture(EelPath.OS.UNIX) val eelTempDir = eel.tempDirFixture() val eelProject = projectFixture(eelTempDir) diff --git a/python/services/internal-impl/src/com/intellij/python/community/services/internal/impl/VanillaPythonWithLanguageLevelImpl.kt b/python/services/internal-impl/src/com/intellij/python/community/services/internal/impl/VanillaPythonWithLanguageLevelImpl.kt index 9a6ae733c881..e8de8d92f314 100644 --- a/python/services/internal-impl/src/com/intellij/python/community/services/internal/impl/VanillaPythonWithLanguageLevelImpl.kt +++ b/python/services/internal-impl/src/com/intellij/python/community/services/internal/impl/VanillaPythonWithLanguageLevelImpl.kt @@ -1,7 +1,8 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.python.community.services.internal.impl -import com.intellij.platform.eel.EelPlatform +import com.intellij.platform.eel.fs.pathOs +import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.provider.asNioPath import com.intellij.platform.eel.provider.getEelDescriptor import com.intellij.python.community.execService.python.validatePythonAndGetVersion @@ -75,9 +76,9 @@ class VanillaPythonWithLanguageLevelImpl internal constructor( override suspend fun getReadableName(): @Nls String { val eelApi = pythonBinary.getEelDescriptor().toEelApi() val home = eelApi.userInfo.home.asNioPath() - val separator = when (eelApi.platform) { - is EelPlatform.Windows -> "\\" - is EelPlatform.Posix -> "/" + val separator = when (eelApi.fs.pathOs) { + EelPath.OS.WINDOWS -> "\\" + EelPath.OS.UNIX -> "/" } val pythonString = (if (pythonBinary.startsWith(home)) "~$separator" + pythonBinary.relativeTo(home).pathString else pythonBinary.pathString)