You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

128 lines
4.6 KiB

package org.jetbrains.compose.desktop.preview.tasks
import org.gradle.api.file.FileCollection
import org.gradle.api.logging.Logger as GradleLogger
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.compose.desktop.tasks.AbstractComposeDesktopTask
import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.*
import org.jetbrains.compose.internal.utils.*
import org.jetbrains.compose.internal.utils.currentTarget
import org.jetbrains.compose.internal.utils.javaExecutable
import org.jetbrains.compose.internal.utils.notNullProperty
import java.io.File
abstract class AbstractConfigureDesktopPreviewTask : AbstractComposeDesktopTask() {
@get:InputFiles
internal lateinit var previewClasspath: FileCollection
@get:Internal
internal val javaHome: Property<String> = objects.notNullProperty<String>().apply {
set(providers.systemProperty("java.home"))
}
// todo
@get:Input
@get:Optional
internal val jvmArgs: ListProperty<String> = objects.listProperty(String::class.java)
@get:Input
internal val previewTarget: Provider<String> =
project.providers.gradleProperty("compose.desktop.preview.target")
@get:Input
internal val idePort: Provider<String> =
project.providers.gradleProperty("compose.desktop.preview.ide.port")
@get:InputFiles
internal val uiTooling: FileCollection =
project.detachedComposeDependency(
groupId = "org.jetbrains.compose.ui",
artifactId = "ui-tooling-desktop",
).excludeTransitiveDependencies()
@get:InputFiles
internal val hostClasspath: FileCollection =
project.detachedComposeGradleDependency(artifactId = "preview-rpc")
@TaskAction
fun run() {
val hostConfig = PreviewHostConfig(
javaExecutable = javaExecutable(javaHome.get()),
hostClasspath = hostClasspath.files.asSequence().pathString()
)
val previewClasspathString =
(previewClasspath.files.asSequence() +
uiTooling.files.asSequence() +
tryGetSkikoRuntimeFilesIfNeeded().asSequence()
).pathString()
val gradleLogger = logger
val previewLogger = GradlePreviewLoggerAdapter(gradleLogger)
val connection = getLocalConnectionOrNull(idePort.get().toInt(), previewLogger, onClose = {})
if (connection != null) {
connection.use {
connection.sendConfigFromGradle(
hostConfig,
previewClasspath = previewClasspathString,
previewFqName = previewTarget.get()
)
}
} else {
gradleLogger.error("Could not connect to IDE")
}
}
private fun tryGetSkikoRuntimeFilesIfNeeded(): Collection<File> {
try {
var hasSkikoJvm = false
var hasSkikoJvmRuntime = false
var skikoVersion: String? = null
for (file in previewClasspath.files) {
if (file.name.endsWith(".jar")) {
if (file.name.startsWith("skiko-awt-runtime-")) {
hasSkikoJvmRuntime = true
continue
} else if (file.name.startsWith("skiko-awt-")) {
hasSkikoJvm = true
skikoVersion = file.name
.removePrefix("skiko-awt-")
.removeSuffix(".jar")
}
}
}
if (hasSkikoJvmRuntime) return emptyList()
if (hasSkikoJvm && !skikoVersion.isNullOrBlank()) {
val skikoRuntimeConfig = project.detachedDependency(
groupId = "org.jetbrains.skiko",
artifactId = "skiko-awt-runtime-${currentTarget.id}",
version = skikoVersion
).excludeTransitiveDependencies()
return skikoRuntimeConfig.files
}
} catch (e: Exception) {
// OK
}
return emptyList()
}
private fun Sequence<File>.pathString(): String =
joinToString(File.pathSeparator) { it.absolutePath }
private class GradlePreviewLoggerAdapter(
private val logger: GradleLogger
) : PreviewLogger() {
// todo: support compose.verbose
override val isEnabled: Boolean
get() = logger.isDebugEnabled
override fun log(s: String) {
logger.info("Compose Preview: $s")
}
}
}