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.
296 lines
9.7 KiB
296 lines
9.7 KiB
package org.jetbrains.compose.desktop.application.tasks |
|
|
|
import org.gradle.api.DefaultTask |
|
import org.gradle.api.file.ConfigurableFileCollection |
|
import org.gradle.api.file.DirectoryProperty |
|
import org.gradle.api.file.RegularFileProperty |
|
import org.gradle.api.internal.file.FileOperations |
|
import org.gradle.api.model.ObjectFactory |
|
import org.gradle.api.provider.ListProperty |
|
import org.gradle.api.provider.Property |
|
import org.gradle.api.provider.ProviderFactory |
|
import org.gradle.api.tasks.* |
|
import org.gradle.api.tasks.Optional |
|
import org.gradle.process.ExecOperations |
|
import org.jetbrains.compose.desktop.application.dsl.TargetFormat |
|
import org.jetbrains.compose.desktop.application.internal.OS |
|
import org.jetbrains.compose.desktop.application.internal.cliArg |
|
import org.jetbrains.compose.desktop.application.internal.currentOS |
|
import org.jetbrains.compose.desktop.application.internal.notNullProperty |
|
import org.jetbrains.compose.desktop.application.internal.nullableProperty |
|
|
|
import java.io.File |
|
import java.nio.file.Files |
|
import javax.inject.Inject |
|
|
|
abstract class AbstractJPackageTask @Inject constructor( |
|
@get:Input |
|
val targetFormat: TargetFormat, |
|
private val execOperations: ExecOperations, |
|
private val fileOperations: FileOperations, |
|
objects: ObjectFactory, |
|
providers: ProviderFactory |
|
) : DefaultTask() { |
|
@get:Input |
|
internal val targetOS: OS |
|
get() = targetFormat.os |
|
|
|
@get:InputFiles |
|
val files: ConfigurableFileCollection = objects.fileCollection() |
|
|
|
@get:OutputDirectory |
|
val destinationDir: DirectoryProperty = objects.directoryProperty() |
|
|
|
@get:Internal |
|
val javaHome: Property<String> = objects.notNullProperty<String>().apply { |
|
set(providers.systemProperty("java.home")) |
|
} |
|
|
|
@get:Internal |
|
val verbose: Property<Boolean> = objects.notNullProperty<Boolean>().apply { |
|
val composeVerbose = providers |
|
.gradleProperty("compose.desktop.verbose") |
|
.map { "true".equals(it, ignoreCase = true) } |
|
set(providers.provider { logger.isDebugEnabled }.orElse(composeVerbose)) |
|
} |
|
|
|
@get:Input |
|
@get:Optional |
|
val installationPath: Property<String?> = objects.nullableProperty() |
|
|
|
@get:InputFile |
|
@get:Optional |
|
@get:PathSensitive(PathSensitivity.ABSOLUTE) |
|
val licenseFile: RegularFileProperty = objects.fileProperty() |
|
|
|
@get:InputFile |
|
@get:Optional |
|
@get:PathSensitive(PathSensitivity.ABSOLUTE) |
|
val iconFile: RegularFileProperty = objects.fileProperty() |
|
|
|
@get:Input |
|
val launcherMainClass: Property<String> = objects.notNullProperty() |
|
|
|
@get:InputFile |
|
@get:PathSensitive(PathSensitivity.ABSOLUTE) |
|
val launcherMainJar: RegularFileProperty = objects.fileProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val launcherArgs: ListProperty<String> = objects.listProperty(String::class.java) |
|
|
|
@get:Input |
|
@get:Optional |
|
val launcherJvmArgs: ListProperty<String> = objects.listProperty(String::class.java) |
|
|
|
@get:Input |
|
val packageName: Property<String> = objects.notNullProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val packageDescription: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val packageCopyright: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val packageVendor: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val packageVersion: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxShortcut: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxPackageName: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxAppRelease: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxAppCategory: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxDebMaintainer: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxMenuGroup: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val linuxRpmLicenseType: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val macPackageIdentifier: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val macPackageName: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val macBundleSigningPrefix: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val macSign: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:InputFile |
|
@get:Optional |
|
val macSigningKeychain: RegularFileProperty = objects.fileProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val macSigningKeyUserName: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winConsole: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winDirChooser: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winPerUserInstall: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winShortcut: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winMenu: Property<Boolean?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winMenuGroup: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
@get:Optional |
|
val winUpgradeUuid: Property<String?> = objects.nullableProperty() |
|
|
|
@get:Input |
|
val modules: ListProperty<String> = objects.listProperty(String::class.java) |
|
|
|
@get:Input |
|
@get:Optional |
|
val freeArgs: ListProperty<String> = objects.listProperty(String::class.java) |
|
|
|
private fun makeArgs(vararg inputDirs: File) = arrayListOf<String>().apply { |
|
for (dir in inputDirs) { |
|
cliArg("--input", dir.absolutePath) |
|
} |
|
|
|
cliArg("--type", targetFormat.id) |
|
cliArg("--dest", destinationDir.asFile.get().absolutePath) |
|
cliArg("--verbose", verbose) |
|
|
|
cliArg("--install-dir", installationPath) |
|
cliArg("--license-file", licenseFile.asFile.orNull?.absolutePath) |
|
cliArg("--icon", iconFile.asFile.orNull?.absolutePath) |
|
|
|
cliArg("--name", packageName) |
|
cliArg("--description", packageDescription) |
|
cliArg("--copyright", packageCopyright) |
|
cliArg("--app-version", packageVersion) |
|
cliArg("--vendor", packageVendor) |
|
|
|
cliArg("--main-jar", launcherMainJar.asFile.get().name) |
|
cliArg("--main-class", launcherMainClass) |
|
launcherArgs.orNull?.forEach { |
|
cliArg("--arguments", it) |
|
} |
|
launcherJvmArgs.orNull?.forEach { |
|
cliArg("--java-options", it) |
|
} |
|
|
|
when (currentOS) { |
|
OS.Linux -> { |
|
cliArg("--linux-shortcut", linuxShortcut) |
|
cliArg("--linux-package-name", linuxPackageName) |
|
cliArg("--linux-app-release", linuxAppRelease) |
|
cliArg("--linux-app-category", linuxAppCategory) |
|
cliArg("--linux-deb-maintainer", linuxDebMaintainer) |
|
cliArg("--linux-menu-group", linuxMenuGroup) |
|
cliArg("--linux-rpm-license-type", linuxRpmLicenseType) |
|
} |
|
OS.MacOS -> { |
|
cliArg("--mac-package-identifier", macPackageIdentifier) |
|
cliArg("--mac-package-name", macPackageName) |
|
cliArg("--mac-bundle-signing-prefix", macBundleSigningPrefix) |
|
cliArg("--mac-sign", macSign) |
|
cliArg("--mac-signing-keychain", macSigningKeychain.asFile.orNull) |
|
cliArg("--mac-signing-key-user-name", macSigningKeyUserName) |
|
} |
|
OS.Windows -> { |
|
cliArg("--win-console", winConsole) |
|
cliArg("--win-dir-chooser", winDirChooser) |
|
cliArg("--win-per-user-install", winPerUserInstall) |
|
cliArg("--win-shortcut", winShortcut) |
|
cliArg("--win-menu", winMenu) |
|
cliArg("--win-menu-group", winMenuGroup) |
|
cliArg("--win-upgrade-uuid", winUpgradeUuid) |
|
} |
|
} |
|
|
|
modules.get().forEach { m -> |
|
cliArg("--add-modules", m) |
|
} |
|
|
|
freeArgs.orNull?.forEach { add(it) } |
|
} |
|
|
|
@TaskAction |
|
fun run() { |
|
val javaHomePath = javaHome.get() |
|
|
|
val executableName = if (currentOS == OS.Windows) "jpackage.exe" else "jpackage" |
|
val jpackage = File(javaHomePath).resolve("bin/$executableName") |
|
check(jpackage.isFile) { |
|
"Invalid JDK: $jpackage is not a file! \n" + |
|
"Ensure JAVA_HOME or buildSettings.javaHome for '${packageName.get()}' app package is set to JDK 14 or newer" |
|
} |
|
|
|
fileOperations.delete(destinationDir) |
|
val tmpDir = Files.createTempDirectory("compose-package").toFile().apply { |
|
deleteOnExit() |
|
} |
|
try { |
|
val args = makeArgs(tmpDir) |
|
|
|
val sourceFile = launcherMainJar.get().asFile |
|
val targetFile = tmpDir.resolve(sourceFile.name) |
|
sourceFile.copyTo(targetFile) |
|
|
|
val myFiles = files |
|
fileOperations.copy { |
|
it.from(myFiles) |
|
it.into(tmpDir) |
|
} |
|
|
|
val composeBuildDir = project.buildDir.resolve("compose").apply { mkdirs() } |
|
val argsFile = composeBuildDir.resolve("${name}.args.txt") |
|
argsFile.writeText(args.joinToString("\n")) |
|
|
|
execOperations.exec { |
|
it.executable = jpackage.absolutePath |
|
it.setArgs(listOf("@${argsFile.absolutePath}")) |
|
}.assertNormalExitValue() |
|
} finally { |
|
tmpDir.deleteRecursively() |
|
} |
|
} |
|
} |