From 355ad3e641aba1cc663622b60147164cb06f8dac Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Fri, 25 Aug 2023 17:23:10 +0000 Subject: [PATCH] [Gradle, JS] Distinguish creating prepared resolution and writing package.json ^KT-61326 fixed --- .../kotlin/gradle/Kotlin2JsGradlePluginIT.kt | 35 ++++++++++++++ .../app/build.gradle.kts | 19 ++++++++ .../app/src/main/kotlin/App.kt | 13 ++++++ .../app/src/test/kotlin/AppTests.kt | 16 +++++++ .../base/build.gradle.kts | 20 ++++++++ .../base/src/main/kotlin/Base.kt | 14 ++++++ .../build.gradle.kts | 13 ++++++ .../lib/build.gradle.kts | 16 +++++++ .../lib/src/main/kotlin/Lib.kt | 14 ++++++ .../settings.gradle | 5 ++ .../targets/js/npm/PublicPackageJsonTask.kt | 4 +- .../npm/resolved/KotlinRootNpmResolution.kt | 14 ++++-- .../KotlinCompilationNpmResolution.kt | 46 +++++++++---------- .../js/npm/tasks/KotlinPackageJsonTask.kt | 6 ++- 14 files changed, 203 insertions(+), 32 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/main/kotlin/App.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/test/kotlin/AppTests.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/src/main/kotlin/Base.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/src/main/kotlin/Lib.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/settings.gradle diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt index 8a6979c1c17..b5f5a108c3a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt @@ -1702,4 +1702,39 @@ class Kotlin2JsIrGradlePluginIT : KGPBaseTest() { } } } + + @DisplayName("test package.jsom skipped with main package.json was up-to-date") + @GradleTest + fun testPackageJsonSkippedWithUpToDatePackageJsons(gradleVersion: GradleVersion) { + project("kotlin-js-browser-library-project", gradleVersion) { + subProject("app").buildGradleKts.modify { + it + """ + + tasks.named("testPackageJson") { + enabled = false + } + + tasks.named("testPublicPackageJson") { + enabled = false + } + """.trimIndent() + } + + build("assemble") { + assertTasksExecuted(":app:packageJson") + assertTasksExecuted(":base:packageJson") + assertTasksExecuted(":lib:packageJson") + } + + build("check") { + assertTasksUpToDate(":app:packageJson") + assertTasksUpToDate(":base:packageJson") + assertTasksUpToDate(":lib:packageJson") + + assertTasksSkipped(":app:testPackageJson") + assertTasksExecuted(":lib:testPackageJson") + assertTasksExecuted(":base:testPackageJson") + } + } + } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/build.gradle.kts new file mode 100644 index 00000000000..4378e8b1bc3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + kotlin("js") +} + +dependencies { + implementation(kotlin("stdlib-js")) + implementation(project(":lib")) + testImplementation(kotlin("test-js")) +} + +kotlin { + js { + browser { + testTask { + enabled = false + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/main/kotlin/App.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/main/kotlin/App.kt new file mode 100644 index 00000000000..b700d846d64 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/main/kotlin/App.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2019 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 com.example + +fun main() { + require("css/main.css") + println("Sheldon: ${sheldon()}") +} + +external fun require(o: String) \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/test/kotlin/AppTests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/test/kotlin/AppTests.kt new file mode 100644 index 00000000000..2de853b46ff --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/app/src/test/kotlin/AppTests.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2021 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 com.example + +import kotlin.test.Test +import kotlin.test.assertEquals + +class AppTests { + @Test + fun testSheldon() { + assertEquals(73, sheldon()) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/build.gradle.kts new file mode 100644 index 00000000000..066376cfe21 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/build.gradle.kts @@ -0,0 +1,20 @@ +import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.IR as IR_TYPE + +plugins { + kotlin("js") +} + +dependencies { + implementation(kotlin("stdlib-js")) +} + +@Suppress("DEPRECATION") +kotlin { + js("ir") + js(IR) + js(IR_TYPE) { + useCommonJs() + browser { + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/src/main/kotlin/Base.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/src/main/kotlin/Base.kt new file mode 100644 index 00000000000..e69d852c3e0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/base/src/main/kotlin/Base.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2019 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 com.example + +fun best(): Int { + return 42 +} + +fun simpleBest(): Int { + return 73 +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/build.gradle.kts new file mode 100644 index 00000000000..877c415742c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + kotlin("js").apply(false) +} + +group = "com.example" +version = "1.0" + +allprojects { + repositories { + mavenLocal() + mavenCentral() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/build.gradle.kts new file mode 100644 index 00000000000..a4724302a79 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + kotlin("js") +} + +dependencies { + implementation(kotlin("stdlib-js")) + implementation(project(":base")) +} + +kotlin { + js { + useCommonJs() + browser { + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/src/main/kotlin/Lib.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/src/main/kotlin/Lib.kt new file mode 100644 index 00000000000..9ec1e64a28c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/lib/src/main/kotlin/Lib.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2019 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 com.example + +fun answer(): Int { + return best() +} + +fun sheldon(): Int { + return simpleBest() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/settings.gradle new file mode 100644 index 00000000000..bb57e5ac101 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-browser-library-project/settings.gradle @@ -0,0 +1,5 @@ +rootProject.name = "kotlin-js-browser" + +include("base") +include("lib") +include("app") \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/PublicPackageJsonTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/PublicPackageJsonTask.kt index a95d54f8dbd..bbaa1edf06b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/PublicPackageJsonTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/PublicPackageJsonTask.kt @@ -16,6 +16,7 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.work.DisableCachingByDefault import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject.Companion.PACKAGE_JSON +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.PreparedKotlinCompilationNpmResolution import org.jetbrains.kotlin.gradle.utils.property import java.io.File @@ -54,11 +55,10 @@ abstract class PublicPackageJsonTask : } } - private val compilationResolution + private val compilationResolution: PreparedKotlinCompilationNpmResolution get() = npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()] .getResolutionOrPrepare( npmResolutionManager.get(), - packageJsonHandlers, logger ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt index ae77c47ebd8..8f7ade1fa08 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt @@ -16,7 +16,7 @@ import java.io.Serializable class KotlinRootNpmResolution( val projects: Map, val rootProjectName: String, - val rootProjectVersion: String + val rootProjectVersion: String, ) : Serializable { operator fun get(project: String) = projects[project] ?: KotlinProjectNpmResolution.empty() @@ -27,12 +27,20 @@ class KotlinRootNpmResolution( logger: Logger, npmEnvironment: NpmEnvironment, yarnEnvironment: YarnEnvironment, - npmResolutionManager: KotlinNpmResolutionManager + npmResolutionManager: KotlinNpmResolutionManager, ): Installation { synchronized(projects) { npmResolutionManager.parameters.gradleNodeModulesProvider.get().close() - val projectResolutions: List = projects.values.flatMap { it.npmProjects }.map { it.close() } + val projectResolutions: List = projects.values + .flatMap { it.npmProjects } + .map { + it.close( + npmResolutionManager, + logger + ) + } + npmEnvironment.packageManager.prepareRootProject( npmEnvironment, rootProjectName, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolution.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolution.kt index ac43d91fd24..b271be4f347 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolution.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolution.kt @@ -29,7 +29,7 @@ class KotlinCompilationNpmResolution( val npmProjectMain: String, val npmProjectPackageJsonFile: File, val npmProjectDir: File, - val tasksRequirements: TasksRequirements + val tasksRequirements: TasksRequirements, ) : Serializable { val inputs: PackageJsonProducerInputs @@ -45,17 +45,13 @@ class KotlinCompilationNpmResolution( @Synchronized fun prepareWithDependencies( - skipWriting: Boolean = false, npmResolutionManager: KotlinNpmResolutionManager, - packageJsonHandlers: ListProperty>, - logger: Logger + logger: Logger, ): PreparedKotlinCompilationNpmResolution { check(resolution == null) { "$this already resolved" } return createPreparedResolution( - skipWriting, npmResolutionManager, - packageJsonHandlers, logger ).also { resolution = it @@ -65,30 +61,28 @@ class KotlinCompilationNpmResolution( @Synchronized fun getResolutionOrPrepare( npmResolutionManager: KotlinNpmResolutionManager, - packageJsonHandlers: ListProperty>, logger: Logger, ): PreparedKotlinCompilationNpmResolution { return resolution ?: prepareWithDependencies( - skipWriting = true, npmResolutionManager, - packageJsonHandlers, logger ) } @Synchronized - fun close(): PreparedKotlinCompilationNpmResolution { + fun close( + npmResolutionManager: KotlinNpmResolutionManager, + logger: Logger, + ): PreparedKotlinCompilationNpmResolution { check(!closed) { "$this already closed" } closed = true - return resolution!! + return getResolutionOrPrepare(npmResolutionManager, logger) } fun createPreparedResolution( - skipWriting: Boolean, npmResolutionManager: KotlinNpmResolutionManager, - packageJsonHandlers: ListProperty>, - logger: Logger + logger: Logger, ): PreparedKotlinCompilationNpmResolution { val rootResolver = npmResolutionManager.parameters.resolution.get() @@ -97,7 +91,6 @@ class KotlinCompilationNpmResolution( val compilationNpmResolution: KotlinCompilationNpmResolution = rootResolver[it.projectPath][it.compilationName] compilationNpmResolution.getResolutionOrPrepare( npmResolutionManager, - packageJsonHandlers, logger ) } @@ -126,11 +119,22 @@ class KotlinCompilationNpmResolution( val otherNpmDependencies = toolsNpmDependencies + transitiveNpmDependencies val allNpmDependencies = disambiguateDependencies(externalNpmDependencies, otherNpmDependencies, logger) + return PreparedKotlinCompilationNpmResolution( + npmProjectDir, + importedExternalGradleDependencies, + allNpmDependencies, + ) + } + + fun createPackageJson( + resolution: PreparedKotlinCompilationNpmResolution, + packageJsonHandlers: ListProperty>, + ) { val packageJson = packageJson( npmProjectName, npmProjectVersion, npmProjectMain, - allNpmDependencies, + resolution.externalNpmDependencies, packageJsonHandlers.get() ) @@ -138,15 +142,7 @@ class KotlinCompilationNpmResolution( it.execute(packageJson) } - if (!skipWriting) { - packageJson.saveTo(npmProjectPackageJsonFile) - } - - return PreparedKotlinCompilationNpmResolution( - npmProjectDir, - importedExternalGradleDependencies, - allNpmDependencies, - ) + packageJson.saveTo(npmProjectPackageJsonFile) } private fun disambiguateDependencies( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt index 8296962a88b..98f88464405 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt @@ -112,12 +112,14 @@ abstract class KotlinPackageJsonTask : @TaskAction fun resolve() { - npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()] + val resolution = npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()] + val preparedResolution = resolution .prepareWithDependencies( npmResolutionManager = npmResolutionManager.get(), - packageJsonHandlers = packageJsonHandlers, logger = logger ) + + resolution.createPackageJson(preparedResolution, packageJsonHandlers) } companion object {