From 53bf4dffa6b9b8e37b8cf8d7deb8b7b28e70116d Mon Sep 17 00:00:00 2001 From: Oleksandr Karpovich Date: Thu, 20 Jun 2024 12:09:34 +0200 Subject: [PATCH] Make sure the web app distribution doesn't contain a duplicate skiko.wasm (#4958) https://youtrack.jetbrains.com/issue/CMP-1114 **Testing:** - changed an existing test to test where added a new check for the content of the app distribution --- .../web/internal/configureWebApplication.kt | 48 ++++++++----------- .../tests/integration/GradlePluginTest.kt | 29 +++++++++-- .../test-projects/misc/skikoWasm/build.gradle | 8 ++-- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt index 2c163824fc..79b68b8227 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt @@ -13,12 +13,11 @@ import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.provider.Provider import org.jetbrains.compose.ComposeBuildConfig import org.jetbrains.compose.ComposeExtension -import org.jetbrains.compose.web.tasks.UnpackSkikoWasmRuntimeTask -import org.jetbrains.compose.internal.utils.* +import org.jetbrains.compose.internal.utils.detachedComposeDependency import org.jetbrains.compose.internal.utils.registerTask -import org.jetbrains.compose.internal.utils.uppercaseFirstChar import org.jetbrains.compose.web.WebExtension -import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import org.jetbrains.compose.web.tasks.UnpackSkikoWasmRuntimeTask +import org.jetbrains.kotlin.gradle.tasks.IncrementalSyncTask internal fun Project.configureWeb( composeExt: ComposeExtension, @@ -48,11 +47,12 @@ internal fun Project.configureWeb( } // configure only if there is k/wasm or k/js target: - webExt.targetsToConfigure(project) - .configureWebApplication(project, shouldRunUnpackSkiko) + if (webExt.targetsToConfigure(project).isNotEmpty()) { + configureWebApplication(project, shouldRunUnpackSkiko) + } } -internal fun Collection.configureWebApplication( +internal fun configureWebApplication( project: Project, shouldRunUnpackSkiko: Provider ) { @@ -63,28 +63,22 @@ internal fun Collection.configureWebApplication( skikoJsWasmRuntimeConfiguration.defaultDependencies { it.addLater(skikoJsWasmRuntimeDependency) } - forEach { - val mainCompilation = it.compilations.getByName("main") - val testCompilation = it.compilations.getByName("test") - val unpackedRuntimeDir = project.layout.buildDirectory.dir("compose/skiko-wasm/${it.targetName}") - val taskName = "unpackSkikoWasmRuntime${it.targetName.uppercaseFirstChar()}" - mainCompilation.defaultSourceSet.resources.srcDir(unpackedRuntimeDir) - testCompilation.defaultSourceSet.resources.srcDir(unpackedRuntimeDir) - - val unpackRuntime = project.registerTask(taskName) { - onlyIf { - shouldRunUnpackSkiko.get() - } - skikoRuntimeFiles = skikoJsWasmRuntimeConfiguration - outputDir.set(unpackedRuntimeDir) - } - project.tasks.named(mainCompilation.processResourcesTaskName).configure { processResourcesTask -> - processResourcesTask.dependsOn(unpackRuntime) - } - project.tasks.named(testCompilation.processResourcesTaskName).configure { processResourcesTask -> - processResourcesTask.dependsOn(unpackRuntime) + val unpackedRuntimeDir = project.layout.buildDirectory.dir("compose/skiko-wasm") + val taskName = "unpackSkikoWasmRuntime" + + val unpackRuntime = project.registerTask(taskName) { + onlyIf { + shouldRunUnpackSkiko.get() } + + skikoRuntimeFiles = skikoJsWasmRuntimeConfiguration + outputDir.set(unpackedRuntimeDir) + } + + project.tasks.withType(IncrementalSyncTask::class.java) { + it.dependsOn(unpackRuntime) + it.from.from(unpackedRuntimeDir) } } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt index 2315dc9119..866e46c945 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt @@ -5,13 +5,13 @@ package org.jetbrains.compose.test.tests.integration +import org.gradle.internal.impldep.junit.framework.TestCase.assertEquals +import org.gradle.internal.impldep.junit.framework.TestCase.assertTrue import org.gradle.util.GradleVersion import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.PreviewLogger import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.RemoteConnection import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.receiveConfigFromGradle -import org.jetbrains.compose.test.utils.GradlePluginTestBase -import org.jetbrains.compose.test.utils.TestProjects -import org.jetbrains.compose.test.utils.TestProperties +import org.jetbrains.compose.test.utils.* import org.jetbrains.compose.test.utils.checks import org.junit.jupiter.api.Assumptions import org.junit.jupiter.api.Test @@ -21,11 +21,16 @@ import java.net.SocketTimeoutException import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicInteger import kotlin.concurrent.thread +import kotlin.test.assertFalse class GradlePluginTest : GradlePluginTestBase() { @Test fun skikoWasm() = with( - testProject(TestProjects.skikoWasm) + testProject( + TestProjects.skikoWasm, + // TODO: enable the configuration cache after moving all test projects to kotlin 2.0 or newer + defaultTestEnvironment.copy(useGradleConfigurationCache = false) + ) ) { fun jsCanvasEnabled(value: Boolean) { modifyGradleProperties { put("org.jetbrains.compose.experimental.jscanvas.enabled", value.toString()) } @@ -39,8 +44,22 @@ class GradlePluginTest : GradlePluginTestBase() { jsCanvasEnabled(true) gradle(":build").checks { - check.taskSuccessful(":unpackSkikoWasmRuntimeJs") + check.taskSuccessful(":unpackSkikoWasmRuntime") check.taskSuccessful(":compileKotlinJs") + check.taskSuccessful(":compileKotlinWasmJs") + check.taskSuccessful(":wasmJsBrowserDistribution") + + file("./build/dist/wasmJs/productionExecutable").apply { + checkExists() + assertTrue(isDirectory) + val distributionFiles = listFiles()!!.map { it.name }.toList() + assertFalse( + distributionFiles.contains("skiko.wasm"), + "skiko.wasm is probably a duplicate" + ) + // one file is the app wasm file and another one is skiko wasm file with a mangled name + assertEquals(2, distributionFiles.filter { it.endsWith(".wasm") }.size) + } } } diff --git a/gradle-plugins/compose/src/test/test-projects/misc/skikoWasm/build.gradle b/gradle-plugins/compose/src/test/test-projects/misc/skikoWasm/build.gradle index c6583d3c0a..dc861c0809 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/skikoWasm/build.gradle +++ b/gradle-plugins/compose/src/test/test-projects/misc/skikoWasm/build.gradle @@ -10,6 +10,10 @@ kotlin { browser() binaries.executable() } + wasm { + browser() + binaries.executable() + } sourceSets { commonMain { dependencies { @@ -22,10 +26,6 @@ kotlin { } } -compose.experimental { - web.application {} -} - // test for https://github.com/JetBrains/compose-multiplatform/issues/3169 afterEvaluate { afterEvaluate {