Alexey Tsvetkov
4 years ago
committed by
Alexey Tsvetkov
8 changed files with 254 additions and 136 deletions
@ -0,0 +1,91 @@
|
||||
package org.jetbrains.compose.desktop.application.tasks |
||||
|
||||
import org.gradle.api.DefaultTask |
||||
import org.gradle.api.file.DirectoryProperty |
||||
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.process.ExecOperations |
||||
import org.gradle.process.ExecResult |
||||
import org.gradle.process.ExecSpec |
||||
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 java.io.File |
||||
import java.nio.file.Files |
||||
import javax.inject.Inject |
||||
|
||||
abstract class AbstractJvmToolOperationTask(private val toolName: String) : DefaultTask() { |
||||
@get:Inject |
||||
protected abstract val objects: ObjectFactory |
||||
@get:Inject |
||||
protected abstract val providers: ProviderFactory |
||||
@get:Inject |
||||
protected abstract val execOperations: ExecOperations |
||||
@get:Inject |
||||
protected abstract val fileOperations: FileOperations |
||||
|
||||
@get:Input |
||||
@get:Optional |
||||
val freeArgs: ListProperty<String> = objects.listProperty(String::class.java) |
||||
|
||||
@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)) |
||||
} |
||||
|
||||
protected open fun makeArgs(tmpDir: File): MutableList<String> = arrayListOf<String>().apply { |
||||
freeArgs.orNull?.forEach { add(it) } |
||||
} |
||||
protected open fun prepareWorkingDir(tmpDir: File) {} |
||||
protected open fun configureExec(exec: ExecSpec) {} |
||||
protected open fun checkResult(result: ExecResult) { |
||||
result.assertNormalExitValue() |
||||
} |
||||
|
||||
@TaskAction |
||||
fun run() { |
||||
val javaHomePath = javaHome.get() |
||||
|
||||
val jtool = File(javaHomePath).resolve("bin/${executableName(toolName)}") |
||||
check(jtool.isFile) { |
||||
"Invalid JDK: $jtool is not a file! \n" + |
||||
"Ensure JAVA_HOME or buildSettings.javaHome is set to JDK 14 or newer" |
||||
} |
||||
|
||||
fileOperations.delete(destinationDir) |
||||
val tmpDir = Files.createTempDirectory("compose-${toolName}").toFile().apply { |
||||
deleteOnExit() |
||||
} |
||||
try { |
||||
val args = makeArgs(tmpDir) |
||||
prepareWorkingDir(tmpDir) |
||||
val composeBuildDir = project.buildDir.resolve("compose").apply { mkdirs() } |
||||
val argsFile = composeBuildDir.resolve("${name}.args.txt") |
||||
argsFile.writeText(args.joinToString("\n")) |
||||
|
||||
execOperations.exec { exec -> |
||||
configureExec(exec) |
||||
exec.executable = jtool.absolutePath |
||||
exec.setArgs(listOf("@${argsFile.absolutePath}")) |
||||
}.also { checkResult(it) } |
||||
} finally { |
||||
tmpDir.deleteRecursively() |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
package org.jetbrains.compose.desktop.application.tasks |
||||
|
||||
import org.gradle.api.DefaultTask |
||||
import org.gradle.api.file.Directory |
||||
import org.gradle.api.provider.Provider |
||||
import org.gradle.api.tasks.Input |
||||
import org.gradle.api.tasks.InputDirectory |
||||
import org.gradle.api.tasks.TaskAction |
||||
import org.gradle.api.tasks.TaskProvider |
||||
import org.gradle.process.ExecOperations |
||||
import org.jetbrains.compose.desktop.application.internal.OS |
||||
import org.jetbrains.compose.desktop.application.internal.currentOS |
||||
import org.jetbrains.compose.desktop.application.internal.executableName |
||||
import org.jetbrains.compose.desktop.application.internal.ioFile |
||||
import javax.inject.Inject |
||||
|
||||
// Custom task is used instead of Exec, because Exec does not support |
||||
// lazy configuration yet. Lazy configuration is needed to |
||||
// calculate appImageDir after the evaluation of createApplicationImage |
||||
abstract class AbstractRunDistributableTask @Inject constructor( |
||||
createApplicationImage: TaskProvider<AbstractJPackageTask>, |
||||
private val execOperations: ExecOperations |
||||
) : DefaultTask() { |
||||
@get:InputDirectory |
||||
internal val appImageRootDir: Provider<Directory> = createApplicationImage.flatMap { it.destinationDir } |
||||
|
||||
@get:Input |
||||
internal val packageName: Provider<String> = createApplicationImage.flatMap { it.packageName } |
||||
|
||||
@TaskAction |
||||
fun run() { |
||||
val appDir = appImageRootDir.get().let { appImageRoot -> |
||||
val files = appImageRoot.asFile.listFiles() |
||||
|
||||
if (files == null || files.isEmpty()) { |
||||
error("Could not find application image: $appImageRoot is empty!") |
||||
} else if (files.size > 1) { |
||||
error("Could not find application image: $appImageRoot contains multiple children [${files.joinToString(", ")}]") |
||||
} else files.single() |
||||
} |
||||
val appExecutableName = executableName(packageName.get()) |
||||
val (workingDir, executable) = when (currentOS) { |
||||
OS.Linux -> appDir to "bin/$appExecutableName" |
||||
OS.Windows -> appDir to appExecutableName |
||||
OS.MacOS -> appDir.resolve("Contents") to "MacOS/$appExecutableName" |
||||
} |
||||
|
||||
execOperations.exec { spec -> |
||||
spec.workingDir(workingDir) |
||||
spec.executable(executable) |
||||
}.assertNormalExitValue() |
||||
} |
||||
} |
Loading…
Reference in new issue