Gradle, tests: fix type in "prepend"
This commit is contained in:
+2
-2
@@ -21,7 +21,7 @@ import java.text.ParseException
|
|||||||
data class TCServiceMessagesClientSettings(
|
data class TCServiceMessagesClientSettings(
|
||||||
val rootNodeName: String,
|
val rootNodeName: String,
|
||||||
val testNameSuffix: String? = null,
|
val testNameSuffix: String? = null,
|
||||||
val prepandSuiteName: Boolean = false,
|
val prependSuiteName: Boolean = false,
|
||||||
val treatFailedTestOutputAsStacktrace: Boolean = false,
|
val treatFailedTestOutputAsStacktrace: Boolean = false,
|
||||||
val stackTraceParser: (String) -> ParsedStackTrace? = { null },
|
val stackTraceParser: (String) -> ParsedStackTrace? = { null },
|
||||||
val ignoreOutOfRootNodes: Boolean = false
|
val ignoreOutOfRootNodes: Boolean = false
|
||||||
@@ -96,7 +96,7 @@ internal open class TCServiceMessagesClient(
|
|||||||
parent.requireReportingNode()
|
parent.requireReportingNode()
|
||||||
|
|
||||||
val finalTestName = testName.let {
|
val finalTestName = testName.let {
|
||||||
if (settings.prepandSuiteName) "${parent.fullNameWithoutRoot}.$it"
|
if (settings.prependSuiteName) "${parent.fullNameWithoutRoot}.$it"
|
||||||
else it
|
else it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -6,22 +6,25 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import org.gradle.api.Project
|
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<T : KotlinCompilation<*>>(
|
abstract class KotlinOnlyTargetPreset<R : KotlinOnlyTarget<T>, T : KotlinCompilation<*>>(
|
||||||
protected val project: Project,
|
protected val project: Project,
|
||||||
protected val kotlinPluginVersion: String
|
protected val kotlinPluginVersion: String
|
||||||
) : KotlinTargetPreset<KotlinOnlyTarget<T>> {
|
) : KotlinTargetPreset<R> {
|
||||||
|
|
||||||
protected abstract fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<T>
|
protected abstract fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<T>
|
||||||
|
|
||||||
protected open fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<T>): String? =
|
protected open fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<T>): String? =
|
||||||
target.targetName
|
target.targetName
|
||||||
|
|
||||||
protected open fun createKotlinOnlyTarget() = KotlinOnlyTarget<T>(project, platformType)
|
abstract protected fun instantiateTarget(): R
|
||||||
|
|
||||||
override fun createTarget(name: String): KotlinOnlyTarget<T> {
|
override fun createTarget(name: String): R {
|
||||||
val result = createKotlinOnlyTarget().apply {
|
val result = instantiateTarget().apply {
|
||||||
targetName = name
|
targetName = name
|
||||||
disambiguationClassifier = provideTargetDisambiguationClassifier(this@apply)
|
disambiguationClassifier = provideTargetDisambiguationClassifier(this@apply)
|
||||||
preset = this@KotlinOnlyTargetPreset
|
preset = this@KotlinOnlyTargetPreset
|
||||||
|
|||||||
+2
-2
@@ -16,14 +16,14 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTargetConfigurator
|
|||||||
open class KotlinJsTargetPreset(
|
open class KotlinJsTargetPreset(
|
||||||
project: Project,
|
project: Project,
|
||||||
kotlinPluginVersion: String
|
kotlinPluginVersion: String
|
||||||
) : KotlinOnlyTargetPreset<KotlinJsCompilation>(
|
) : KotlinOnlyTargetPreset<KotlinJsTarget, KotlinJsCompilation>(
|
||||||
project,
|
project,
|
||||||
kotlinPluginVersion
|
kotlinPluginVersion
|
||||||
) {
|
) {
|
||||||
override val platformType: KotlinPlatformType
|
override val platformType: KotlinPlatformType
|
||||||
get() = KotlinPlatformType.js
|
get() = KotlinPlatformType.js
|
||||||
|
|
||||||
override fun createKotlinOnlyTarget() = KotlinJsTarget(project, platformType)
|
override fun instantiateTarget() = KotlinJsTarget(project, platformType)
|
||||||
|
|
||||||
override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator(kotlinPluginVersion)
|
override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator(kotlinPluginVersion)
|
||||||
|
|
||||||
|
|||||||
+1
@@ -46,6 +46,7 @@ fun parseNodeJsStackTrace(stackTrace: String): NodeJsStackTrace {
|
|||||||
var firstLines = true
|
var firstLines = true
|
||||||
val stack = mutableListOf<NodeJsStackTraceElement>()
|
val stack = mutableListOf<NodeJsStackTraceElement>()
|
||||||
|
|
||||||
|
// see examples at NodeJsStackTraceParserKtTest
|
||||||
stackTrace.lines().forEach {
|
stackTrace.lines().forEach {
|
||||||
val srcLine = it.trim()
|
val srcLine = it.trim()
|
||||||
|
|
||||||
|
|||||||
-1
@@ -6,7 +6,6 @@ internal data class NodeJsEnv(
|
|||||||
val nodeDir: File,
|
val nodeDir: File,
|
||||||
val nodeBinDir: File,
|
val nodeBinDir: File,
|
||||||
val nodeExecutable: String,
|
val nodeExecutable: String,
|
||||||
val npmExecutable: String,
|
|
||||||
|
|
||||||
val platformName: String,
|
val platformName: String,
|
||||||
val architectureName: String,
|
val architectureName: String,
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides platform and architecture names that is used to download 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 {
|
internal object NodeJsPlatform {
|
||||||
private val props = System.getProperties()
|
private val props = System.getProperties()
|
||||||
|
|||||||
+3
-3
@@ -11,8 +11,8 @@ import java.io.File
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
open class NodeJsSetupTask : DefaultTask() {
|
open class NodeJsSetupTask : DefaultTask() {
|
||||||
private val settings = NodeJsRootExtension[project]
|
private val settings = project.nodeJs.root
|
||||||
private val env by lazy { settings.buildEnv() }
|
private val env by lazy { settings.environment }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
group = NodeJsRootExtension.NODE_JS
|
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)
|
val conf = this.project.configurations.detachedConfiguration(dep)
|
||||||
conf.isTransitive = false
|
conf.isTransitive = false
|
||||||
val result = conf.resolve().single()
|
val result = conf.resolve().single()
|
||||||
|
|||||||
-246
@@ -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<String, Element> = 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<String> = mutableListOf()
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
@Suppress("PropertyName")
|
|
||||||
var _files: List<File>? = null
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
@Suppress("PropertyName")
|
|
||||||
var _fillFiles: (() -> List<File>)? = null
|
|
||||||
|
|
||||||
val files: List<File>
|
|
||||||
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<File>) {
|
|
||||||
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<String>()
|
|
||||||
|
|
||||||
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<KotlinCommonOptions>,
|
|
||||||
project: Project,
|
|
||||||
transitiveDependencies: MutableList<TransitiveNpmDependency>
|
|
||||||
): List<TransitiveNpmDependency> {
|
|
||||||
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<File>().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<TransitiveNpmDependency>
|
|
||||||
) {
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-15
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.yarn
|
package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||||
|
|
||||||
import com.google.gson.stream.JsonReader
|
import com.google.gson.stream.JsonReader
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.StringReader
|
import java.io.StringReader
|
||||||
|
|
||||||
@@ -16,23 +17,11 @@ data class YarnLock(val entries: List<Entry>) {
|
|||||||
val resolved: String?,
|
val resolved: String?,
|
||||||
val integrity: String?,
|
val integrity: String?,
|
||||||
val dependencies: List<Dependency>
|
val dependencies: List<Dependency>
|
||||||
) {
|
)
|
||||||
val packageKey = key.substringBeforeLast("@")
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Dependency(val key: String, val version: String?) {
|
data class Dependency(val key: String, val version: String?) {
|
||||||
val group: String?
|
val scopedName: PackageJson.ScopedName
|
||||||
val packageName: String
|
get() = PackageJson.scopedName(key)
|
||||||
|
|
||||||
init {
|
|
||||||
if (key.contains("/")) {
|
|
||||||
group = key.substringBeforeLast("/").removePrefix("@")
|
|
||||||
packageName = key.substringAfterLast("/")
|
|
||||||
} else {
|
|
||||||
group = null
|
|
||||||
packageName = key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+2
-2
@@ -14,8 +14,8 @@ import java.io.File
|
|||||||
import javax.xml.ws.Action
|
import javax.xml.ws.Action
|
||||||
|
|
||||||
open class YarnSetupTask : DefaultTask() {
|
open class YarnSetupTask : DefaultTask() {
|
||||||
private val settings = YarnRootExtension[project]
|
private val settings = project.yarn
|
||||||
private val env by lazy { settings.buildEnv() }
|
private val env by lazy { settings.environment }
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
val downloadUrl
|
val downloadUrl
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ open class KotlinNativeTest : KotlinTest() {
|
|||||||
val clientSettings = TCServiceMessagesClientSettings(
|
val clientSettings = TCServiceMessagesClientSettings(
|
||||||
name,
|
name,
|
||||||
testNameSuffix = targetName,
|
testNameSuffix = targetName,
|
||||||
prepandSuiteName = targetName != null,
|
prependSuiteName = targetName != null,
|
||||||
treatFailedTestOutputAsStacktrace = true,
|
treatFailedTestOutputAsStacktrace = true,
|
||||||
stackTraceParser = ::parseKotlinNativeStackTraceAsJvm
|
stackTraceParser = ::parseKotlinNativeStackTraceAsJvm
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user