Browse Source

Merge compose.desktop.application plugin with compose plugin

This change removes `org.jetbrains.compose.desktop.application` plugin id
in favor of doing everything in `org.jetbrains.compose`.
The change simplifies configuring Compose Desktop projects.
Now, just one plugin dependency is needed.

To avoid task name conflicts with common task names such as `package` and `run`,
the plugin creates tasks lazily only if `application` block/property is used in a script.
pull/45/head
Alexey Tsvetkov 4 years ago
parent
commit
3b7835fb4a
  1. 4
      examples/imageviewer/build.gradle.kts
  2. 1
      examples/imageviewer/desktop/build.gradle.kts
  3. 47
      gradle-plugins/compose-desktop-application/build.gradle.kts
  4. 10
      gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/ComposeBasePlugin.kt
  5. 14
      gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/DesktopBasePlugin.kt
  6. 5
      gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt
  7. 30
      gradle-plugins/compose/build.gradle.kts
  8. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeExtension.kt
  9. 11
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt
  10. 20
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt
  11. 5
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/Application.kt
  12. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/ConfigurationSource.kt
  13. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/NativeDistributions.kt
  14. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/PlatformSettings.kt
  15. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/TargetFormat.kt
  16. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/cliArgUtils.kt
  17. 42
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt
  18. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/dslUtils.kt
  19. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/osUtils.kt
  20. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt
  21. 0
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt
  22. 3
      gradle-plugins/settings.gradle.kts
  23. 12
      tutorials/Native_distributions_and_local_execution/README.md

4
examples/imageviewer/build.gradle.kts

