diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt index 8335a52a556..a2e69637f39 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt @@ -21,7 +21,7 @@ import java.text.ParseException data class TCServiceMessagesClientSettings( val rootNodeName: String, val testNameSuffix: String? = null, - val prepandSuiteName: Boolean = false, + val prependSuiteName: Boolean = false, val treatFailedTestOutputAsStacktrace: Boolean = false, val stackTraceParser: (String) -> ParsedStackTrace? = { null }, val ignoreOutOfRootNodes: Boolean = false @@ -96,7 +96,7 @@ internal open class TCServiceMessagesClient( parent.requireReportingNode() val finalTestName = testName.let { - if (settings.prepandSuiteName) "${parent.fullNameWithoutRoot}.$it" + if (settings.prependSuiteName) "${parent.fullNameWithoutRoot}.$it" else it } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt index 85f9c88bec0..83d8b73ecf1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt @@ -6,22 +6,25 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset -abstract class KotlinOnlyTargetPreset>( +abstract class KotlinOnlyTargetPreset, T : KotlinCompilation<*>>( protected val project: Project, protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { +) : KotlinTargetPreset { protected abstract fun createKotlinTargetConfigurator(): KotlinTargetConfigurator protected open fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget): String? = target.targetName - protected open fun createKotlinOnlyTarget() = KotlinOnlyTarget(project, platformType) + abstract protected fun instantiateTarget(): R - override fun createTarget(name: String): KotlinOnlyTarget { - val result = createKotlinOnlyTarget().apply { + override fun createTarget(name: String): R { + val result = instantiateTarget().apply { targetName = name disambiguationClassifier = provideTargetDisambiguationClassifier(this@apply) preset = this@KotlinOnlyTargetPreset diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetPreset.kt index ede6af4b33a..18d28a7f121 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetPreset.kt @@ -16,14 +16,14 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTargetConfigurator open class KotlinJsTargetPreset( project: Project, kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( +) : KotlinOnlyTargetPreset( project, kotlinPluginVersion ) { override val platformType: KotlinPlatformType get() = KotlinPlatformType.js - override fun createKotlinOnlyTarget() = KotlinJsTarget(project, platformType) + override fun instantiateTarget() = KotlinJsTarget(project, platformType) override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator(kotlinPluginVersion) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/NodeJsStackTraceParser.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/NodeJsStackTraceParser.kt index ee73e50ba5c..dc8eb3ab490 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/NodeJsStackTraceParser.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/internal/NodeJsStackTraceParser.kt @@ -46,6 +46,7 @@ fun parseNodeJsStackTrace(stackTrace: String): NodeJsStackTrace { var firstLines = true val stack = mutableListOf() + // see examples at NodeJsStackTraceParserKtTest stackTrace.lines().forEach { val srcLine = it.trim() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt index 2f1bf9f956e..f21d9d55621 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt @@ -6,7 +6,6 @@ internal data class NodeJsEnv( val nodeDir: File, val nodeBinDir: File, val nodeExecutable: String, - val npmExecutable: String, val platformName: String, val architectureName: String, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlatform.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlatform.kt index 7afea8819c5..43a33bd2fc2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlatform.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlatform.kt @@ -2,7 +2,7 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs /** * Provides platform and architecture names that is used to download NodeJs. - * See [NodeJsEnv.ivyDependency] that is filled in [NodeJsRootExtension.buildEnv]. + * See [NodeJsEnv.ivyDependency] that is filled in [NodeJsRootExtension.environment]. */ internal object NodeJsPlatform { private val props = System.getProperties() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt index 27c935f59fe..76315f038ad 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt @@ -11,8 +11,8 @@ import java.io.File import java.net.URI open class NodeJsSetupTask : DefaultTask() { - private val settings = NodeJsRootExtension[project] - private val env by lazy { settings.buildEnv() } + private val settings = project.nodeJs.root + private val env by lazy { settings.environment } init { group = NodeJsRootExtension.NODE_JS @@ -55,7 +55,7 @@ open class NodeJsSetupTask : DefaultTask() { } } - val dep = this.project.dependencies.create(env.ivyDependency) + val dep = this.project.dependencies.create(ivyDependency) val conf = this.project.configurations.detachedConfiguration(dep) conf.isTransitive = false val result = conf.resolve().single() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesSync.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesSync.kt deleted file mode 100644 index 6297c1ca2b2..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesSync.kt +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. 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.targets.js.npm - -import com.google.gson.GsonBuilder -import com.google.gson.JsonParseException -import org.gradle.api.Project -import org.gradle.api.internal.project.ProjectInternal -import org.gradle.internal.hash.FileHasher -import org.jetbrains.kotlin.daemon.common.toHexString -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModulesSync.* -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProjectLayout.Companion.PACKAGE_JSON -import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile -import java.io.File - -/** - * Incrementally sync gradle JS dependencies into node_modules directory. - * - * Working by traversing giving classpath. - * For each classpath element (called [Element]) `.js` and `.js.map` files are stored into `node_modules`. - * - * To do it incrementally, state of previously traversed classpath elements are stored in - * `node_modules/.from-gradle` file. Unchanged elements will not been visited. - * - * See [Element] and [getOrCompute] for more details. - */ -internal class GradleNodeModulesSync(val project: Project) { - companion object { - const val STATE_FILE_NAME = ".from-gradle" - } - - private val hasher = (project as ProjectInternal).services.get(FileHasher::class.java) - private val npmProjectLayout = NpmProjectLayout[project] - private val nodeModulesDir = npmProjectLayout.nodeModulesDir - private val gson = GsonBuilder().setPrettyPrinting().create() - - private class State { - val contents: MutableMap = mutableMapOf() - - operator fun get(elementHash: ByteArray) = - contents[elementHash.toHexString()] - - operator fun set(elementHash: ByteArray, element: Element) { - contents[elementHash.toHexString()] = element - } - } - - /** - * Traversed element from classpath. - * Stored in state file. - * - * When classpath traversed all elements are in one of this states: - * - unchanged: was loaded from previous state and contents not changed. - * only [fileNames] are known and contents of element not visited, - * but visitor are saved in [_fillFiles] to load in next case - * - unchanged but missed in node_modules: some of [fileNames] missed in node_modules - * in this case [_fillFiles] called before [files] was getted for copy spec - * - unchanged and existed in node_modules: nothing will be done in this case - * - new: not existed in previous state. In this case element is visited, - * both [fileNames] and [_files] are filled already - * - deleted: was loaded from previous state, but not existed in current state - * only [fileNames] are known for this case, which is used to remove outdated files - * - changed: this is just combination of deleted and new state - */ - private class Element { - lateinit var source: String - val fileNames: MutableList = mutableListOf() - - @Transient - @Suppress("PropertyName") - var _files: List? = null - - @Transient - @Suppress("PropertyName") - var _fillFiles: (() -> List)? = null - - val files: List - get() { - if (_files == null) { - _files = _fillFiles!!() - } - return _files!! - } - } - - /** - * Get info of classpath element from previous state (with storing visitor for case when files are deleted in node_modules) - * or compute it now. - * - * @param file classpath element - * @param buildElement js files list provider - */ - private fun getOrCompute(file: File, buildElement: () -> List) { - val hash = hasher.hash(file).toByteArray() - val old = old[hash] - if (old != null) old._fillFiles = buildElement - new[hash] = old ?: Element().also { - it.source = file.absolutePath - it._files = buildElement() - it._files!!.mapTo(it.fileNames) { it.name } - } - } - - private lateinit var old: State - private val new = State() - - private val stateFile = nodeModulesDir.resolve(STATE_FILE_NAME) - - fun loadOldState() { - val state: State? = if (stateFile.isFile) try { - stateFile.reader().use { - gson.fromJson(it, State::class.java) - } - } catch (e: JsonParseException) { - project.logger.warn("Cannot load previous state of Gradle depencies stored in node_modules", e) - null - } else { - if (stateFile.isDirectory) stateFile.deleteRecursively() - null - } - - old = state ?: State() - } - - fun sync() { - val children = nodeModulesDir.list()?.toSet() ?: setOf() - val deleted = old.contents.keys.toMutableSet() - val absented = mutableSetOf() - - new.contents.forEach { (key, value) -> - deleted.remove(key) - if (key !in old.contents.keys) absented.add(key) - else if (value.fileNames.any { it !in children }) absented.add(key) - } - - deleted.forEach { - old.contents[it]!!.fileNames.forEach { fileName -> - nodeModulesDir.resolve(fileName).delete() - } - } - - if (absented.isNotEmpty()) { - project.copy { copy -> - absented.forEach { key -> - copy.from(new.contents[key]!!.files) - } - copy.into(nodeModulesDir) - } - } - - if (deleted.isNotEmpty() || absented.isNotEmpty()) { - saveNewState() - } - } - - private fun saveNewState() { - stateFile.writer().use { - gson.toJson(new, it) - } - } - - class TransitiveNpmDependency( - val key: String, - val version: String - ) - - fun visitCompilation( - compilation: KotlinCompilation, - project: Project, - transitiveDependencies: MutableList - ): List { - val kotlin2JsCompile = compilation.compileKotlinTask as Kotlin2JsCompile - - // classpath - compilation.relatedConfigurationNames.forEach { - val configuration = project.configurations.getByName(it) - if (configuration.isCanBeResolved) { - configuration.resolve().forEach { srcFile -> - when { - srcFile.name == PACKAGE_JSON -> visitPackageJson(srcFile, transitiveDependencies) - isKotlinJsRuntimeFile(srcFile) -> getOrCompute(srcFile) { - listOf(srcFile) - } - srcFile.isZip -> getOrCompute(srcFile) { - mutableListOf().also { files -> - this.project.zipTree(srcFile).forEach { innerFile -> - when { - innerFile.name == PACKAGE_JSON -> visitPackageJson(innerFile, transitiveDependencies) - isKotlinJsRuntimeFile(innerFile) -> files.add(innerFile) - } - } - } - } - } - } - } - } - - // output - if (kotlin2JsCompile.state.executed) { - copyCompileOutput(project, kotlin2JsCompile) - } else { - kotlin2JsCompile.doLast { - copyCompileOutput(project, kotlin2JsCompile) - } - } - - return transitiveDependencies - } - - private fun copyCompileOutput(project: Project, kotlin2JsCompile: Kotlin2JsCompile) { - project.copy { copy -> - copy.from(kotlin2JsCompile.outputFile) - copy.from(kotlin2JsCompile.outputFile.path + ".map") - copy.into(nodeModulesDir) - } - } - - private fun visitPackageJson( - innerFile: File, - transitiveDependencies: MutableList - ) { - val packageJson = innerFile.reader().use { - gson.fromJson(it, PackageJson::class.java) - } - - packageJson.dependencies.forEach { (key, version) -> - transitiveDependencies.add(TransitiveNpmDependency(key, version)) - } - } - - private val File.isZip - get() = isFile && (name.endsWith(".jar") || name.endsWith(".zip")) - - private fun isKotlinJsRuntimeFile(file: File): Boolean { - if (!file.isFile) return false - val name = file.name - return (name.endsWith(".js") && !name.endsWith(".meta.js")) - || name.endsWith(".js.map") - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnLock.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnLock.kt index 205c4821d61..f52935277a4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnLock.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnLock.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import com.google.gson.stream.JsonReader +import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson import java.io.File import java.io.StringReader @@ -16,23 +17,11 @@ data class YarnLock(val entries: List) { val resolved: String?, val integrity: String?, val dependencies: List - ) { - val packageKey = key.substringBeforeLast("@") - } + ) data class Dependency(val key: String, val version: String?) { - val group: String? - val packageName: String - - init { - if (key.contains("/")) { - group = key.substringBeforeLast("/").removePrefix("@") - packageName = key.substringAfterLast("/") - } else { - group = null - packageName = key - } - } + val scopedName: PackageJson.ScopedName + get() = PackageJson.scopedName(key) } companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt index 145f93e4484..94748447ce3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt @@ -14,8 +14,8 @@ import java.io.File import javax.xml.ws.Action open class YarnSetupTask : DefaultTask() { - private val settings = YarnRootExtension[project] - private val env by lazy { settings.buildEnv() } + private val settings = project.yarn + private val env by lazy { settings.environment } @Suppress("MemberVisibilityCanBePrivate") val downloadUrl diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTest.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTest.kt index 4b745a554fe..b0cc9cbb0e7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTest.kt @@ -48,7 +48,7 @@ open class KotlinNativeTest : KotlinTest() { val clientSettings = TCServiceMessagesClientSettings( name, testNameSuffix = targetName, - prepandSuiteName = targetName != null, + prependSuiteName = targetName != null, treatFailedTestOutputAsStacktrace = true, stackTraceParser = ::parseKotlinNativeStackTraceAsJvm )