Browse Source

Update gradle plugin: Deprecate experimental configuration for Compose for Web (#4796)

Since 1.6.10 Compose for Web goes to Alpha and experimental
configuration is not needed anymore. We'll configure the web targets by
default when they're added to projects.


## Testing
- I built the plugin to mavenLocal. And used it in a couple of our
samples.
- After gradle sync completes, I observe the Deprecation warning in
build.gradle.kts on `compose.experimental.web` usages (see a screenshot
below)
<img width="1022" alt="Screenshot 2024-05-10 at 15 41 14"
src="https://github.com/JetBrains/compose-multiplatform/assets/7372778/e8ede073-8d34-4dd7-ae74-c83ca0ff5c96">


Then I remove deprecated API usages and test that the project works
without it:
- run `./gradlew clean` just in case
- run the app: `./gradlew wasmJsBrowserRun` and `./gradlew jsBrowserRun`
- both run fine
- build the production distribution: `./gradlew
wasmJsBrowserDistribution`
- `cd ..../build/dist/wasmJs/productionExecutable` and run `python -m
http.server`, open a browser at `http://localhost:8000` - the app should
work the same way it works with gradle tasks above

<!-- Optional -->
This should be tested by QA

## Release Notes

### Highlights - Web
- Compose for Web goes to Alpha!
Some experimental Compose Multiplatform Gradle plugin APIs for web app
configuration were deprecated. Their usage is not required anymore.
pull/4819/head
Oleksandr Karpovich 6 months ago committed by GitHub
parent
commit
885ea3da2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt
  2. 8
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/dsl/ExperimentalExtension.kt
  3. 3
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/dsl/ExperimentalWebApplication.kt
  4. 9
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/dsl/ExperimentalWebExtension.kt
  5. 1
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt
  6. 24
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/configureExperimental.kt
  7. 48
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/web/tasks/ExperimentalUnpackSkikoWasmRuntimeTask.kt
  8. 10
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/dsl/WebApplication.kt
  9. 23
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt
  10. 50
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/tasks/UnpackSkikoWasmRuntimeTask.kt

3
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt

@ -27,6 +27,7 @@ import org.jetbrains.compose.internal.utils.currentTarget
import org.jetbrains.compose.resources.ResourcesExtension import org.jetbrains.compose.resources.ResourcesExtension
import org.jetbrains.compose.resources.configureComposeResources import org.jetbrains.compose.resources.configureComposeResources
import org.jetbrains.compose.web.WebExtension import org.jetbrains.compose.web.WebExtension
import org.jetbrains.compose.web.internal.configureWeb
import org.jetbrains.kotlin.com.github.gundy.semver4j.SemVer import org.jetbrains.kotlin.com.github.gundy.semver4j.SemVer
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
@ -65,7 +66,7 @@ abstract class ComposePlugin : Plugin<Project> {
project.afterEvaluate { project.afterEvaluate {
configureDesktop(project, desktopExtension) configureDesktop(project, desktopExtension)
project.configureExperimental(composeExtension, experimentalExtension) project.configureWeb(composeExtension)
project.plugins.withId(KOTLIN_MPP_PLUGIN_ID) { project.plugins.withId(KOTLIN_MPP_PLUGIN_ID) {
val mppExt = project.mppExt val mppExt = project.mppExt
project.configureExperimentalTargetsFlagsCheck(mppExt) project.configureExperimentalTargetsFlagsCheck(mppExt)

8
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/dsl/ExperimentalExtension.kt

@ -12,7 +12,15 @@ import javax.inject.Inject
abstract class ExperimentalExtension @Inject constructor( abstract class ExperimentalExtension @Inject constructor(
objects: ObjectFactory objects: ObjectFactory
) { ) {
@Deprecated(
message = "Starting from 1.6.10, Compose for Web goes to Alpha. Experimental configuration is not needed anymore.",
)
val web: ExperimentalWebExtension = objects.newInstance(ExperimentalWebExtension::class.java) val web: ExperimentalWebExtension = objects.newInstance(ExperimentalWebExtension::class.java)
@Deprecated(
message = "Starting from 1.6.10, Compose for Web goes to Alpha. Experimental configuration is not needed anymore."
)
fun web(action: Action<ExperimentalWebExtension>) { fun web(action: Action<ExperimentalWebExtension>) {
action.execute(web) action.execute(web)
} }

3
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/dsl/ExperimentalWebApplication.kt

@ -7,6 +7,9 @@ package org.jetbrains.compose.experimental.dsl
import javax.inject.Inject import javax.inject.Inject
@Deprecated(
message = "Starting from 1.6.10, Compose for Web goes to Alpha. Experimental configuration is not needed anymore.",
)
abstract class ExperimentalWebApplication @Inject constructor( abstract class ExperimentalWebApplication @Inject constructor(
@Suppress("unused") @Suppress("unused")
val name: String, val name: String,

9
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/dsl/ExperimentalWebExtension.kt

@ -10,15 +10,24 @@ import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.ExtensionAware import org.gradle.api.plugins.ExtensionAware
import javax.inject.Inject import javax.inject.Inject
@Deprecated(
message = "Starting from 1.6.10, Compose for Web goes to Alpha. Experimental configuration is not needed anymore.",
)
abstract class ExperimentalWebExtension @Inject constructor(private val objectFactory: ObjectFactory) : ExtensionAware { abstract class ExperimentalWebExtension @Inject constructor(private val objectFactory: ObjectFactory) : ExtensionAware {
internal var _isApplicationInitialized = false internal var _isApplicationInitialized = false
private set private set
@Deprecated(
message = "Starting from 1.6.10, Compose for Web goes to Alpha. Experimental configuration is not needed anymore.",
)
val application: ExperimentalWebApplication by lazy { val application: ExperimentalWebApplication by lazy {
_isApplicationInitialized = true _isApplicationInitialized = true
objectFactory.newInstance(ExperimentalWebApplication::class.java, "main") objectFactory.newInstance(ExperimentalWebApplication::class.java, "main")
} }
@Deprecated(
message = "Starting from 1.6.10, Compose for Web goes to Alpha. Experimental configuration is not needed anymore.",
)
fun application(fn: Action<ExperimentalWebApplication>) { fun application(fn: Action<ExperimentalWebApplication>) {
fn.execute(application) fn.execute(application)
} }

1
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt

@ -27,7 +27,6 @@ private val TargetType.gradlePropertyName get() = "org.jetbrains.compose.experim
private val EXPERIMENTAL_TARGETS: Set<TargetType> = setOf( private val EXPERIMENTAL_TARGETS: Set<TargetType> = setOf(
TargetType("macos", presets = listOf("macosX64", "macosArm64")), TargetType("macos", presets = listOf("macosX64", "macosArm64")),
TargetType("jscanvas", presets = listOf("jsIr", "js")), TargetType("jscanvas", presets = listOf("jsIr", "js")),
TargetType("wasm", presets = listOf("wasm", "wasmJs")),
) )
private sealed interface CheckResult { private sealed interface CheckResult {

24
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/configureExperimental.kt

@ -1,24 +0,0 @@
/*
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
package org.jetbrains.compose.experimental.internal
import org.gradle.api.Project
import org.jetbrains.compose.ComposeExtension
import org.jetbrains.compose.experimental.dsl.ExperimentalExtension
import org.jetbrains.compose.experimental.web.internal.configureExperimentalWebApplication
import org.jetbrains.compose.web.WebExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
internal fun Project.configureExperimental(
composeExt: ComposeExtension,
experimentalExt: ExperimentalExtension
) {
if (experimentalExt.web._isApplicationInitialized) {
val webExt = composeExt.extensions.getByType(WebExtension::class.java)
webExt.targetsToConfigure(project)
.configureExperimentalWebApplication(project, experimentalExt.web.application)
}
}

48
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/web/tasks/ExperimentalUnpackSkikoWasmRuntimeTask.kt

@ -5,46 +5,10 @@
package org.jetbrains.compose.experimental.web.tasks package org.jetbrains.compose.experimental.web.tasks
import org.gradle.api.DefaultTask import org.jetbrains.compose.web.tasks.UnpackSkikoWasmRuntimeTask
import org.gradle.api.file.ArchiveOperations
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.jetbrains.compose.internal.utils.clearDirs
import java.io.File
import javax.inject.Inject
abstract class ExperimentalUnpackSkikoWasmRuntimeTask : DefaultTask() { @Deprecated(
@get:InputFiles message = "Starting from 1.6.10 Compose for Web goes to Alpha",
lateinit var skikoRuntimeFiles: FileCollection replaceWith = ReplaceWith("UnpackSkikoWasmRuntimeTask")
)
@get:OutputDirectory abstract class ExperimentalUnpackSkikoWasmRuntimeTask : UnpackSkikoWasmRuntimeTask()
abstract val outputDir: DirectoryProperty
@get:Inject
internal abstract val archiveOperations: ArchiveOperations
@get:Inject
internal abstract val fileOperations: FileSystemOperations
@TaskAction
fun run() {
fileOperations.clearDirs(outputDir)
for (file in skikoRuntimeFiles.files) {
if (file.name.endsWith(".jar", ignoreCase = true)) {
unpackJar(file)
}
}
}
private fun unpackJar(file: File) {
fileOperations.copy { copySpec ->
copySpec.from(archiveOperations.zipTree(file))
copySpec.into(outputDir)
}
}
}

10
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/dsl/WebApplication.kt

@ -0,0 +1,10 @@
package org.jetbrains.compose.web.dsl
import javax.inject.Inject
abstract class WebApplication @Inject constructor(
@Suppress("unused")
val name: String,
) {
}

23
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/web/internal/configureExperimentalWebApplication.kt → gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt

@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/ */
package org.jetbrains.compose.experimental.web.internal package org.jetbrains.compose.web.internal
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
@ -11,16 +11,25 @@ import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.artifacts.UnresolvedDependency import org.gradle.api.artifacts.UnresolvedDependency
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.jetbrains.compose.ComposeBuildConfig import org.jetbrains.compose.ComposeBuildConfig
import org.jetbrains.compose.experimental.dsl.ExperimentalWebApplication import org.jetbrains.compose.ComposeExtension
import org.jetbrains.compose.experimental.web.tasks.ExperimentalUnpackSkikoWasmRuntimeTask import org.jetbrains.compose.web.tasks.UnpackSkikoWasmRuntimeTask
import org.jetbrains.compose.internal.utils.* import org.jetbrains.compose.internal.utils.*
import org.jetbrains.compose.internal.utils.registerTask import org.jetbrains.compose.internal.utils.registerTask
import org.jetbrains.compose.internal.utils.uppercaseFirstChar 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.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
internal fun Collection<KotlinJsIrTarget>.configureExperimentalWebApplication( internal fun Project.configureWeb(
project: Project, composeExt: ComposeExtension,
app: ExperimentalWebApplication ) {
val webExt = composeExt.extensions.getByType(WebExtension::class.java)
// configure only if there is k/wasm or k/js target:
webExt.targetsToConfigure(project)
.configureWebApplication(project)
}
internal fun Collection<KotlinJsIrTarget>.configureWebApplication(
project: Project
) { ) {
val skikoJsWasmRuntimeConfiguration = project.configurations.create("COMPOSE_SKIKO_JS_WASM_RUNTIME") val skikoJsWasmRuntimeConfiguration = project.configurations.create("COMPOSE_SKIKO_JS_WASM_RUNTIME")
val skikoJsWasmRuntimeDependency = skikoVersionProvider(project).map { skikoVersion -> val skikoJsWasmRuntimeDependency = skikoVersionProvider(project).map { skikoVersion ->
@ -37,7 +46,7 @@ internal fun Collection<KotlinJsIrTarget>.configureExperimentalWebApplication(
mainCompilation.defaultSourceSet.resources.srcDir(unpackedRuntimeDir) mainCompilation.defaultSourceSet.resources.srcDir(unpackedRuntimeDir)
testCompilation.defaultSourceSet.resources.srcDir(unpackedRuntimeDir) testCompilation.defaultSourceSet.resources.srcDir(unpackedRuntimeDir)
val unpackRuntime = project.registerTask<ExperimentalUnpackSkikoWasmRuntimeTask>(taskName) { val unpackRuntime = project.registerTask<UnpackSkikoWasmRuntimeTask>(taskName) {
skikoRuntimeFiles = skikoJsWasmRuntimeConfiguration skikoRuntimeFiles = skikoJsWasmRuntimeConfiguration
outputDir.set(unpackedRuntimeDir) outputDir.set(unpackedRuntimeDir)
} }

50
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/tasks/UnpackSkikoWasmRuntimeTask.kt

@ -0,0 +1,50 @@
/*
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
package org.jetbrains.compose.web.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.ArchiveOperations
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.jetbrains.compose.internal.utils.clearDirs
import java.io.File
import javax.inject.Inject
abstract class UnpackSkikoWasmRuntimeTask : DefaultTask() {
@get:InputFiles
lateinit var skikoRuntimeFiles: FileCollection
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
@get:Inject
internal abstract val archiveOperations: ArchiveOperations
@get:Inject
internal abstract val fileOperations: FileSystemOperations
@TaskAction
fun run() {
fileOperations.clearDirs(outputDir)
for (file in skikoRuntimeFiles.files) {
if (file.name.endsWith(".jar", ignoreCase = true)) {
unpackJar(file)
}
}
}
private fun unpackJar(file: File) {
fileOperations.copy { copySpec ->
copySpec.from(archiveOperations.zipTree(file))
copySpec.into(outputDir)
}
}
}
Loading…
Cancel
Save