Skip to content

Commit

Permalink
[Wasm] Move nodejs setup task to project-scoped plugin NodeJsPlugin
Browse files Browse the repository at this point in the history
To solve problem that users cannot set Node.JS version per sub-project,
new plugin NodeJsPlugin is introduced and it now registers setup task per-project
NodeJsRootExtension has deprecated properties to configure Node.JS version,
But it influences only rootProject's NodeJs

Added new kind of extensions to configure tools (Binaryen, D8, Node.js, Yarn) with Provider API. In the future old extensions should be deprecated and removed, and new "EnvSpec" should be the only way to configure

^KT-69628 fixed


Co-authored-by: Adam Semenenko <[email protected]>
  • Loading branch information
2 people authored and qodana-bot committed Sep 18, 2024
1 parent 4ce13c9 commit bc02ee8
Show file tree
Hide file tree
Showing 63 changed files with 1,442 additions and 673 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
package org.jetbrains.kotlin.gradle

@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
annotation class ExperimentalWasmDsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

package org.jetbrains.kotlin.gradle

import org.gradle.api.Action
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.test.TestMetadata
import org.junit.jupiter.api.DisplayName


@MppGradlePluginTests
class NodeJsGradlePluginIT : KGPBaseTest() {
@DisplayName("Set different Node.js versions in different subprojects")
@GradleTest
@TestMetadata("subprojects-nodejs-setup")
fun testDifferentVersionInSubprojects(gradleVersion: GradleVersion) {
project(
"subprojects-nodejs-setup",
gradleVersion
) {
build(":app1:jsNodeDevelopmentRun") {
assertOutputContains("Hello with version: v22.2.0")
}

build(":app2:jsNodeDevelopmentRun") {
assertOutputContains("Hello with version: v22.1.0")
}
}
}

@DisplayName("Set different Node.js versions in different subprojects configured with previous API")
@GradleTest
@TestMetadata("subprojects-nodejs-setup")
fun testDifferentVersionInSubprojectsWithPreviousApi(gradleVersion: GradleVersion) {
project(
"subprojects-nodejs-setup",
gradleVersion
) {
listOf("app1", "app2").forEach { subProjectName ->
subProject(subProjectName).buildGradleKts.modify {
it.replace("plugins.", "rootProject.plugins.")
.replace("the", "rootProject.the")
.replace("NodeJsPlugin", "NodeJsRootPlugin")
.replace("NodeJsEnvSpec", "NodeJsRootExtension")
.replace("""version\.set\(("\d+\.\d+.\d+")\)""".toRegex(), "version = \"22.3.0\"")
}
}

build(":app1:jsNodeDevelopmentRun") {
assertOutputContains("Hello with version: v22.3.0")
}

build(":app2:jsNodeDevelopmentRun") {
assertOutputContains("Hello with version: v22.3.0")
}
}
}

@DisplayName("Set different Node.js versions in root project and subprojects")
@GradleTest
@TestMetadata("subprojects-nodejs-setup")
fun testDifferentVersionInRootProjectAndSubprojects(gradleVersion: GradleVersion) {
project(
"subprojects-nodejs-setup",
gradleVersion
) {
buildScriptInjection {
project.rootProject.plugins.withType(NodeJsRootPlugin::class.java, Action {
project.rootProject.extensions.getByType(NodeJsRootExtension::class.java).version = "22.3.0"
})
}

build(":app1:jsNodeDevelopmentRun") {
assertOutputContains("Hello with version: v22.2.0")
}

build(":app2:jsNodeDevelopmentRun") {
assertOutputContains("Hello with version: v22.1.0")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
import javax.inject.Inject
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject

plugins {
kotlin("js")
Expand Down Expand Up @@ -56,20 +54,25 @@ kotlin {
customField("customField5", "@as/${nameOfModule}")
}
}
}
}

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
val kotlinNodeJs = rootProject.extensions.getByType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>()

tasks.register<Exec>("runWebpackResult") {
val webpackTask = tasks.named<org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack>("browserProductionWebpack")
dependsOn(webpackTask)
val mainCompilation = compilations["main"]
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
tasks.register<Exec>("runWebpackResult") {
val webpackTask = tasks.named<org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack>("browserProductionWebpack")
dependsOn(webpackTask)

executable(kotlinNodeJs.requireConfigured().nodeExecutable)
val workDir = webpackTask.flatMap { it.outputDirectory.asFile }

workingDir(webpackTask.flatMap { it.outputDirectory.asFile })
args("./${project.name}.js")
val npmProject = mainCompilation.npmProject
val projectName = project.name
doFirst {
this as Exec
npmProject.useTool(this, "webpack/bin/webpack", args = listOf())
this.args = listOf("./$projectName.js")
workingDir(workDir)
}
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProjectKt

plugins {
id("org.jetbrains.kotlin.js")
}
Expand All @@ -16,6 +18,28 @@ kotlin {
js {
binaries.executable()
browser()

rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin) {
// def kotlinNodeJs = rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExtension)

def mainCompilation = compilations["main"]

tasks.register("runWebpack", Exec) {
dependsOn(tasks.named('browserProductionWebpack'))

workingDir = "${rootProject.buildDir}/js/packages/kotlin-js-dce-mainProject"

def npmProject = NpmProjectKt.getNpmProject(mainCompilation)

doFirst {
npmProject.useTool(it, "webpack/bin/webpack", [], [])
}
}

tasks.named("assemble") {
dependsOn("runWebpack")
}
}
}
}

Expand All @@ -33,23 +57,6 @@ kotlin {
// destinationDirectory = project.layout.buildDirectory.dir("kotlin-js-min")
//}

rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin) {
def kotlinNodeJs = rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension)

tasks.register("runWebpack", Exec) {
dependsOn(tasks.named('browserProductionWebpack'))

executable(kotlinNodeJs.requireConfigured().executable)

workingDir = "${rootProject.buildDir}/js/packages/kotlin-js-dce-mainProject"
args = ["../../node_modules/webpack/bin/webpack.js"]
}

tasks.named("assemble") {
dependsOn("runWebpack")
}
}



tasks.register('runRhino', JavaExec) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repositories {
mavenCentral()
}

with(org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin.apply(rootProject)) {
with(org.jetbrains.kotlin.gradle.targets.js.d8.D8Plugin.apply(rootProject)) {
// Test that we can set the version and it is a String.
// But use the default version since update this place every time anyway.
version = (version as String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJ
}
}

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin> {
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.d8.D8Plugin> {
// Test that we can set the version and it is a String.
// But use the default version since update this place every time anyway.
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.d8.D8RootExtension>().version = (version as String)
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.d8.D8Extension>().version = (version as String)
}

allprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
kotlin("multiplatform")
}

with(org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin.apply(rootProject)) {
with(org.jetbrains.kotlin.gradle.targets.js.d8.D8Plugin.apply(rootProject)) {
// Test that we can set the version and it is a String.
// But use the default version since update this place every time anyway.
version = (version as String)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("org.jetbrains.kotlin.multiplatform")
}

kotlin {
js {
binaries.executable()
nodejs()
}
}

plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin> {
the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec>().version.set("22.2.0")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

fun main() {
println("Hello with version: " + process.version)
}

external val process: dynamic
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("org.jetbrains.kotlin.multiplatform")
}

kotlin {
js {
binaries.executable()
nodejs()
}
}

plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin> {
the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec>().version.set("22.1.0")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

fun main() {
println("Hello with version: " + process.version)
}

external val process: dynamic
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugins {
id("org.jetbrains.kotlin.multiplatform") apply false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include("app1")
include("app2")
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJ
}
}

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin> {
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.d8.D8Plugin> {
// Test that we can set the version and it is a String.
// But use the default version since update this place every time anyway.
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.d8.D8RootExtension>().version = (version as String)
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.d8.D8Extension>().version = (version as String)
}

allprojects {
Expand Down
Loading

0 comments on commit bc02ee8

Please sign in to comment.