@ -1,5 +1,8 @@
buildscript { buildscript {
repositories { repositories {
mavenLocal().mavenContent {
includeModule("org.jetbrains.compose", "compose-gradle-plugin")
}
google() google()
jcenter() jcenter()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
@ -7,7 +10,6 @@ buildscript {
dependencies { dependencies {
classpath("org.jetbrains.compose:compose-gradle-plugin:0.1.0-m1-build57") classpath("org.jetbrains.compose:compose-gradle-plugin:0.1.0-m1-build57")
classpath("org.jetbrains.compose:compose-desktop-application-gradle-plugin:0.1.0-m1-build57")
classpath("com.android.tools.build:gradle:4.0.1") classpath("com.android.tools.build:gradle:4.0.1")
classpath(kotlin("gradle-plugin", version = "1.4.0")) classpath(kotlin("gradle-plugin", version = "1.4.0"))
} }

1
examples/imageviewer/desktop/build.gradle.kts

@ -4,7 +4,6 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins { plugins {
kotlin("multiplatform") // kotlin("jvm") doesn't work well in IDEA/AndroidStudio (https://github.com/JetBrains/compose-jb/issues/22) kotlin("multiplatform") // kotlin("jvm") doesn't work well in IDEA/AndroidStudio (https://github.com/JetBrains/compose-jb/issues/22)
id("org.jetbrains.compose") id("org.jetbrains.compose")
id("org.jetbrains.compose.desktop.application")
} }
kotlin { kotlin {

47
gradle-plugins/compose-desktop-application/build.gradle.kts

@ -1,47 +0,0 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
kotlin("jvm")
id("com.gradle.plugin-publish")
id("java-gradle-plugin")
id("maven-publish")
id("com.github.johnrengelman.shadow") version "6.1.0"
}
gradlePluginConfig {
pluginId = "org.jetbrains.compose.desktop.application"
artifactId = "compose-desktop-application-gradle-plugin"
displayName = "JetBrains Compose Desktop Application Plugin"
description = "Plugin for creating native distributions and run configurations"
implementationClass = "org.jetbrains.compose.desktop.application.ApplicationPlugin"
}
val embedded by configurations.creating
dependencies {
fun embeddedCompileOnly(dep: String) {
compileOnly(dep)
embedded(dep)
}
compileOnly(gradleApi())
compileOnly(kotlin("gradle-plugin-api"))
compileOnly(kotlin("gradle-plugin"))
// include relocated download task to avoid potential runtime conflicts
embeddedCompileOnly("de.undercouch:gradle-download-task:4.1.1")
}
val shadow = tasks.named<ShadowJar>("shadowJar") {
val fromPackage = "de.undercouch"
val toPackage = "org.jetbrains.compose.$fromPackage"
relocate(fromPackage, toPackage)
archiveClassifier.set("shadow")
configurations = listOf(embedded)
exclude("META-INF/gradle-plugins/de.undercouch.download.properties")
}
val jar = tasks.named<Jar>("jar") {
dependsOn(shadow)
from(zipTree(shadow.get().archiveFile))
this.duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

10
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/ComposeBasePlugin.kt

@ -1,10 +0,0 @@
package org.jetbrains.compose
import org.gradle.api.Plugin
import org.gradle.api.Project
open class ComposeBasePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.extensions.create("compose", ComposeExtension::class.java)
}
}

14
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/DesktopBasePlugin.kt

@ -1,14 +0,0 @@
package org.jetbrains.compose.desktop
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.jetbrains.compose.ComposeBasePlugin
import org.jetbrains.compose.ComposeExtension
open class DesktopBasePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.plugins.apply(ComposeBasePlugin::class.java)
val composeExt = project.extensions.getByType(ComposeExtension::class.java)
composeExt.extensions.create("desktop", DesktopExtension::class.java)
}
}

5
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt

@ -1,5 +0,0 @@
package org.jetbrains.compose.desktop
import org.gradle.api.plugins.ExtensionAware
abstract class DesktopExtension : ExtensionAware

30
gradle-plugins/compose/build.gradle.kts

@ -1,9 +1,12 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("de.fuerstenau.buildconfig") id("de.fuerstenau.buildconfig")
id("com.gradle.plugin-publish") id("com.gradle.plugin-publish")
id("java-gradle-plugin") id("java-gradle-plugin")
id("maven-publish") id("maven-publish")
id("com.github.johnrengelman.shadow") version "6.1.0"
} }
gradlePluginConfig { gradlePluginConfig {
@ -20,9 +23,34 @@ buildConfig {
buildConfigField("String", "composeVersion", BuildProperties.composeVersion) buildConfigField("String", "composeVersion", BuildProperties.composeVersion)
} }
val embedded by configurations.creating
dependencies { dependencies {
compileOnly(gradleApi()) compileOnly(gradleApi())
compileOnly(localGroovy()) compileOnly(localGroovy())
compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin") compileOnly(kotlin("gradle-plugin-api"))
compileOnly(kotlin("gradle-plugin"))
testImplementation(gradleTestKit()) testImplementation(gradleTestKit())
fun embeddedCompileOnly(dep: String) {
compileOnly(dep)
embedded(dep)
}
// include relocated download task to avoid potential runtime conflicts
embeddedCompileOnly("de.undercouch:gradle-download-task:4.1.1")
}
val shadow = tasks.named<ShadowJar>("shadowJar") {
val fromPackage = "de.undercouch"
val toPackage = "org.jetbrains.compose.$fromPackage"
relocate(fromPackage, toPackage)
archiveClassifier.set("shadow")
configurations = listOf(embedded)
exclude("META-INF/gradle-plugins/de.undercouch.download.properties")
}
val jar = tasks.named<Jar>("jar") {
dependsOn(shadow)
from(zipTree(shadow.get().archiveFile))
this.duplicatesStrategy = DuplicatesStrategy.INCLUDE
} }

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/ComposeExtension.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeExtension.kt

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

@ -5,6 +5,8 @@ package org.jetbrains.compose
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.dsl.DependencyHandler
import org.jetbrains.compose.desktop.DesktopExtension
import org.jetbrains.compose.desktop.application.internal.configureApplicationImpl
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@ -12,7 +14,16 @@ private val composeVersion get() = ComposeBuildConfig.composeVersion
class ComposePlugin : Plugin<Project> { class ComposePlugin : Plugin<Project> {
override fun apply(project: Project) { override fun apply(project: Project) {
val composeExtension = project.extensions.create("compose", ComposeExtension::class.java)
val desktopExtension = composeExtension.extensions.create("desktop", DesktopExtension::class.java)
project.afterEvaluate { project.afterEvaluate {
if (desktopExtension._isApplicationInitialized) {
// If application object was not accessed in a script,
// we want to avoid creating tasks like package, run, etc. to avoid conflicts with other plugins
configureApplicationImpl(project, desktopExtension.application)
}
project.dependencies.add( project.dependencies.add(
"kotlinCompilerPluginClasspath", "kotlinCompilerPluginClasspath",
"org.jetbrains.compose.compiler:compiler:$composeVersion" "org.jetbrains.compose.compiler:compiler:$composeVersion"

20
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt

@ -0,0 +1,20 @@
package org.jetbrains.compose.desktop
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.ExtensionAware
import org.jetbrains.compose.desktop.application.dsl.Application
import javax.inject.Inject
abstract class DesktopExtension @Inject constructor(private val objectFactory: ObjectFactory) : ExtensionAware {
internal var _isApplicationInitialized = false
private set
val application: Application by lazy {
_isApplicationInitialized = true
objectFactory.newInstance(Application::class.java, "main")
}
fun application(fn: Application.() -> Unit) {
application.fn()
}
}

5
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/Application.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/Application.kt

@ -16,6 +16,9 @@ open class Application @Inject constructor(
objects: ObjectFactory objects: ObjectFactory
) { ) {
internal var _configurationSource: ConfigurationSource? = null internal var _configurationSource: ConfigurationSource? = null
private set
internal var _isDefaultConfigurationEnabled = true
private set
internal val _fromFiles = objects.fileCollection() internal val _fromFiles = objects.fileCollection()
internal val _dependenciesTaskNames = ArrayList<String>() internal val _dependenciesTaskNames = ArrayList<String>()
@ -28,7 +31,7 @@ open class Application @Inject constructor(
_configurationSource = ConfigurationSource.KotlinMppTarget(from) _configurationSource = ConfigurationSource.KotlinMppTarget(from)
} }
fun disableDefaultConfiguration() { fun disableDefaultConfiguration() {
_configurationSource = null _isDefaultConfigurationEnabled = false
} }
fun fromFiles(vararg files: Any) { fun fromFiles(vararg files: Any) {

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/ConfigurationSource.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/ConfigurationSource.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/NativeDistributions.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/NativeDistributions.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/PlatformSettings.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/PlatformSettings.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/TargetFormat.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/TargetFormat.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/cliArgUtils.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/cliArgUtils.kt

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

@ -1,49 +1,33 @@
package org.jetbrains.compose.desktop.application package org.jetbrains.compose.desktop.application.internal
import org.gradle.api.* import org.gradle.api.*
import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.compose.ComposeExtension
import org.jetbrains.compose.desktop.DesktopBasePlugin
import org.jetbrains.compose.desktop.DesktopExtension
import org.jetbrains.compose.desktop.application.dsl.Application import org.jetbrains.compose.desktop.application.dsl.Application
import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.compose.desktop.application.internal.OS
import org.jetbrains.compose.desktop.application.internal.configureWix
import org.jetbrains.compose.desktop.application.internal.currentOS
import org.jetbrains.compose.desktop.application.internal.provider
import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import java.io.File import java.io.File
import java.util.* import java.util.*
private const val PLUGIN_ID = "org.jetbrains.compose.desktop.application"
// todo: multiple launchers // todo: multiple launchers
// todo: file associations // todo: file associations
// todo: use workers // todo: use workers
@Suppress("unused") // Gradle plugin entry point fun configureApplicationImpl(project: Project, app: Application) {
open class ApplicationPlugin : Plugin<Project> { project.afterEvaluate {
override fun apply(project: Project) { if (app._isDefaultConfigurationEnabled) {
project.plugins.apply(DesktopBasePlugin::class.java) if (project.plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) {
val composeExt = project.extensions.getByType(ComposeExtension::class.java) project.configureFromMppPlugin(app)
val desktopExt = composeExt.extensions.getByType(DesktopExtension::class.java) } else if (project.plugins.hasPlugin("org.jetbrains.kotlin.jvm")) {
val mainApplication = project.objects.newInstance(Application::class.java, "main") val mainSourceSet = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.getByName("main")
desktopExt.extensions.add("application", mainApplication) app.from(mainSourceSet)
project.plugins.withId("org.jetbrains.kotlin.jvm") { }
val mainSourceSet = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.getByName("main")
mainApplication.from(mainSourceSet)
}
project.plugins.withId("org.jetbrains.kotlin.multiplatform") {
project.configureFromMppPlugin(mainApplication)
}
project.afterEvaluate {
project.configurePackagingTasks(listOf(mainApplication))
project.configureWix()
} }
project.configurePackagingTasks(listOf(app))
project.configureWix()
} }
} }
@ -56,7 +40,7 @@ internal fun Project.configureFromMppPlugin(mainApplication: Application) {
mainApplication.from(target) mainApplication.from(target)
isJvmTargetConfigured = true isJvmTargetConfigured = true
} else { } else {
logger.error("w: Default configuration for '$PLUGIN_ID' is disabled: " + logger.error("w: Default configuration for Compose Desktop Application is disabled: " +
"multiple Kotlin JVM targets definitions are detected. " + "multiple Kotlin JVM targets definitions are detected. " +
"Specify, which target to use by using `compose.desktop.application.from(kotlinMppTarget)`") "Specify, which target to use by using `compose.desktop.application.from(kotlinMppTarget)`")
mainApplication.disableDefaultConfiguration() mainApplication.disableDefaultConfiguration()

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/dslUtils.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/dslUtils.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/osUtils.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/osUtils.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt

0
gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt

3
gradle-plugins/settings.gradle.kts

@ -5,5 +5,4 @@ pluginManagement {
} }
} }
include(":compose") include(":compose")
include(":compose-desktop-application")

12
tutorials/Native_distributions_and_local_execution/README.md

@ -5,10 +5,9 @@
In this tutorial, we'll show you how to create native distributions (installers/packages) for all the supported systems. In this tutorial, we'll show you how to create native distributions (installers/packages) for all the supported systems.
We will also demonstrate how to run an application locally with the same settings as for distributions. We will also demonstrate how to run an application locally with the same settings as for distributions.
## Desktop application Gradle plugin ## Gradle plugin
`org.jetbrains.compose.desktop.application` `org.jetbrains.compose` Gradle plugin simplifies the packaging of applications into native distributions and running an application locally.
simplifies the packaging of applications into native distributions and running an application locally.
Currently, the plugin uses [jpackage](https://openjdk.java.net/jeps/343) for packaging self-contained applications. Currently, the plugin uses [jpackage](https://openjdk.java.net/jeps/343) for packaging self-contained applications.
## Basic usage ## Basic usage
@ -26,7 +25,6 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.compose") id("org.jetbrains.compose")
id("org.jetbrains.compose.desktop.application")
} }
dependencies { dependencies {
@ -53,6 +51,8 @@ Tasks that are not compatible with the current OS are skipped by default.
aggregating all package tasks for an application. aggregating all package tasks for an application.
* `run` is used to run an app locally. You need to define a `mainClass` — an fq-name of a class, * `run` is used to run an app locally. You need to define a `mainClass` — an fq-name of a class,
containing the `main` function. containing the `main` function.
Note, that the tasks are created only if the `application` block/property is used in a script.
After a build, output binaries can be found in `${project.buildDir}/compose/binaries`. After a build, output binaries can be found in `${project.buildDir}/compose/binaries`.
@ -144,7 +144,7 @@ If the default configuration is ambiguous or not sufficient, the plugin can be c
```kotlin ```kotlin
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.compose.desktop.application") id("org.jetbrains.compose")
} }
val customSourceSet = sourceSets.create("customSourceSet") val customSourceSet = sourceSets.create("customSourceSet")
@ -158,7 +158,7 @@ compose.desktop {
```kotlin ```kotlin
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
id("org.jetbrains.compose.desktop.application") id("org.jetbrains.compose")
} }
kotlin { kotlin {

Loading…
Cancel
Save