[eel-vcs] using eel external cli api:

add a helper method in the base class

GitOrigin-RevId: 2bb99e819515fa8099fc6b7e7f3c9de4d3bf7269
This commit is contained in:
Mihail Buryakov
2025-05-30 01:05:23 +03:00
committed by intellij-monorepo-bot
parent a2cc34426a
commit c3a9fe8834
4 changed files with 76 additions and 3 deletions

View File

@@ -25,6 +25,8 @@ jvm_library(
"//platform/platform-util-netty:ide-util-netty",
"@lib//:netty-codec-http",
"@lib//:netty-buffer",
"//platform/eel",
"//platform/eel-provider",
],
exports = ["//platform/built-in-server:builtInServer-impl"],
runtime_deps = [":external-process-auth-helper_resources"]
@@ -50,6 +52,8 @@ jvm_library(
"@lib//:netty-codec-http",
"@lib//:netty-buffer",
"@lib//:junit5",
"//platform/eel",
"//platform/eel-provider",
],
runtime_deps = [":external-process-auth-helper_resources"]
)

View File

@@ -15,6 +15,7 @@ f:com.intellij.externalProcessAuthHelper.ExternalProcessAuthHelperBundle
- s:messagePointer(java.lang.String,java.lang.Object[]):java.util.function.Supplier
a:com.intellij.externalProcessAuthHelper.ExternalProcessHandlerService
- <init>(java.lang.String,java.lang.Class):V
- <init>(java.lang.String,java.lang.Class,externalApp.ExternalCli,java.util.List,kotlinx.coroutines.CoroutineScope):V
- f:getCallbackScriptPath(java.lang.String,com.intellij.externalProcessAuthHelper.ScriptGenerator,Z):java.io.File
- f:getIdePort():I
- pa:handleRequest(externalApp.ExternalAppHandler,java.lang.String):java.lang.String

View File

@@ -22,5 +22,7 @@
<orderEntry type="library" name="netty-codec-http" level="project" />
<orderEntry type="library" name="netty-buffer" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit5" level="project" />
<orderEntry type="module" module-name="intellij.platform.eel" />
<orderEntry type="module" module-name="intellij.platform.eel.provider" />
</component>
</module>

View File

@@ -6,23 +6,41 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.EmptyProgressIndicator
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.runBlockingMaybeCancellable
import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.Disposer
import com.intellij.platform.eel.EelApi
import com.intellij.platform.eel.EelExecApi
import com.intellij.platform.eel.provider.asNioPath
import com.intellij.platform.eel.provider.utils.asOutputStream
import com.intellij.util.cancelOnDispose
import com.intellij.util.concurrency.AppExecutorUtil
import com.intellij.util.io.readUtf8
import externalApp.ExternalApp
import externalApp.ExternalAppEntry
import externalApp.ExternalAppHandler
import externalApp.ExternalCli
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.http.*
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.HttpMethod
import io.netty.handler.codec.http.HttpResponseStatus
import io.netty.handler.codec.http.QueryStringDecoder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.NonNls
import org.jetbrains.ide.*
import org.jetbrains.ide.BuiltInServerManager
import org.jetbrains.ide.RestService
import org.jetbrains.io.response
import java.io.File
import java.io.IOException
import java.io.PrintStream
import java.nio.charset.StandardCharsets
import java.nio.file.Path
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentHashMap
import kotlin.io.path.pathString
/**
* The provider of external application scripts called by Git when a remote operation needs communication with the user.
@@ -37,9 +55,16 @@ import java.util.concurrent.ConcurrentHashMap
*/
abstract class ExternalProcessHandlerService<T : ExternalAppHandler>(
private val scriptNamePrefix: @NonNls String,
private val scriptMainClass: Class<out ExternalApp>
private val scriptMainClass: Class<out ExternalApp>,
private val scriptBody: ExternalCli?,
private val requiredEnvVariables: List<String>,
private val coroutineScope: CoroutineScope?
) {
@Deprecated("Use constructor with scriptMainInstance")
constructor(scriptNamePrefix: String, scriptMainClass: Class<out ExternalApp>) :
this(scriptNamePrefix, scriptMainClass, null, emptyList(), null)
private val scriptPaths = HashMap<@NonNls String, File>()
private val SCRIPT_FILE_LOCK = Any()
@@ -69,6 +94,47 @@ abstract class ExternalProcessHandlerService<T : ExternalAppHandler>(
}
}
/**
* Get file to the script service
*
* @return path to the script
*/
@Throws(IOException::class)
@ApiStatus.Internal
fun getCallbackScriptPath(eelApi: EelApi, useBatchFile: Boolean, disposable: Disposable): Path {
if (scriptBody == null || coroutineScope == null) throw UnsupportedOperationException("Handler ${this.javaClass} doesn't support eel external cli.")
return runBlockingMaybeCancellable {
val script = eelApi.exec.createExternalCli(object : EelExecApi.LocalExternalCliOptions {
override val mainClass = scriptMainClass
override val useBatchFile = useBatchFile
override val filePrefix = scriptNamePrefix
override val envVariablesToCapture = requiredEnvVariables
})
coroutineScope.launch {
script.consumeInvocations { process ->
process.toExternalAppEntry().use { externalAppEntry ->
scriptBody.entryPoint(externalAppEntry)
}
}
}.cancelOnDispose(disposable)
script.path.asNioPath()
}
}
private class EelExternalAppEntry(val process: EelExecApi.ExternalCliProcess) : ExternalAppEntry, AutoCloseable {
val myStderr: PrintStream = process.stderr.asOutputStream().let(::PrintStream)
override fun getArgs(): Array<out String> = process.args.toTypedArray()
override fun getEnvironment(): Map<String, String> = process.environment
override fun getWorkingDirectory(): String = process.workingDir.asNioPath().pathString
override fun getStderr(): PrintStream = myStderr
override fun close() {
stderr.close()
}
}
private fun EelExecApi.ExternalCliProcess.toExternalAppEntry() = EelExternalAppEntry(this)
fun registerHandler(handler: T, disposable: Disposable): UUID {
val key: UUID = UUID.randomUUID()
handlers[key] = handler