Disable yarn and npm tasks from the build when tests are not active

Kotlin build shouldn't depend on npm during while deploy artefacts tasks

^KTI-887 Fixed
^KT-53687 Related
This commit is contained in:
Nikolay Krasko
2022-08-05 12:30:14 +02:00
committed by teamcity
parent db1bd4f232
commit 01f567a16d
8 changed files with 136 additions and 1 deletions
+2
View File
@@ -895,6 +895,8 @@ if (disableVerificationTasks) {
}
}
gradle.taskGraph.whenReady(checkYarnAndNPMSuppressed)
plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin::class) {
extensions.configure(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension::class.java) {
npmInstallTaskProvider?.configure {
@@ -0,0 +1,121 @@
/*
* Copyright 2010-2022 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.
*/
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.execution.TaskExecutionGraph
import org.gradle.api.tasks.TaskProvider
/* This file is solely needed to suppress implicit dependencies on npm and yarn tasks registered by Kotlin Gradle Plugin */
private val rootNpmRelatedTasks = setOf("kotlinNpmInstall", "kotlinStoreYarnLock")
private val ownNpmRelatedTasks = setOf("jsGenerateExternalsIntegrated", "irGenerateExternalsIntegrated", "wasmGenerateExternalsIntegrated")
private val forbidImplicitDependOnNpmRelatedTasks = setOf(
"jsPackageJson",
"jsPublicPackageJson",
"irPublicPackageJson",
"legacyPublicPackageJson",
"wasmPackageJson",
"wasmPublicPackageJson",
"compileKotlinJs",
"compileKotlinJsIr",
"compileKotlinWasm",
"compileKotlinJsLegacy"
)
private val allowImplicitDependOnNpmForTasks = setOf("compileTestKotlinJs", "compileTestKotlinWasm")
/**
* Kotlin JS gradle plugin implicitly define dependency to installing NPM and Yarn
* https://youtrack.jetbrains.com/issue/KT-53687/Dont-trigger-npm-and-yarn-related-tasks-if-it-not-relevant-for-assemble
* We would like to explicitly disable this behaviour for kotlin standard library publication as it's shouldn't be needed but make the
* build slower, make it less stable, generated additional traiffic, make the build less secure and so on.
*
* Implemented by manually removing dependencies set by Kotlin Gradle Plugin.
*/
fun Project.suppressYarnAndNpmForAssemble() {
afterEvaluate {
for (npmYarnTaskName in rootNpmRelatedTasks) {
tasks.findByPath(":$npmYarnTaskName") ?: error("Can't find root task $npmYarnTaskName")
}
val npmRelatedTasksNames = rootNpmRelatedTasks + ownNpmRelatedTasks
for (taskName in forbidImplicitDependOnNpmRelatedTasks) {
val task = project.tasks.findByName(taskName) ?: continue
if (!task.enabled) continue
val removeDependencies = task.dependsOn
.filterIsInstance(TaskProvider::class.java)
.filter { it.name in npmRelatedTasksNames }
.toSet()
if (removeDependencies.isNotEmpty()) {
task.setDependsOn(task.dependsOn - removeDependencies)
logger.quiet("Disable NPM/Yarn dependency tasks in $project - " +
"remove ${removeDependencies.joinToString(", ") { "'${it.name}'" }} dependencies from $task")
}
}
}
}
private fun findRootTasks(taskGraph: TaskExecutionGraph): List<Task> {
val allDependentTasksPaths = mutableSetOf<String>()
val allTasksPaths = mutableSetOf<String>()
taskGraph.allTasks.forEach { task ->
allTasksPaths.add(task.path)
for (dependency in task.taskDependencies.getDependencies(task)) {
allDependentTasksPaths.add(dependency.path)
}
}
val rootTasksPaths = allTasksPaths - allDependentTasksPaths
return taskGraph.allTasks.filter { task -> task.path in rootTasksPaths }
}
private fun tasksGraphString(taskGraph: TaskExecutionGraph, ident: String = "", nextIdent: (String) -> String = { "$it|-"}): String {
return buildString {
val alreadyPrintedTasks = mutableSetOf<String>()
fun Task.printTree(indent: String) {
append(indent)
if (path in alreadyPrintedTasks) {
appendLine("$path *")
} else {
alreadyPrintedTasks.add(path)
appendLine(path)
val nextIndent = nextIdent(indent)
for (dependency in taskDependencies.getDependencies(this)) {
dependency.printTree(nextIndent)
}
}
}
for (rootTask in findRootTasks(taskGraph)) {
rootTask.printTree(ident)
}
}
}
val Project.checkYarnAndNPMSuppressed: Action<TaskExecutionGraph> get() {
return Action<TaskExecutionGraph> {
val disableNpmYarnCheck = providers.gradleProperty("kotlin.build.disable.npmyarn.suppress.check")
.forUseAtConfigurationTime().orNull?.toBoolean() ?: false
if (disableNpmYarnCheck) return@Action
val executeTaskNames = allTasks.filter { it.enabled }.map { it.name }.toSet()
val npmYarnTasks = rootNpmRelatedTasks.filter { it in executeTaskNames }
val allowedTask = allowImplicitDependOnNpmForTasks.filter { it in executeTaskNames }
if (npmYarnTasks.isNotEmpty()) {
if (allowedTask.isEmpty()) {
error("$npmYarnTasks tasks shouldn't be present in the task graph: $npmYarnTasks " +
"as $allowImplicitDependOnNpmForTasks tasks were not activated\n" +
"Graph:\n${tasksGraphString(this)}")
}
}
}
}
@@ -4,6 +4,8 @@ plugins {
kotlin("multiplatform")
}
suppressYarnAndNpmForAssemble()
val commonMainSources by task<Sync> {
from(
"$rootDir/libraries/kotlin.test/common/src/main",
@@ -35,6 +35,8 @@ kotlin {
}
}
suppressYarnAndNpmForAssemble()
tasks.withType<KotlinCompile<*>>().configureEach {
kotlinOptions.freeCompilerArgs += listOf(
"-Xallow-kotlin-package",
@@ -10,6 +10,8 @@ kotlin {
}
}
suppressYarnAndNpmForAssemble()
val commonMainSources by task<Sync> {
dependsOn(":kotlin-stdlib-js-ir:commonMainSources")
from {
+3 -1
View File
@@ -1,5 +1,4 @@
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.IR
plugins {
kotlin("multiplatform")
@@ -17,6 +16,8 @@ kotlin {
}
}
suppressYarnAndNpmForAssemble()
val unimplementedNativeBuiltIns =
(file("$rootDir/core/builtins/native/kotlin/").list().toSortedSet() - file("$rootDir/libraries/stdlib/js-ir/builtins/").list())
.map { "core/builtins/native/kotlin/$it" }
@@ -169,3 +170,4 @@ val packFullRuntimeKLib by tasks.registering(Jar::class) {
destinationDirectory.set(rootProject.buildDir.resolve("js-ir-runtime"))
archiveFileName.set("full-runtime.klib")
}
+2
View File
@@ -7,6 +7,8 @@ plugins {
kotlin("multiplatform")
}
suppressYarnAndNpmForAssemble()
description = "Kotlin Standard Library for experimental WebAssembly platform"
val unimplementedNativeBuiltIns =
@@ -28,6 +28,8 @@ kotlin {
}
}
suppressYarnAndNpmForAssemble()
configureCommonPublicationSettingsForGradle(signLibraryPublication)
publishing {