Browse Source

Add suggestRuntimeModules task

Resolves #463
pull/517/head
Alexey Tsvetkov 4 years ago committed by Alexey Tsvetkov
parent
commit
dc428d3a22
  1. 6
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/NativeDistributions.kt
  2. 2
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/cliArgUtils.kt
  3. 12
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt
  4. 11
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/osUtils.kt
  5. 2
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractCheckNativeDistributionRuntime.kt
  6. 10
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJvmToolOperationTask.kt
  7. 76
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractSuggestModulesTask.kt
  8. 11
      gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/DesktopApplicationTest.kt

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

@ -7,6 +7,10 @@ import org.gradle.api.model.ObjectFactory
import java.util.*
import javax.inject.Inject
internal val DEFAULT_RUNTIME_MODULES = arrayOf(
"java.base", "java.desktop", "java.logging"
)
open class NativeDistributions @Inject constructor(
objects: ObjectFactory,
layout: ProjectLayout
@ -30,7 +34,7 @@ open class NativeDistributions @Inject constructor(
set(layout.buildDirectory.dir("compose/binaries"))
}
var modules = arrayListOf("java.desktop", "java.logging")
var modules = arrayListOf(*DEFAULT_RUNTIME_MODULES)
fun modules(vararg modules: String) {
this.modules.addAll(modules.toList())
}

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

@ -35,5 +35,5 @@ private fun <T : Any?> defaultToString(): (T) -> String =
"\"$asString\""
}
private fun File.normalizedPath() =
internal fun File.normalizedPath() =
if (currentOS == OS.Windows) absolutePath.replace("\\", "\\\\") else absolutePath

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

@ -63,6 +63,18 @@ internal fun Project.configurePackagingTasks(apps: Collection<Application>) {
)
}
tasks.composeTask<AbstractSuggestModulesTask>(taskName("suggestRuntimeModules", app)) {
dependsOn(checkRuntime)
javaHome.set(provider { app.javaHomeOrDefault() })
modules.set(provider { app.nativeDistributions.modules })
app._configurationSource?.let { configSource ->
dependsOn(configSource.jarTaskName)
files.from(configSource.runtimeClasspath(project))
launcherMainJar.set(app.mainJar.orElse(configSource.jarTask(project).flatMap { it.archiveFile }))
}
}
val createRuntimeImage = tasks.composeTask<AbstractJLinkTask>(
taskName("createRuntimeImage", app)
) {

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

@ -1,7 +1,9 @@
package org.jetbrains.compose.desktop.application.internal
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.compose.desktop.application.tasks.MIN_JAVA_RUNTIME_VERSION
import java.io.File
internal enum class OS(val id: String) {
@ -63,6 +65,15 @@ internal object MacUtils {
}
}
internal fun jvmToolFile(toolName: String, javaHome: Provider<String>): File {
val jtool = File(javaHome.get()).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 $MIN_JAVA_RUNTIME_VERSION or newer"
}
return jtool
}
@Internal
internal fun findOutputFileOrDir(dir: File, targetFormat: TargetFormat): File =
when (targetFormat) {

2
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractCheckNativeDistributionRuntime.kt

@ -12,7 +12,7 @@ import org.jetbrains.compose.desktop.application.internal.notNullProperty
import java.io.File
// __COMPOSE_NATIVE_DISTRIBUTIONS_MIN_JAVA_VERSION__
private const val MIN_JAVA_RUNTIME_VERSION = 15
internal const val MIN_JAVA_RUNTIME_VERSION = 15
@CacheableTask
abstract class AbstractCheckNativeDistributionRuntime : AbstractComposeDesktopTask() {

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

@ -7,10 +7,9 @@ import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.process.ExecResult
import org.gradle.process.ExecSpec
import org.gradle.work.InputChanges
import org.jetbrains.compose.desktop.application.internal.ComposeProperties
import org.jetbrains.compose.desktop.application.internal.executableName
import org.jetbrains.compose.desktop.application.internal.jvmToolFile
import org.jetbrains.compose.desktop.application.internal.ioFile
import org.jetbrains.compose.desktop.application.internal.notNullProperty
import java.io.File
@ -49,13 +48,8 @@ abstract class AbstractJvmToolOperationTask(private val toolName: String) : Abst
@TaskAction
fun run(inputChanges: InputChanges) {
initState()
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"
}
val jtool = jvmToolFile(toolName, javaHome = javaHome)
fileOperations.delete(destinationDir)
prepareWorkingDir(inputChanges)

76
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractSuggestModulesTask.kt

@ -0,0 +1,76 @@
package org.jetbrains.compose.desktop.application.tasks
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.compose.desktop.application.dsl.DEFAULT_RUNTIME_MODULES
import org.jetbrains.compose.desktop.application.internal.*
import org.jetbrains.compose.desktop.application.internal.ComposeProperties
import org.jetbrains.compose.desktop.application.internal.normalizedPath
import org.jetbrains.kotlin.konan.file.File
abstract class AbstractSuggestModulesTask : AbstractComposeDesktopTask() {
@get:Input
val javaHome: Property<String> = objects.notNullProperty<String>().apply {
set(providers.systemProperty("java.home"))
}
@get:InputFiles
val files: ConfigurableFileCollection = objects.fileCollection()
@get:InputFile
@get:PathSensitive(PathSensitivity.ABSOLUTE)
val launcherMainJar: RegularFileProperty = objects.fileProperty()
@get:Input
val modules: ListProperty<String> = objects.listProperty(String::class.java)
@get:Input
val jvmTarget: Property<String> = objects.notNullProperty(MIN_JAVA_RUNTIME_VERSION.toString())
@get:LocalState
protected val workingDir: Provider<Directory> = project.layout.buildDirectory.dir("compose/tmp/$name")
@TaskAction
fun run() {
val jtool = jvmToolFile("jdeps", javaHome = javaHome)
fileOperations.delete(workingDir)
fileOperations.mkdir(workingDir)
val args = arrayListOf<String>().apply {
add("--print-module-deps")
add("--ignore-missing-deps")
add("--multi-release")
add(jvmTarget.get())
add("--class-path")
add(files.joinToString(File.pathSeparator) { it.normalizedPath() })
add(launcherMainJar.ioFile.normalizedPath())
}
try {
runExternalTool(
tool = jtool,
args = args,
forceLogToFile = true,
processStdout = { output ->
val defaultModules = hashSetOf(*DEFAULT_RUNTIME_MODULES)
val suggestedModules = output.splitToSequence(",")
.map { it.trim() }
.filter { it.isNotBlank() && it !in defaultModules }
.toSortedSet()
val suggestion = "modules(${suggestedModules.joinToString(", ") { "\"$it\"" }})"
logger.quiet("Suggested runtime modules to include:")
logger.quiet(suggestion)
}
)
} finally {
if (!ComposeProperties.preserveWorkingDir(providers).get()) {
fileOperations.delete(workingDir)
}
}
}
}

11
gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/DesktopApplicationTest.kt

@ -170,4 +170,15 @@ class DesktopApplicationTest : GradlePluginTestBase() {
}
}
}
@Test
fun testSuggestModules() {
with(testProject(TestProjects.jvm)) {
gradle(":suggestRuntimeModules").build().checks { check ->
check.taskOutcome(":suggestRuntimeModules", TaskOutcome.SUCCESS)
check.logContains("Suggested runtime modules to include:")
check.logContains("modules(\"java.instrument\", \"jdk.unsupported\")")
}
}
}
}

Loading…
Cancel
Save