From 815c0484a977c01ca62c46c5fdcc7eb5150ae0b6 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 29 Oct 2020 14:19:55 +0300 Subject: [PATCH] Download WiX toolset on Windows It is a non-optional dependency for jpackage (see "Dependencies" section of https://openjdk.java.net/jeps/343). --- .../build.gradle.kts | 27 +++++++++ .../desktop/application/ApplicationPlugin.kt | 3 +- .../application/internal/wixToolset.kt | 55 +++++++++++++++++++ .../application/tasks/AbstractJPackageTask.kt | 22 +++++++- 4 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt diff --git a/gradle-plugins/compose-desktop-application/build.gradle.kts b/gradle-plugins/compose-desktop-application/build.gradle.kts index cb94359bb1..c561130b16 100644 --- a/gradle-plugins/compose-desktop-application/build.gradle.kts +++ b/gradle-plugins/compose-desktop-application/build.gradle.kts @@ -1,8 +1,11 @@ +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 { @@ -13,8 +16,32 @@ gradlePluginConfig { 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") { + 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") { + dependsOn(shadow) + from(zipTree(shadow.get().archiveFile)) + this.duplicatesStrategy = DuplicatesStrategy.INCLUDE +} \ No newline at end of file diff --git a/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/ApplicationPlugin.kt b/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/ApplicationPlugin.kt index e284274a28..9c81a8a79c 100644 --- a/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/ApplicationPlugin.kt +++ b/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/ApplicationPlugin.kt @@ -12,6 +12,7 @@ import org.jetbrains.compose.desktop.DesktopExtension import org.jetbrains.compose.desktop.application.dsl.Application import org.jetbrains.compose.desktop.application.dsl.ConfigurationSource 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 @@ -22,7 +23,6 @@ import java.util.* private const val PLUGIN_ID = "org.jetbrains.compose.desktop.application" -// todo: fix windows // todo: multiple launchers // todo: file associations // todo: use workers @@ -43,6 +43,7 @@ open class ApplicationPlugin : Plugin { } project.afterEvaluate { project.configurePackagingTasks(listOf(mainApplication)) + project.configureWix() } } } diff --git a/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt b/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt new file mode 100644 index 0000000000..4e7e638c7f --- /dev/null +++ b/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt @@ -0,0 +1,55 @@ +package org.jetbrains.compose.desktop.application.internal + +import de.undercouch.gradle.tasks.download.Download +import org.gradle.api.Project +import org.gradle.api.tasks.Copy +import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask +import java.io.File + +internal const val DOWNLOAD_WIX_TOOLSET_TASK_NAME = "downloadWix" +internal const val UNZIP_WIX_TOOLSET_TASK_NAME = "unzipWix" +internal const val WIX_PATH_ENV_VAR = "WIX_PATH" +internal const val DOWNLOAD_WIX_PROPERTY = "compose.desktop.application.downloadWix" + +internal fun Project.configureWix() { + if (currentOS != OS.Windows) return + + val wixPath = System.getenv()[WIX_PATH_ENV_VAR] + if (wixPath != null) { + val wixDir = File(wixPath) + check(wixDir.isDirectory) { "$WIX_PATH_ENV_VAR value is not a valid directory: $wixDir" } + eachWindowsPackageTask { + wixToolsetDir.set(wixDir) + } + return + } + + if (project.findProperty(DOWNLOAD_WIX_PROPERTY) == "false") return + + val root = project.rootProject + val wixDir = root.buildDir.resolve("wixToolset") + val zipFile = wixDir.resolve("wix311.zip") + val unzipDir = wixDir.resolve("unpacked") + val download = root.tasks.maybeCreate(DOWNLOAD_WIX_TOOLSET_TASK_NAME, Download::class.java).apply { + onlyIf { !zipFile.isFile } + src("https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip") + dest(zipFile) + } + val unzip = root.tasks.maybeCreate(UNZIP_WIX_TOOLSET_TASK_NAME, Copy::class.java).apply { + dependsOn(download) + from(zipTree(zipFile)) + destinationDir = unzipDir + } + eachWindowsPackageTask { + dependsOn(unzip) + wixToolsetDir.set(unzipDir) + } +} + +private fun Project.eachWindowsPackageTask(fn: AbstractJPackageTask.() -> Unit) { + tasks.withType(AbstractJPackageTask::class.java).configureEach { packageTask -> + if (packageTask.targetOS == OS.Windows) { + packageTask.fn() + } + } +} \ No newline at end of file diff --git a/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt b/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt index f6d2e37791..064170add9 100644 --- a/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt +++ b/gradle-plugins/compose-desktop-application/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt @@ -12,6 +12,7 @@ import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.* import org.gradle.api.tasks.Optional import org.gradle.process.ExecOperations +import org.gradle.process.ExecSpec import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.internal.OS import org.jetbrains.compose.desktop.application.internal.cliArg @@ -54,6 +55,11 @@ abstract class AbstractJPackageTask @Inject constructor( set(providers.provider { logger.isDebugEnabled }.orElse(composeVerbose)) } + @get:InputDirectory + @get:Optional + /** @see internal/wixToolset.kt */ + val wixToolsetDir: DirectoryProperty = objects.directoryProperty() + @get:Input @get:Optional val installationPath: Property = objects.nullableProperty() @@ -285,12 +291,22 @@ abstract class AbstractJPackageTask @Inject constructor( val argsFile = composeBuildDir.resolve("${name}.args.txt") argsFile.writeText(args.joinToString("\n")) - execOperations.exec { - it.executable = jpackage.absolutePath - it.setArgs(listOf("@${argsFile.absolutePath}")) + execOperations.exec { exec -> + configureWixPathIfNeeded(exec) + exec.executable = jpackage.absolutePath + exec.setArgs(listOf("@${argsFile.absolutePath}")) }.assertNormalExitValue() } finally { tmpDir.deleteRecursively() } } + + private fun configureWixPathIfNeeded(exec: ExecSpec) { + if (currentOS == OS.Windows) { + val wixDir = wixToolsetDir.asFile.orNull ?: return + val wixPath = wixDir.absolutePath + val path = System.getenv("PATH") ?: "" + exec.environment("PATH", "$wixPath;$path") + } + } } \ No newline at end of file