IJPL-194952 Revert "[eel] IJPL-172897: remove EelPath.OS, use only EelPlatform in the API"

This reverts commit 1a1b6768


(cherry picked from commit f07a5eac3280186c0f27e156a70498a7ed962469)

IJ-MR-167682

GitOrigin-RevId: db14b1563fc992df3842d3407321bf2cc67381e9
This commit is contained in:
Vladimir Lagunov
2025-07-01 15:34:37 +02:00
committed by intellij-monorepo-bot
parent 70908d094a
commit 9a0da96e42
23 changed files with 159 additions and 125 deletions

View File

@@ -9,7 +9,6 @@ import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.SimpleJavaSdkType import com.intellij.openapi.projectRoots.SimpleJavaSdkType
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
import com.intellij.platform.eel.EelPlatform
import com.intellij.platform.eel.path.EelPath import com.intellij.platform.eel.path.EelPath
import com.intellij.platform.eel.provider.LocalEelDescriptor import com.intellij.platform.eel.provider.LocalEelDescriptor
import com.intellij.platform.eel.provider.utils.EelPathUtils import com.intellij.platform.eel.provider.utils.EelPathUtils
@@ -25,7 +24,7 @@ import java.nio.file.Path
@TestApplication @TestApplication
class ProjectWizardJdkComboBoxTest { class ProjectWizardJdkComboBoxTest {
val eelFixture = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) val eelFixture = eelFixture(EelPath.OS.UNIX)
@Test @Test
fun `changing eel changes available sdks`(@TestDisposable disposable: Disposable): Unit = timeoutRunBlocking { fun `changing eel changes available sdks`(@TestDisposable disposable: Disposable): Unit = timeoutRunBlocking {

View File

@@ -27,6 +27,8 @@ import kotlin.io.path.fileStore
import kotlin.streams.asSequence import kotlin.streams.asSequence
abstract class NioBasedEelFileSystemApi(@VisibleForTesting val fs: FileSystem) : EelFileSystemApi { abstract class NioBasedEelFileSystemApi(@VisibleForTesting val fs: FileSystem) : EelFileSystemApi {
abstract val pathOs: EelPath.OS
protected fun EelPath.toNioPath(): Path = protected fun EelPath.toNioPath(): Path =
fs.getPath(toString()) fs.getPath(toString())
@@ -335,6 +337,7 @@ abstract class PosixNioBasedEelFileSystemApi(
fs: FileSystem, fs: FileSystem,
override val user: EelUserPosixInfo, override val user: EelUserPosixInfo,
) : NioBasedEelFileSystemApi(fs), LocalEelFileSystemPosixApi { ) : NioBasedEelFileSystemApi(fs), LocalEelFileSystemPosixApi {
override val pathOs: EelPath.OS = EelPath.OS.UNIX
override suspend fun createDirectory( override suspend fun createDirectory(
path: EelPath, path: EelPath,
@@ -404,6 +407,7 @@ abstract class WindowsNioBasedEelFileSystemApi(
fs: FileSystem, fs: FileSystem,
override val user: EelUserWindowsInfo, override val user: EelUserWindowsInfo,
) : NioBasedEelFileSystemApi(fs), LocalEelFileSystemWindowsApi { ) : NioBasedEelFileSystemApi(fs), LocalEelFileSystemWindowsApi {
override val pathOs: EelPath.OS = EelPath.OS.WINDOWS
override suspend fun getRootDirectories(): Collection<EelPath> = override suspend fun getRootDirectories(): Collection<EelPath> =
FileSystems.getDefault().rootDirectories.map { path -> FileSystems.getDefault().rootDirectories.map { path ->

View File

@@ -62,10 +62,18 @@ class LocalPosixEelApiImpl(private val nioFs: FileSystem = FileSystems.getDefaul
check(SystemInfo.isUnix) check(SystemInfo.isUnix)
} }
override val platform: EelPlatform.Posix = when { override val platform: EelPlatform.Posix
SystemInfo.isMac -> EelPlatform.Darwin(CpuArch.CURRENT.toEelArch()) get() {
SystemInfo.isFreeBSD -> EelPlatform.FreeBSD(CpuArch.CURRENT.toEelArch()) val arch = CpuArch.CURRENT.toEelArch()
else -> EelPlatform.Linux(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 tunnels: EelTunnelsPosixApi get() = EelLocalTunnelsApiImpl
@@ -80,6 +88,7 @@ class LocalPosixEelApiImpl(private val nioFs: FileSystem = FileSystems.getDefaul
} }
override val fs: LocalEelFileSystemPosixApi = object : PosixNioBasedEelFileSystemApi(nioFs, userInfo) { override val fs: LocalEelFileSystemPosixApi = object : PosixNioBasedEelFileSystemApi(nioFs, userInfo) {
override val pathOs: EelPath.OS = EelPath.OS.UNIX
override val descriptor: EelDescriptor get() = LocalEelDescriptor override val descriptor: EelDescriptor get() = LocalEelDescriptor
override suspend fun createTemporaryDirectory( override suspend fun createTemporaryDirectory(

View File

@@ -393,13 +393,6 @@ f:com.intellij.platform.eel.channels.EelSendChannelKt
- a:toString():java.lang.String - a:toString():java.lang.String
*f:com.intellij.platform.eel.path.EelPath$Companion *f:com.intellij.platform.eel.path.EelPath$Companion
- f:parse(java.lang.String,com.intellij.platform.eel.EelDescriptor):com.intellij.platform.eel.path.EelPath - 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 *f:com.intellij.platform.eel.path.EelPathException
- java.lang.RuntimeException - java.lang.RuntimeException
- <init>(java.lang.String,java.lang.String):V - <init>(java.lang.String,java.lang.String):V

View File

@@ -18,7 +18,6 @@ interface EelApi {
@get:ApiStatus.Experimental @get:ApiStatus.Experimental
val descriptor: EelDescriptor val descriptor: EelDescriptor
// TODO: should it be extension property?
val platform: EelPlatform val platform: EelPlatform
/** Docs: [EelFileSystemApi] */ /** Docs: [EelFileSystemApi] */

View File

@@ -51,7 +51,7 @@ interface EelDescriptorWithoutNativeFileChooserSupport : EelDescriptor
*/ */
@ApiStatus.Experimental @ApiStatus.Experimental
interface EelDescriptor { interface EelDescriptor {
@Deprecated("Use platform instead", ReplaceWith("platform")) @Deprecated("Use osFamily instead", ReplaceWith("platform"))
@get:ApiStatus.Internal @get:ApiStatus.Internal
val operatingSystem: OS val operatingSystem: OS
get() = when (osFamily) { get() = when (osFamily) {

View File

@@ -9,6 +9,14 @@ import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.CheckReturnValue import org.jetbrains.annotations.CheckReturnValue
import java.nio.ByteBuffer 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 @get:ApiStatus.Internal
val EelFileSystemApi.pathSeparator: String val EelFileSystemApi.pathSeparator: String
get() = when (this) { get() = when (this) {

View File

@@ -3,7 +3,6 @@ package com.intellij.platform.eel.path
import com.intellij.platform.eel.EelDescriptor import com.intellij.platform.eel.EelDescriptor
import com.intellij.platform.eel.EelOsFamily import com.intellij.platform.eel.EelOsFamily
import com.intellij.platform.eel.directorySeparators
internal class ArrayListEelAbsolutePath private constructor( internal class ArrayListEelAbsolutePath private constructor(
override val descriptor: EelDescriptor, override val descriptor: EelDescriptor,
@@ -53,7 +52,7 @@ internal class ArrayListEelAbsolutePath private constructor(
} }
override fun resolve(other: String): EelPath { override fun resolve(other: String): EelPath {
val delimiters = this.platform.directorySeparators val delimiters = this.os.directorySeparators
val otherParts = other.split(*delimiters).filter(String::isNotEmpty) val otherParts = other.split(*delimiters).filter(String::isNotEmpty)
for (name in otherParts) { for (name in otherParts) {
if (name.isNotEmpty()) { if (name.isNotEmpty()) {
@@ -117,6 +116,12 @@ internal class ArrayListEelAbsolutePath private constructor(
return nameCount - other.nameCount 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 = override fun equals(other: Any?): Boolean =
other is EelPath && other is EelPath &&
nameCount == other.nameCount && nameCount == other.nameCount &&

View File

@@ -3,6 +3,8 @@ package com.intellij.platform.eel.path
import com.intellij.platform.eel.EelDescriptor import com.intellij.platform.eel.EelDescriptor
import com.intellij.platform.eel.EelOsFamily 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 import org.jetbrains.annotations.ApiStatus
@get:ApiStatus.Internal @get:ApiStatus.Internal
@@ -135,6 +137,17 @@ sealed interface EelPath {
/** See [java.nio.file.Path.endsWith] */ /** See [java.nio.file.Path.endsWith] */
fun endsWith(suffix: List<String>): Boolean fun endsWith(suffix: List<String>): 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 * ```kotlin
* EelPath.parse("/abc", OS.UNIX).getChild("..") == EelPath.parse("abc/..", false) * EelPath.parse("/abc", OS.UNIX).getChild("..") == EelPath.parse("abc/..", false)
@@ -154,7 +167,7 @@ sealed interface EelPath {
*/ */
override fun toString(): String override fun toString(): String
@Deprecated("Use EelPlatform instead, will be removed soon") @ApiStatus.Internal
enum class OS { enum class OS {
WINDOWS, UNIX WINDOWS, UNIX
} }
@@ -165,3 +178,27 @@ operator fun EelPath.div(part: String): EelPath = resolve(part)
@ApiStatus.Experimental @ApiStatus.Experimental
class EelPathException(val raw: String, val reason: String) : RuntimeException("`$raw`: $reason") 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
}

View File

@@ -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 package com.intellij.platform.ijent.community.impl.nio
import com.intellij.platform.eel.directorySeparators import com.intellij.platform.eel.directorySeparators
@@ -67,6 +67,10 @@ class IjentNioFileSystem internal constructor(
} }
override fun getPath(first: String, vararg more: String): IjentNioPath { 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 { return try {
more.fold(EelPath.parse(first, ijentFs.descriptor)) { path, newPart -> path.resolve(newPart) }.toNioPath() more.fold(EelPath.parse(first, ijentFs.descriptor)) { path, newPart -> path.resolve(newPart) }.toNioPath()
} }

View File

@@ -2,10 +2,8 @@
package com.intellij.platform.ijent.community.impl.nio package com.intellij.platform.ijent.community.impl.nio
import com.intellij.platform.core.nio.fs.BasicFileAttributesHolder2 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.EelPath
import com.intellij.platform.eel.path.EelPathException import com.intellij.platform.eel.path.EelPathException
import com.intellij.platform.eel.path.platform
import com.intellij.platform.eel.provider.utils.getOrThrowFileSystemException import com.intellij.platform.eel.provider.utils.getOrThrowFileSystemException
import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.ApiStatus
import java.net.URI import java.net.URI
@@ -156,9 +154,9 @@ internal class AbsoluteIjentNioPath(val eelPath: EelPath, nioFs: IjentNioFileSys
} }
override fun toUri(): URI { override fun toUri(): URI {
val prefix = when (eelPath.platform) { val prefix = when (eelPath.os) {
EelOsFamily.Windows -> "/" + eelPath.root.toString().replace('\\', '/') EelPath.OS.WINDOWS -> "/" + eelPath.root.toString().replace('\\', '/')
EelOsFamily.Posix -> null EelPath.OS.UNIX -> null
} }
val allParts = listOfNotNull(prefix) + eelPath.parts val allParts = listOfNotNull(prefix) + eelPath.parts
return allParts.fold(nioFs.uri, URI::resolve) return allParts.fold(nioFs.uri, URI::resolve)

View File

@@ -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 package com.intellij.platform.ijent
import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.EelPlatform

View File

@@ -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 package com.intellij.platform.ijent.spi
import com.intellij.execution.CommandLineUtil.posixQuote import com.intellij.execution.CommandLineUtil.posixQuote
@@ -58,16 +58,12 @@ abstract class IjentDeployingOverShellProcessStrategy(scope: CoroutineScope) : I
context context
} }
private val myTargetPlatform = scope.async(start = CoroutineStart.LAZY) { override suspend fun getTargetPlatform(): EelPlatform.Posix {
myContext.await().execCommand { return myContext.await().execCommand {
getTargetPlatform() getTargetPlatform()
} }
} }
override suspend fun getTargetPlatform(): EelPlatform.Posix {
return myTargetPlatform.await()
}
final override suspend fun createProcess(binaryPath: String): IjentSessionMediator { final override suspend fun createProcess(binaryPath: String): IjentSessionMediator {
return myContext.await().execCommand { return myContext.await().execCommand {
execIjent(binaryPath) execIjent(binaryPath)

View File

@@ -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.SdkTestCase.TestSdkGenerator.SdkInfo
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel
import com.intellij.openapi.roots.ui.configuration.testSdkFixture 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.path.EelPath
import com.intellij.platform.eel.provider.utils.EelPathUtils import com.intellij.platform.eel.provider.utils.EelPathUtils
import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture
@@ -26,7 +25,7 @@ import java.nio.file.Files
@TestApplication @TestApplication
class ProjectJdkEelTest { class ProjectJdkEelTest {
val eel = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) val eel = eelFixture(EelPath.OS.UNIX)
val localProject = projectFixture(openAfterCreation = true) val localProject = projectFixture(openAfterCreation = true)

View File

@@ -5,10 +5,8 @@ import com.intellij.execution.wsl.WSLDistribution
import com.intellij.execution.wsl.WslDistributionManager import com.intellij.execution.wsl.WslDistributionManager
import com.intellij.execution.wsl.WslIjentManager import com.intellij.execution.wsl.WslIjentManager
import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.runBlockingMaybeCancellable
import com.intellij.platform.eel.provider.EelNioBridgeService import com.intellij.platform.eel.provider.EelNioBridgeService
import com.intellij.platform.ide.impl.wsl.ijent.nio.IjentWslNioFileSystemProvider 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.IjentFailSafeFileSystemPosixApi
import com.intellij.platform.ijent.community.impl.nio.IjentNioFileSystemProvider import com.intellij.platform.ijent.community.impl.nio.IjentNioFileSystemProvider
import com.intellij.platform.ijent.community.impl.nio.telemetry.TracingFileSystemProvider 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.FileSystem
import java.nio.file.FileSystemAlreadyExistsException import java.nio.file.FileSystemAlreadyExistsException
import java.nio.file.spi.FileSystemProvider import java.nio.file.spi.FileSystemProvider
import java.util.concurrent.ConcurrentHashMap
import java.util.function.BiConsumer import java.util.function.BiConsumer
private suspend fun WSLDistribution.getIjent(): IjentPosixApi {
return WslIjentManager.instanceAsync().getIjentApi(this, null, false)
}
@ApiStatus.Internal @ApiStatus.Internal
@VisibleForTesting @VisibleForTesting
class IjentWslNioFsToggleStrategy( class IjentWslNioFsToggleStrategy(
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
) { ) {
internal val enabledInDistros: MutableMap<WSLDistribution, WslEelDescriptor> = ConcurrentHashMap() internal val enabledInDistros: MutableSet<WSLDistribution> = ContainerUtil.newConcurrentSet()
private val providersCache = ContainerUtil.createConcurrentWeakMap<String, IjentWslNioFileSystemProvider>() private val providersCache = ContainerUtil.createConcurrentWeakMap<String, IjentWslNioFileSystemProvider>()
@@ -67,27 +60,23 @@ class IjentWslNioFsToggleStrategy(
} }
private fun handleWslDistributionAddition(distro: WSLDistribution) { private fun handleWslDistributionAddition(distro: WSLDistribution) {
enabledInDistros += distro
switchToIjentFs(distro) switchToIjentFs(distro)
} }
private fun handleWslDistributionDeletion(distro: WSLDistribution) { private fun handleWslDistributionDeletion(distro: WSLDistribution) {
val descriptor = enabledInDistros.remove(distro) enabledInDistros -= distro
recomputeEel(distro) { _, actualFs ->
if (descriptor != null) {
recomputeEel(descriptor) { _, actualFs ->
actualFs actualFs
} }
} }
}
fun switchToIjentFs(distro: WSLDistribution) { fun switchToIjentFs(distro: WSLDistribution) {
val ijentFsProvider = TracingFileSystemProvider(IjentNioFileSystemProvider.getInstance()) val ijentFsProvider = TracingFileSystemProvider(IjentNioFileSystemProvider.getInstance())
val descriptor = runBlockingMaybeCancellable { distro.getIjent() }.descriptor as WslEelDescriptor
enabledInDistros[distro] = descriptor
try { try {
val ijentFs = IjentFailSafeFileSystemPosixApi(coroutineScope) { distro.getIjent() } val ijentFs = IjentFailSafeFileSystemPosixApi(coroutineScope) {
WslIjentManager.instanceAsync().getIjentApi(distro, null, false)
}
ijentFsProvider.newFileSystem( ijentFsProvider.newFileSystem(
URI("ijent", "wsl", "/${distro.id}", null, null), URI("ijent", "wsl", "/${distro.id}", null, null),
IjentNioFileSystemProvider.newFileSystemMap(ijentFs), IjentNioFileSystemProvider.newFileSystemMap(ijentFs),
@@ -97,7 +86,7 @@ class IjentWslNioFsToggleStrategy(
// Nothing. // Nothing.
} }
recomputeEel(descriptor) { underlyingProvider, _ -> recomputeEel(distro) { underlyingProvider, _ ->
val fileSystemProvider = providersCache.computeIfAbsent(distro.id) { val fileSystemProvider = providersCache.computeIfAbsent(distro.id) {
IjentWslNioFileSystemProvider( IjentWslNioFileSystemProvider(
wslDistribution = distro, wslDistribution = distro,
@@ -111,9 +100,9 @@ class IjentWslNioFsToggleStrategy(
} }
} }
fun switchToTracingWsl9pFs(descriptor: WslEelDescriptor) { fun switchToTracingWsl9pFs(distro: WSLDistribution) {
recomputeEel(descriptor) { underlyingProvider, previousFs -> recomputeEel(distro) { underlyingProvider, previousFs ->
LOG.info("Switching $descriptor to the original file system but with tracing") LOG.info("Switching $distro to the original file system but with tracing")
try { try {
previousFs?.close() previousFs?.close()
@@ -129,11 +118,14 @@ class IjentWslNioFsToggleStrategy(
fun unregisterAll() { fun unregisterAll() {
val service = EelNioBridgeService.getInstanceSync() val service = EelNioBridgeService.getInstanceSync()
enabledInDistros.entries.forEachGuaranteed { (_, descriptor) -> val distros = mutableListOf<WSLDistribution>()
service.unregister(descriptor) enabledInDistros.removeIf {
distros += it
true
}
for (distro in distros) {
service.unregister(WslEelDescriptor(distro))
} }
enabledInDistros.clear()
} }
} }
@@ -152,12 +144,13 @@ private val WSLDistribution.roots: Set<String>
} }
private fun recomputeEel( private fun recomputeEel(
descriptor: WslEelDescriptor, distro: WSLDistribution,
action: (underlyingProvider: FileSystemProvider, previousFs: FileSystem?) -> FileSystem?, action: (underlyingProvider: FileSystemProvider, previousFs: FileSystem?) -> FileSystem?,
) { ) {
val service = EelNioBridgeService.getInstanceSync() val service = EelNioBridgeService.getInstanceSync()
val descriptor = WslEelDescriptor(distro)
descriptor.distribution.roots.forEachGuaranteed { localRoot -> distro.roots.forEachGuaranteed { localRoot ->
service.register(localRoot, descriptor, descriptor.distribution.id, false, false, action) service.register(localRoot, descriptor, distro.id, false, false, action)
} }
} }

View File

@@ -48,14 +48,15 @@ class IjentWslNioFsToggler(private val coroutineScope: CoroutineScope) {
fun switchToIjentFs(distro: WSLDistribution) { fun switchToIjentFs(distro: WSLDistribution) {
logErrorIfNotWindows() logErrorIfNotWindows()
strategy ?: error("Not available") strategy ?: error("Not available")
strategy.enabledInDistros.add(distro)
strategy.switchToIjentFs(distro) strategy.switchToIjentFs(distro)
} }
@TestOnly @TestOnly
fun switchToTracingWsl9pFs(descriptor: WslEelDescriptor) { fun switchToTracingWsl9pFs(distro: WSLDistribution) {
logErrorIfNotWindows() logErrorIfNotWindows()
strategy ?: error("Not available") strategy ?: error("Not available")
strategy.switchToTracingWsl9pFs(descriptor) strategy.switchToTracingWsl9pFs(distro)
} }
@TestOnly @TestOnly

View File

@@ -3,7 +3,7 @@ package com.intellij.platform.testFramework.junit5.eel.fixture
import com.intellij.platform.eel.EelApi import com.intellij.platform.eel.EelApi
import com.intellij.platform.eel.EelDescriptor 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.eel.path.EelPath
import com.intellij.platform.testFramework.junit5.eel.impl.currentOs import com.intellij.platform.testFramework.junit5.eel.impl.currentOs
import com.intellij.platform.testFramework.junit5.eel.impl.eelInitializer 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. * The local file system would not be able to recognize these paths, so you can test whether your feature is eel-agnostic.
*/ */
@TestOnly @TestOnly
fun eelFixture(os: EelPlatform = currentOs): TestFixture<IsolatedFileSystem> { fun eelFixture(os: EelPath.OS = currentOs): TestFixture<IsolatedFileSystem> {
val os = when (os) {
EelPath.OS.WINDOWS -> EelOsFamily.Windows
EelPath.OS.UNIX -> EelOsFamily.Posix
}
return testFixture("eel-test-fixture", eelInitializer(os)) return testFixture("eel-test-fixture", eelInitializer(os))
} }

View File

@@ -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 package com.intellij.platform.testFramework.junit5.eel.impl.nio
import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.SystemInfo
import com.intellij.platform.eel.EelPlatform import com.intellij.platform.eel.EelOsFamily
import com.intellij.platform.eel.path.EelPath
import java.io.File import java.io.File
import java.nio.file.FileStore import java.nio.file.*
import java.nio.file.FileSystem
import java.nio.file.Path
import java.nio.file.PathMatcher
import java.nio.file.WatchService
import java.nio.file.attribute.UserPrincipalLookupService import java.nio.file.attribute.UserPrincipalLookupService
import java.nio.file.spi.FileSystemProvider 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) val root: EelUnitTestPath = EelUnitTestPath(this, rootDirectory)
override fun provider(): FileSystemProvider { override fun provider(): FileSystemProvider {

View File

@@ -5,11 +5,9 @@ package com.intellij.platform.testFramework.junit5.eel.impl
import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.SystemInfo
import com.intellij.platform.core.nio.fs.MultiRoutingFileSystem import com.intellij.platform.core.nio.fs.MultiRoutingFileSystem
import com.intellij.platform.eel.EelApi import com.intellij.platform.eel.*
import com.intellij.platform.eel.EelDescriptor
import com.intellij.platform.eel.EelPlatform
import com.intellij.platform.eel.fs.createTemporaryDirectory 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.EelNioBridgeService
import com.intellij.platform.eel.provider.asNioPath import com.intellij.platform.eel.provider.asNioPath
import com.intellij.platform.testFramework.junit5.eel.fixture.IsolatedFileSystem 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\\" internal const val FAKE_WINDOWS_ROOT = "\\\\dummy-ij-root\\test-eel\\"
private val EelPlatform.name: String get() = when (this) { internal val currentOs: EelPath.OS
is EelPlatform.Posix -> "posix"
is EelPlatform.Windows -> "windows"
}
internal val currentOs: EelPlatform
get() = if (SystemInfo.isWindows) { get() = if (SystemInfo.isWindows) {
EelPlatform.Windows(EelPlatform.Arch.Unknown) EelPath.OS.WINDOWS
} }
else { 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) { return when (os) {
is EelPlatform.Posix -> EelTestPosixApi(descriptor, fileSystem, fileSystem.fakeLocalRoot) EelOsFamily.Posix -> EelTestPosixApi(descriptor, fileSystem, fileSystem.fakeLocalRoot)
is EelPlatform.Windows -> EelTestWindowsApi(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 data class IsolatedFileSystemImpl(override val storageRoot: Path, override val eelDescriptor: EelDescriptor, override val eelApi: EelApi) : IsolatedFileSystem
internal fun eelInitializer(os: EelPlatform): TestFixtureInitializer<IsolatedFileSystem> = TestFixtureInitializer { initialized -> internal fun eelInitializer(os: EelOsFamily): TestFixtureInitializer<IsolatedFileSystem> = TestFixtureInitializer { initialized ->
checkMultiRoutingFileSystem() checkMultiRoutingFileSystem()
val meaningfulDirName = "eel-fixture-${os.name}" val meaningfulDirName = "eel-fixture-${os.name.lowercase()}"
val directory = Files.createTempDirectory(meaningfulDirName) val directory = Files.createTempDirectory(meaningfulDirName)
val fakeRoot = if (SystemInfo.isUnix) { val fakeRoot = if (SystemInfo.isUnix) {
@@ -67,8 +60,8 @@ internal fun eelInitializer(os: EelPlatform): TestFixtureInitializer<IsolatedFil
val service = EelNioBridgeService.getInstanceSync() val service = EelNioBridgeService.getInstanceSync()
val fakeLocalFileSystem = EelUnitTestFileSystem(EelUnitTestFileSystemProvider(defaultProvider), os, directory, fakeRoot) val fakeLocalFileSystem = EelUnitTestFileSystem(EelUnitTestFileSystemProvider(defaultProvider), os, directory, fakeRoot)
val apiRef = AtomicReference<EelApi>(null) val apiRef = AtomicReference<EelApi>(null)
val descriptor = EelTestDescriptor(Ksuid.generate().toString(), os.osFamily, apiRef::get) val descriptor = EelTestDescriptor(Ksuid.generate().toString(), os, apiRef::get)
service.register(fakeRoot, descriptor, descriptor.id, true, (os is EelPlatform.Windows)) { _, _ -> service.register(fakeRoot, descriptor, descriptor.id, true, (os.isWindows)) { _, _ ->
fakeLocalFileSystem fakeLocalFileSystem
} }
val eelApi = eelApiByOs(fakeLocalFileSystem, descriptor, os) val eelApi = eelApiByOs(fakeLocalFileSystem, descriptor, os)

View File

@@ -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 package com.intellij.platform.testFramework.junit5.eel.showcase
import com.intellij.openapi.util.io.OSAgnosticPathUtil 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.path.EelPath
import com.intellij.platform.eel.provider.asEelPath import com.intellij.platform.eel.provider.asEelPath
import com.intellij.platform.eel.provider.asNioPath import com.intellij.platform.eel.provider.asNioPath
import com.intellij.platform.eel.provider.utils.EelPathUtils 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.IsolatedFileSystem
import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.testFramework.junit5.fixture.TestFixture import com.intellij.testFramework.junit5.fixture.TestFixture
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@@ -20,13 +19,13 @@ import java.nio.file.Path
@TestApplication @TestApplication
class EelFsShowcase { class EelFsShowcase {
val fsAndEelUnix: TestFixture<IsolatedFileSystem> = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) val fsAndEelUnix: TestFixture<IsolatedFileSystem> = eelFixture(EelPath.OS.UNIX)
val fsAndEelWindows: TestFixture<IsolatedFileSystem> = eelFixture(EelPlatform.Windows(EelPlatform.Arch.Unknown)) val fsAndEelWindows: TestFixture<IsolatedFileSystem> = eelFixture(EelPath.OS.WINDOWS)
fun EelPlatform.osDependentFixture(): TestFixture<IsolatedFileSystem> = when (this) { fun EelPath.OS.osDependentFixture(): TestFixture<IsolatedFileSystem> = when (this) {
is EelPlatform.Windows -> fsAndEelWindows EelPath.OS.WINDOWS -> fsAndEelWindows
is EelPlatform.Posix -> fsAndEelUnix EelPath.OS.UNIX -> fsAndEelUnix
} }
@Test @Test
@@ -60,17 +59,16 @@ class EelFsShowcase {
Assertions.assertEquals(eelNio, eelNioEel) Assertions.assertEquals(eelNio, eelNioEel)
} }
@Test @ParameterizedTest
fun `uri validity`() { @EnumSource(EelPath.OS::class)
for (eel in listOf(fsAndEelUnix, fsAndEelWindows)) { fun `uri validity`(os: EelPath.OS) {
val root = eel.get().storageRoot val root = os.osDependentFixture().get().storageRoot
val path = root.resolve("a/b/c/d/e") val path = root.resolve("a/b/c/d/e")
val uri = EelPathUtils.getUriLocalToEel(path) val uri = EelPathUtils.getUriLocalToEel(path)
Assertions.assertEquals("file", uri.scheme) Assertions.assertEquals("file", uri.scheme)
Assertions.assertNull(uri.authority) Assertions.assertNull(uri.authority)
Assertions.assertTrue(uri.path.contains("a/b/c/d/e")) Assertions.assertTrue(uri.path.contains("a/b/c/d/e"))
} }
}
@Test @Test
fun `windows path is separator agnostic`() { fun `windows path is separator agnostic`() {

View File

@@ -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 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.path.EelPath
import com.intellij.platform.eel.provider.asEelPath import com.intellij.platform.eel.provider.asEelPath
import com.intellij.platform.eel.provider.utils.EelPathUtils 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.eelFixture
import com.intellij.platform.testFramework.junit5.eel.fixture.tempDirFixture import com.intellij.platform.testFramework.junit5.eel.fixture.tempDirFixture
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.testFramework.junit5.fixture.projectFixture import com.intellij.testFramework.junit5.fixture.projectFixture
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@@ -15,7 +14,7 @@ import java.nio.file.Path
@TestApplication @TestApplication
class EelProjectShowcase { class EelProjectShowcase {
val eel = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) val eel = eelFixture(EelPath.OS.UNIX)
val tempDir = eel.tempDirFixture() val tempDir = eel.tempDirFixture()
val project = projectFixture(tempDir, openAfterCreation = true) val project = projectFixture(tempDir, openAfterCreation = true)

View File

@@ -6,7 +6,6 @@ import com.intellij.openapi.application.edtWriteAction
import com.intellij.openapi.components.service import com.intellij.openapi.components.service
import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.util.registry.Registry
import com.intellij.platform.backend.workspace.GlobalWorkspaceModelCache 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.path.EelPath
import com.intellij.platform.eel.provider.getEelDescriptor import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture import com.intellij.platform.testFramework.junit5.eel.fixture.eelFixture
@@ -26,7 +25,7 @@ import org.junit.jupiter.api.Test
@TestApplication @TestApplication
class GlobalWorkspaceModelEelTest { class GlobalWorkspaceModelEelTest {
val eel = eelFixture(EelPlatform.Linux(EelPlatform.Arch.Unknown)) val eel = eelFixture(EelPath.OS.UNIX)
val eelTempDir = eel.tempDirFixture() val eelTempDir = eel.tempDirFixture()
val eelProject = projectFixture(eelTempDir) val eelProject = projectFixture(eelTempDir)

View File

@@ -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. // 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 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.asNioPath
import com.intellij.platform.eel.provider.getEelDescriptor import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.python.community.execService.python.validatePythonAndGetVersion import com.intellij.python.community.execService.python.validatePythonAndGetVersion
@@ -75,9 +76,9 @@ class VanillaPythonWithLanguageLevelImpl internal constructor(
override suspend fun getReadableName(): @Nls String { override suspend fun getReadableName(): @Nls String {
val eelApi = pythonBinary.getEelDescriptor().toEelApi() val eelApi = pythonBinary.getEelDescriptor().toEelApi()
val home = eelApi.userInfo.home.asNioPath() val home = eelApi.userInfo.home.asNioPath()
val separator = when (eelApi.platform) { val separator = when (eelApi.fs.pathOs) {
is EelPlatform.Windows -> "\\" EelPath.OS.WINDOWS -> "\\"
is EelPlatform.Posix -> "/" EelPath.OS.UNIX -> "/"
} }
val pythonString = (if (pythonBinary.startsWith(home)) "~$separator" + pythonBinary.relativeTo(home).pathString val pythonString = (if (pythonBinary.startsWith(home)) "~$separator" + pythonBinary.relativeTo(home).pathString
else pythonBinary.pathString) else pythonBinary.pathString)