[Gradle, JS] Refactor with coroutines

This commit is contained in:
Ilya Goncharov
2020-09-11 19:35:33 +03:00
parent 4986e8c9cc
commit a86dd8b5ba
5 changed files with 121 additions and 39 deletions
@@ -3,8 +3,20 @@ plugins {
} }
dependencies { dependencies {
// implementation(project(":kotlin-gradle-plugin"))
implementation("io.ktor:ktor-client-cio:1.4.0") implementation("io.ktor:ktor-client-cio:1.4.0")
implementation("com.google.code.gson:gson:${rootProject.extra["versions.jar.gson"]}") implementation("com.google.code.gson:gson:${rootProject.extra["versions.jar.gson"]}")
implementation("org.apache.velocity:velocity:1.7")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC")
}
val generateNpmVersions by generator(
"org.jetbrains.kotlin.generators.gradle.targets.js.MainKt",
sourceSets["main"]
)
listOf(generateNpmVersions).forEach {
it.systemProperty(
"org.jetbrains.kotlin.generators.gradle.targets.js.outputSourceRoot",
project(":kotlin-gradle-plugin").projectDir.resolve("src/main/kotlin").absolutePath
)
} }
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2020 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 org.jetbrains.kotlin.generators.gradle.targets.js
data class Package(
val name: String,
val version: SemVer
) {
// Used in velocity template
@Suppress("unused")
fun camelize(): String =
name
.split("-")
.mapIndexed { index, item -> if (index == 0) item else item.capitalize() }
.joinToString("")
}
data class PackageInformation(
val name: String,
val versions: Set<String>
)
@@ -18,35 +18,44 @@ import kotlin.coroutines.CoroutineContext
class VersionFetcher( class VersionFetcher(
private val coroutineContext: CoroutineContext private val coroutineContext: CoroutineContext
) { ) : AutoCloseable {
private val client = HttpClient() private val client = HttpClient()
suspend fun fetch(): List<PackageInformation> { suspend fun fetch(): List<PackageInformation> {
return withContext(coroutineContext) { return npmPackages
npmPackages .map { fetchPackageInformationAsync(it) }
.map { packageName -> .map { fetched ->
val packagePath = val (packageName, value) = fetched.await()
if (packageName.startsWith("@")) val fetchedPackageInformation = Gson().fromJson(value, FetchedPackageInformation::class.java)
"@" + encodeURIComponent(packageName) PackageInformation(
else packageName,
encodeURIComponent(packageName) fetchedPackageInformation.versions.keys
)
}
}
val fetch = async<String> { private suspend fun fetchPackageInformationAsync(packageName: String) =
client.get("http://registry.npmjs.org/$packagePath") withContext(coroutineContext) {
} val packagePath =
if (packageName.startsWith("@"))
"@" + encodeURIComponent(packageName)
else
encodeURIComponent(packageName)
val fetchedPackageInformation = Gson().fromJson(fetch.await(), FetchedPackageInformation::class.java) async {
PackageInformation( packageName to client.get<String>("http://registry.npmjs.org/$packagePath")
packageName, }
fetchedPackageInformation.versions.keys
)
}.also {
client.close()
}
} }
override fun close() {
client.close()
} }
} }
private data class FetchedPackageInformation(
val versions: Map<String, Any>
)
fun encodeURIComponent(s: String): String { fun encodeURIComponent(s: String): String {
return try { return try {
URLEncoder.encode(s, StandardCharsets.UTF_8.name()) URLEncoder.encode(s, StandardCharsets.UTF_8.name())
@@ -59,18 +68,4 @@ fun encodeURIComponent(s: String): String {
} catch (e: UnsupportedEncodingException) { } catch (e: UnsupportedEncodingException) {
s s
} }
} }
data class PackageInformation(
val name: String,
val versions: Set<String>
)
data class Package(
val name: String,
val version: SemVer
)
data class FetchedPackageInformation(
val versions: Map<String, Any>
)
@@ -6,14 +6,47 @@
package org.jetbrains.kotlin.generators.gradle.targets.js package org.jetbrains.kotlin.generators.gradle.targets.js
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.apache.velocity.VelocityContext
import org.apache.velocity.app.Velocity
import org.apache.velocity.app.VelocityEngine
import org.apache.velocity.runtime.RuntimeConstants.RESOURCE_LOADER
import java.io.File
fun main() { fun main() {
val outputSourceRoot = System.getProperties()["org.jetbrains.kotlin.generators.gradle.targets.js.outputSourceRoot"]
val packageName = "org.jetbrains.kotlin.gradle.targets.js"
val className = "NpmVersions"
val fileName = "$className.kt"
val targetFile = File("$outputSourceRoot")
.resolve(packageName.replace(".", "/"))
.resolve(fileName)
val context = VelocityContext()
.apply {
put("package", packageName)
put("class", className)
}
val velocityEngine = VelocityEngine().apply {
setProperty(RESOURCE_LOADER, "class")
setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader")
init()
}
val template = velocityEngine.getTemplate("$fileName.vm")
runBlocking { runBlocking {
val packages = VersionFetcher(coroutineContext).fetch() val packages = VersionFetcher(coroutineContext).use {
it.fetch()
}
findLastVersions(packages) findLastVersions(packages)
.forEach { .also {
println(it) context.put("dependencies", it)
} }
targetFile.writer().use {
template.merge(context, it)
}
} }
} }
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2020 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 $package
/**
* Package versions used by tasks
*/
// DO NOT MODIFY DIRECTLY! Use org.jetbrains.kotlin.generators.gradle.targets.js.MainKt
class $class {
#foreach( $dep in $dependencies )
val $dep.camelize() = NpmPackageVersion("$dep.name", "$dep.version")
#end
val kotlinJsTestRunner = KotlinGradleNpmPackage("test-js-runner")
}