Browse Source

Add preview support to Gradle plugin

pull/566/head
Alexey Tsvetkov 4 years ago committed by Alexey Tsvetkov
parent
commit
b483ad4c22
  1. 34
      gradle-plugins/build.gradle.kts
  2. 14
      gradle-plugins/compose-preview-runtime/build.gradle.kts
  3. 40
      gradle-plugins/compose-preview-runtime/src/main/kotlin/org/jetbrains/compose/desktop/preview/runtime/ComposePreviewRunner.kt
  4. 3
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt
  5. 8
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt
  6. 26
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/preview/internal/configurePreview.kt
  7. 39
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/preview/tasks/AbstractRunComposePreviewTask.kt
  8. 1
      gradle-plugins/settings.gradle.kts

34
gradle-plugins/build.gradle.kts

@ -48,28 +48,36 @@ subprojects {
}
afterEvaluate {
mavenPublicationConfig?.let { mavenPublicationConfig ->
configurePublication(mavenPublicationConfig)
val publicationConfig = mavenPublicationConfig
val gradlePluginConfig = gradlePluginConfig
gradlePluginConfig?.let { gradlePluginConfig ->
configureGradlePlugin(mavenPublicationConfig, gradlePluginConfig)
if (publicationConfig != null) {
if (gradlePluginConfig != null) {
// pluginMaven is a default publication created by java-gradle-plugin
// https://github.com/gradle/gradle/issues/10384
configureMavenPublication("pluginMaven", publicationConfig)
configureGradlePlugin(publicationConfig, gradlePluginConfig)
} else {
configureMavenPublication("maven", publicationConfig) {
from(components["java"])
}
}
}
}
}
fun Project.configurePublication(
publicationConfig: MavenPublicationConfigExtension
fun Project.configureMavenPublication(
publicationName: String,
config: MavenPublicationConfigExtension,
customize: MavenPublication.() -> Unit = {}
) {
// maven publication for plugin
configureIfExists<PublishingExtension> {
// pluginMaven is a default publication created by java-gradle-plugin
// https://github.com/gradle/gradle/issues/10384
publications.create<MavenPublication>("pluginMaven") {
artifactId = publicationConfig.artifactId
publications.create<MavenPublication>(publicationName) {
artifactId = config.artifactId
pom {
name.set(publicationConfig.displayName)
description.set(publicationConfig.description)
name.set(config.displayName)
description.set(config.description)
url.set(BuildProperties.website)
licenses {
license {
@ -78,6 +86,8 @@ fun Project.configurePublication(
}
}
}
customize()
}
}
}

14
gradle-plugins/compose-preview-runtime/build.gradle.kts

@ -0,0 +1,14 @@
plugins {
kotlin("jvm")
id("maven-publish")
}
mavenPublicationConfig {
displayName = "Compose Desktop Preview Runtime"
description = "Runtime helpers for Compose Desktop Preview"
artifactId = "compose-preview-runtime-desktop"
}
dependencies {
compileOnly("org.jetbrains.kotlin:kotlin-stdlib")
}

40
gradle-plugins/compose-preview-runtime/src/main/kotlin/org/jetbrains/compose/desktop/preview/runtime/ComposePreviewRunner.kt

@ -0,0 +1,40 @@
/*
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
package org.jetbrains.compose.desktop.preview.runtime
import kotlin.reflect.KProperty1
class ComposePreviewRunner {
companion object {
private const val PREVIEW_ANNOTATION_FQ_NAME = "androidx.compose.ui.tooling.desktop.preview.Preview"
@JvmStatic
fun main(args: Array<String>) {
val classLoader = ComposePreviewRunner::class.java.classLoader
val previewFqName = args[0]
val previewClassFqName = previewFqName.substringBeforeLast(".")
val previewMethodName = previewFqName.substringAfterLast(".")
val previewClass = classLoader.loadClass(previewClassFqName)
val previewMethod = previewClass.methods.find { it.name == previewMethodName }
?: error("Could not find method '$previewMethodName' in class '${previewClass.canonicalName}'")
val content = previewMethod.invoke(previewClass)
val previewAnnotation = previewMethod.annotations.find { it.annotationClass.qualifiedName == PREVIEW_ANNOTATION_FQ_NAME }
?: error("Could not find '$PREVIEW_ANNOTATION_FQ_NAME' annotation on '$previewClassFqName#$previewMethodName'")
val environmentKClassProperty = previewAnnotation.annotationClass.members.find { it is KProperty1<*, *> && it.name == "environment" }
as KProperty1<Any, Class<*>>
val environmentClass = environmentKClassProperty.get(previewAnnotation)
val previewEnvironment = environmentClass
.getDeclaredConstructor()
.newInstance()
val showMethod = previewEnvironment.javaClass
.methods.find { it.name == "show" }
?: error("Could not find 'show' in class '${environmentClass.canonicalName}'")
showMethod.invoke(previewEnvironment, content)
}
}
}

3
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt

@ -15,6 +15,7 @@ import org.gradle.api.plugins.ExtensionAware
import org.jetbrains.compose.desktop.DesktopExtension
import org.jetbrains.compose.desktop.application.internal.configureApplicationImpl
import org.jetbrains.compose.desktop.application.internal.currentTarget
import org.jetbrains.compose.desktop.preview.internal.initializePreview
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@ -35,6 +36,8 @@ class ComposePlugin : Plugin<Project> {
}
}
project.initializePreview()
project.pluginManager.apply(ComposeCompilerKotlinSupportPlugin::class.java)
project.afterEvaluate {

8
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt

@ -17,6 +17,8 @@ import org.jetbrains.compose.desktop.application.dsl.Application
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.compose.desktop.application.internal.validation.validatePackageVersions
import org.jetbrains.compose.desktop.application.tasks.*
import org.jetbrains.compose.desktop.preview.internal.configureRunPreviewTask
import org.jetbrains.compose.desktop.preview.tasks.AbstractRunComposePreviewTask
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import java.io.File
@ -155,6 +157,10 @@ internal fun Project.configurePackagingTasks(apps: Collection<Application>) {
val run = project.tasks.composeTask<JavaExec>(taskName("run", app)) {
configureRunTask(app)
}
val runPreview = project.tasks.composeTask<AbstractRunComposePreviewTask>("runComposeDesktopPreview") {
configureRunPreviewTask(app)
}
}
}
@ -327,7 +333,7 @@ private fun File.isZipOrJar() =
name.endsWith(".jar", ignoreCase = true)
|| name.endsWith(".zip", ignoreCase = true)
private fun Application.javaHomeOrDefault(): String =
internal fun Application.javaHomeOrDefault(): String =
javaHome ?: System.getProperty("java.home")
private inline fun <reified T : Task> TaskContainer.composeTask(

26
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/preview/internal/configurePreview.kt

@ -0,0 +1,26 @@
package org.jetbrains.compose.desktop.preview.internal
import org.gradle.api.Project
import org.jetbrains.compose.composeVersion
import org.jetbrains.compose.desktop.application.dsl.Application
import org.jetbrains.compose.desktop.application.internal.javaHomeOrDefault
import org.jetbrains.compose.desktop.application.internal.provider
import org.jetbrains.compose.desktop.preview.tasks.AbstractRunComposePreviewTask
internal const val PREVIEW_RUNTIME_CLASSPATH_CONFIGURATION = "composeDesktopPreviewRuntimeClasspath"
private val COMPOSE_PREVIEW_RUNTIME_DEPENDENCY = "org.jetbrains.compose:compose-preview-runtime-desktop:$composeVersion"
fun Project.initializePreview() {
configurations.create(PREVIEW_RUNTIME_CLASSPATH_CONFIGURATION).defaultDependencies { deps ->
deps.add(dependencies.create(COMPOSE_PREVIEW_RUNTIME_DEPENDENCY))
}
}
internal fun AbstractRunComposePreviewTask.configureRunPreviewTask(app: Application) {
app._configurationSource?.let { configSource ->
dependsOn(configSource.jarTaskName)
classpath = configSource.runtimeClasspath(project)
javaHome.set(provider { app.javaHomeOrDefault() })
jvmArgs.set(provider { app.jvmArgs })
}
}

39
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/preview/tasks/AbstractRunComposePreviewTask.kt

@ -0,0 +1,39 @@
package org.jetbrains.compose.desktop.preview.tasks
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.jetbrains.compose.desktop.application.internal.javaExecutable
import org.jetbrains.compose.desktop.application.internal.notNullProperty
import org.jetbrains.compose.desktop.preview.internal.PREVIEW_RUNTIME_CLASSPATH_CONFIGURATION
import org.jetbrains.compose.desktop.tasks.AbstractComposeDesktopTask
abstract class AbstractRunComposePreviewTask : AbstractComposeDesktopTask() {
@get:InputFiles
internal lateinit var classpath: FileCollection
@get:InputFiles
internal val previewRuntimeClasspath: FileCollection
get() = project.configurations.getByName(PREVIEW_RUNTIME_CLASSPATH_CONFIGURATION)
@get:Internal
internal val javaHome: Property<String> = objects.notNullProperty<String>().apply {
set(providers.systemProperty("java.home"))
}
@get:Input
@get:Optional
internal val jvmArgs: ListProperty<String> = objects.listProperty(String::class.java)
@TaskAction
fun run() {
val target = project.findProperty("compose.desktop.preview.target") as String
execOperations.javaexec { javaExec ->
javaExec.executable = javaExecutable(javaHome.get())
javaExec.main = "org.jetbrains.compose.desktop.preview.runtime.ComposePreviewRunner"
javaExec.classpath = previewRuntimeClasspath + classpath
javaExec.args = listOf(target)
}
}
}

1
gradle-plugins/settings.gradle.kts

@ -6,3 +6,4 @@ pluginManagement {
}
include(":compose")
include(":compose-preview-runtime")
Loading…
Cancel
Save