mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[terminal] IJPL-188055 fix detecting default shell using EelApi
GitOrigin-RevId: b1fba6f92158e14a6eea100d9407c873d2689b82
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5544fd6ebd
commit
2e5cefd8e0
@@ -10,7 +10,14 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.guessProjectDir
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.NioFiles
|
||||
import com.intellij.openapi.util.text.Strings
|
||||
import com.intellij.platform.eel.EelDescriptor
|
||||
import com.intellij.platform.eel.isWindows
|
||||
import com.intellij.platform.eel.provider.LocalEelDescriptor
|
||||
import com.intellij.platform.eel.provider.getEelDescriptor
|
||||
import com.intellij.platform.eel.provider.toEelApiBlocking
|
||||
import com.intellij.platform.eel.provider.utils.fetchLoginShellEnvVariablesBlocking
|
||||
import com.intellij.util.xmlb.annotations.Property
|
||||
import org.jetbrains.plugins.terminal.settings.TerminalLocalOptions
|
||||
import java.io.File
|
||||
@@ -98,12 +105,23 @@ class TerminalProjectOptionsProvider(val project: Project) : PersistentStateComp
|
||||
}
|
||||
|
||||
private fun isProjectLevelShellPath(workingDirectory: () -> String?): Boolean {
|
||||
return SystemInfo.isWindows && findWslDistributionName(workingDirectory()) != null
|
||||
val eelDescriptor = toEelDescriptor(workingDirectory)
|
||||
return eelDescriptor !== LocalEelDescriptor
|
||||
}
|
||||
|
||||
private fun toEelDescriptor(workingDirectory: () -> String?): EelDescriptor {
|
||||
val path = workingDirectory()?.let {
|
||||
NioFiles.toPath(it)
|
||||
}
|
||||
return path?.getEelDescriptor() ?: LocalEelDescriptor
|
||||
}
|
||||
|
||||
fun defaultShellPath(): String = findDefaultShellPath { startingDirectory }
|
||||
|
||||
private fun findDefaultShellPath(workingDirectory: () -> String?): String {
|
||||
if (shouldUseEelApi()) {
|
||||
return findDefaultShellPath(toEelDescriptor(workingDirectory))
|
||||
}
|
||||
if (SystemInfo.isWindows) {
|
||||
val wslDistributionName = findWslDistributionName(workingDirectory())
|
||||
if (wslDistributionName != null) {
|
||||
@@ -128,6 +146,14 @@ class TerminalProjectOptionsProvider(val project: Project) : PersistentStateComp
|
||||
return if (directory == null) null else WslPath.parseWindowsUncPath(directory)?.distributionId
|
||||
}
|
||||
|
||||
private fun findDefaultShellPath(eelDescriptor: EelDescriptor): String {
|
||||
if (eelDescriptor.platform.isWindows) {
|
||||
return "powershell.exe"
|
||||
}
|
||||
val eelApi = eelDescriptor.toEelApiBlocking()
|
||||
return eelApi.exec.fetchLoginShellEnvVariablesBlocking()["SHELL"] ?: "/bin/sh"
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(TerminalProjectOptionsProvider::class.java)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import com.intellij.openapi.vfs.impl.wsl.WslConstants;
|
||||
import com.intellij.platform.eel.EelDescriptor;
|
||||
import com.intellij.platform.eel.EelPlatform;
|
||||
import com.intellij.platform.eel.provider.EelProviderUtil;
|
||||
import com.intellij.platform.eel.provider.LocalEelDescriptor;
|
||||
import com.intellij.platform.eel.provider.utils.EelUtilsKt;
|
||||
import com.intellij.terminal.ui.TerminalWidget;
|
||||
import com.intellij.util.EnvironmentRestorer;
|
||||
@@ -34,7 +33,10 @@ import org.jetbrains.plugins.terminal.util.TerminalEnvironment;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.plugins.terminal.LocalTerminalDirectRunner.isDirectory;
|
||||
@@ -50,7 +52,7 @@ public final class LocalOptionsConfigurer {
|
||||
String workingDir = getWorkingDirectory(baseOptions.getWorkingDirectory(), project);
|
||||
Map<String, String> envs = getTerminalEnvironment(baseOptions.getEnvVariables(), workingDir, project, eelDescriptor);
|
||||
|
||||
List<String> initialCommand = getInitialCommand(baseOptions, project, eelDescriptor);
|
||||
List<String> initialCommand = getInitialCommand(baseOptions, project);
|
||||
TerminalWidget widget = baseOptions.getWidget();
|
||||
if (widget != null) {
|
||||
widget.setShellCommand(initialCommand);
|
||||
@@ -153,11 +155,7 @@ public final class LocalOptionsConfigurer {
|
||||
return envs;
|
||||
}
|
||||
|
||||
private static @NotNull List<String> getInitialCommand(@NotNull ShellStartupOptions options, @NotNull Project project, @Nullable EelDescriptor eelDescriptor) {
|
||||
if (eelDescriptor != null && eelDescriptor != LocalEelDescriptor.INSTANCE) {
|
||||
return LocalTerminalStartCommandBuilder.convertShellPathToCommand(Optional.of(fetchLoginShellEnvVariables(eelDescriptor)).map(e -> e.get("SHELL")).orElse("/bin/sh"));
|
||||
}
|
||||
|
||||
private static @NotNull List<String> getInitialCommand(@NotNull ShellStartupOptions options, @NotNull Project project) {
|
||||
List<String> shellCommand = options.getShellCommand();
|
||||
return shellCommand != null ? shellCommand : LocalTerminalStartCommandBuilder.convertShellPathToCommand(getShellPath(project));
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.openapi.util.registry.Registry.Companion.`is`
|
||||
import com.intellij.platform.eel.EelApi
|
||||
import com.intellij.platform.eel.EelExecApi
|
||||
import com.intellij.platform.eel.ExecuteProcessException
|
||||
import com.intellij.platform.eel.provider.LocalEelDescriptor
|
||||
import com.intellij.platform.eel.provider.asEelPath
|
||||
import com.intellij.platform.eel.provider.getEelDescriptor
|
||||
import com.intellij.platform.eel.spawnProcess
|
||||
@@ -48,7 +49,7 @@ internal fun logCommonStartupInfo(
|
||||
", time to process created: ${durationBetweenStartupAndConnectorCreated.toMillis()} ms")
|
||||
}
|
||||
|
||||
@Throws(ErrnoException::class)
|
||||
@Throws(ExecuteProcessException::class)
|
||||
internal fun startProcess(
|
||||
command: List<String>,
|
||||
envs: Map<String, String>,
|
||||
@@ -63,7 +64,7 @@ internal fun startProcess(
|
||||
}
|
||||
|
||||
private suspend fun convertCommandToRemote(eelApi: EelApi, command: List<String>): List<String> {
|
||||
if (isWslCommand(command)) {
|
||||
if (eelApi.descriptor != LocalEelDescriptor && isWslCommand(command)) {
|
||||
val shell = eelApi.exec.fetchLoginShellEnvVariables()["SHELL"] ?: "/bin/sh"
|
||||
return listOf(shell, LocalTerminalDirectRunner.LOGIN_CLI_OPTION, LocalTerminalStartCommandBuilder.INTERACTIVE_CLI_OPTION)
|
||||
}
|
||||
@@ -88,9 +89,12 @@ private suspend fun getEelApi(
|
||||
val wslDistribNameFromWorkingDirectory = WslPath.parseWindowsUncPath(workingDirectory.toString())?.distributionId
|
||||
if (wslDistribNameFromCommandline != wslDistribNameFromWorkingDirectory) {
|
||||
val wslRootPath = WSLDistribution(wslDistribNameFromCommandline).getUNCRootPath()
|
||||
val eelApi = wslRootPath.getEelDescriptor().toEelApi()
|
||||
val userHome = runCatching { eelApi.exec.fetchLoginShellEnvVariables()["HOME"] }.getOrNull()
|
||||
return eelApi to wslRootPath.resolve(userHome ?: ".")
|
||||
val eelDescriptor = wslRootPath.getEelDescriptor()
|
||||
if (eelDescriptor != LocalEelDescriptor) {
|
||||
val eelApi = eelDescriptor.toEelApi()
|
||||
val userHome = runCatching { eelApi.exec.fetchLoginShellEnvVariables()["HOME"] }.getOrNull()
|
||||
return eelApi to wslRootPath.resolve(userHome ?: ".")
|
||||
}
|
||||
}
|
||||
}
|
||||
return workingDirectory.getEelDescriptor().toEelApi() to workingDirectory
|
||||
@@ -106,7 +110,7 @@ private fun getWslDistributionNameFromCommand(command: List<String>): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
@Throws(ErrnoException::class)
|
||||
@Throws(ExecuteProcessException::class)
|
||||
private suspend fun doStartProcess(
|
||||
eelApi: EelApi,
|
||||
command: List<String>,
|
||||
@@ -119,17 +123,11 @@ private suspend fun doStartProcess(
|
||||
.env(envs)
|
||||
.workingDirectory(workingDirectory.asEelPath())
|
||||
.interactionOptions(EelExecApi.Pty(initialTermSize.columns, initialTermSize.rows, true))
|
||||
return try {
|
||||
execOptions.eelIt().convertToJavaProcess() as PtyProcess
|
||||
} catch (e : ExecuteProcessException) {
|
||||
throw ErrnoException(e)
|
||||
}
|
||||
return execOptions.eelIt().convertToJavaProcess() as PtyProcess
|
||||
}
|
||||
|
||||
internal fun shouldUseEelApi(): Boolean {
|
||||
return `is`("terminal.use.EelApi", false)
|
||||
}
|
||||
|
||||
internal class ErrnoException(val error: ExecuteProcessException): Exception(error.message)
|
||||
|
||||
private val log: Logger = logger<AbstractTerminalRunner<*>>()
|
||||
|
||||
Reference in New Issue
Block a user