Gradle, tests: fix type in "prepend"
This commit is contained in:
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+9
-6
@@ -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<T : KotlinCompilation<*>>(
|
||||
abstract class KotlinOnlyTargetPreset<R : KotlinOnlyTarget<T>, T : KotlinCompilation<*>>(
|
||||
protected val project: Project,
|
||||
protected val kotlinPluginVersion: String
|
||||
) : KotlinTargetPreset<KotlinOnlyTarget<T>> {
|
||||
) : KotlinTargetPreset<R> {
|
||||
|
||||
protected abstract fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<T>
|
||||
|
||||
protected open fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<T>): String? =
|
||||
target.targetName
|
||||
|
||||
protected open fun createKotlinOnlyTarget() = KotlinOnlyTarget<T>(project, platformType)
|
||||
abstract protected fun instantiateTarget(): R
|
||||
|
||||
override fun createTarget(name: String): KotlinOnlyTarget<T> {
|
||||
val result = createKotlinOnlyTarget().apply {
|
||||
override fun createTarget(name: String): R {
|
||||
val result = instantiateTarget().apply {
|
||||
targetName = name
|
||||
disambiguationClassifier = provideTargetDisambiguationClassifier(this@apply)
|
||||
preset = this@KotlinOnlyTargetPreset
|
||||
|
||||
+2
-2
@@ -16,14 +16,14 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTargetConfigurator
|
||||
open class KotlinJsTargetPreset(
|
||||
project: Project,
|
||||
kotlinPluginVersion: String
|
||||
) : KotlinOnlyTargetPreset<KotlinJsCompilation>(
|
||||
) : KotlinOnlyTargetPreset<KotlinJsTarget, KotlinJsCompilation>(
|
||||
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)
|
||||
|
||||
|
||||
+1
@@ -46,6 +46,7 @@ fun parseNodeJsStackTrace(stackTrace: String): NodeJsStackTrace {
|
||||
var firstLines = true
|
||||
val stack = mutableListOf<NodeJsStackTraceElement>()
|
||||
|
||||
// see examples at NodeJsStackTraceParserKtTest
|
||||
stackTrace.lines().forEach {
|
||||
val srcLine = it.trim()
|
||||
|
||||
|
||||
-1
@@ -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,
|
||||
|
||||
+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.
|
||||
* 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()
|
||||
|
||||
+3
-3
@@ -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()
|
||||
|
||||
-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
|
||||
|
||||
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<Entry>) {
|
||||
val resolved: String?,
|
||||
val integrity: String?,
|
||||
val dependencies: List<Dependency>
|
||||
) {
|
||||
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 {
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ open class KotlinNativeTest : KotlinTest() {
|
||||
val clientSettings = TCServiceMessagesClientSettings(
|
||||
name,
|
||||
testNameSuffix = targetName,
|
||||
prepandSuiteName = targetName != null,
|
||||
prependSuiteName = targetName != null,
|
||||
treatFailedTestOutputAsStacktrace = true,
|
||||
stackTraceParser = ::parseKotlinNativeStackTraceAsJvm
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user