move schema to kotlin-multiplatform

This commit is contained in:
Adam 2021-12-08 17:43:08 +01:00
parent 6d60428ab9
commit 1f88d6f464
11 changed files with 118 additions and 46 deletions

View file

@ -7,7 +7,7 @@ import kotlinx.serialization.json.jsonPrimitive
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.LogLevel import org.gradle.api.provider.MapProperty
import org.gradle.api.specs.Spec import org.gradle.api.specs.Spec
import org.gradle.kotlin.dsl.invoke import org.gradle.kotlin.dsl.invoke
@ -27,18 +27,23 @@ fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec<
fun Project.areJsonPropertiesUpToDate( fun Project.areJsonPropertiesUpToDate(
packageJsonFile: RegularFileProperty, packageJsonFile: RegularFileProperty,
properties: () -> Map<String, String> properties: MapProperty<String, String>
): Spec<Task> = Spec<Task> { ): Spec<Task> = Spec<Task> {
val packageJsonContent = packageJsonFile.get().asFile.readText() val packageJsonContent = packageJsonFile.get().asFile.readText()
val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject
properties().all { (key, expectedVal) -> properties.get().all { (key, expectedVal) ->
val actualVal = packageJson[key]?.jsonPrimitive?.content val actualVal = packageJson[key]?.jsonPrimitive?.content
(expectedVal == actualVal).also { val isUpToDate = expectedVal == actualVal
logger.log(
if (it) LogLevel.LIFECYCLE else LogLevel.INFO, if (isUpToDate) {
logger.info("package.json property is up to date, '$key = $actualVal'")
} else {
logger.lifecycle(
"package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)" "package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)"
) )
} }
isUpToDate
} }
} }

View file

@ -31,7 +31,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
propertiesToCheck.put("version", "${project.version}") propertiesToCheck.put("version", "${project.version}")
// check to see if the properties are already up-to-date // check to see if the properties are already up-to-date
onlyIf(!areJsonPropertiesUpToDate(packageJsonFile) { propertiesToCheck.get() }) onlyIf(!areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck))
doLast { doLast {
val packageJsonContent = packageJsonFile.get().asFile.readText() val packageJsonContent = packageJsonFile.get().asFile.readText()

View file

@ -18,8 +18,8 @@ kotlinx-serialization = "1.3.1"
kvision = "5.6.1" kvision = "5.6.1"
## test ## ## test ##
junit = "5.8.1" junit = "5.8.2"
kotest = "4.6.3" kotest = "5.0.1"
## infra ## ## infra ##
factorio = "1.1.48" factorio = "1.1.48"

View file

@ -55,7 +55,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) {
description = "Convert Typescript To Lua" description = "Convert Typescript To Lua"
group = project.name group = project.name
dependsOn(tasks.npmInstall, installEventsSchema) dependsOn(tasks.npmInstall, installEventsTsSchema)
execOverrides { standardOutput = System.out } execOverrides { standardOutput = System.out }
@ -84,23 +84,27 @@ val typescriptToLua by tasks.registering(NpmTask::class) {
into(outputDir) into(outputDir)
} }
} }
} }
val installEventsSchema by tasks.registering(Sync::class) { val installEventsTsSchema by tasks.registering(Sync::class) {
description = "Fetch the latest shared data-model" description = "Fetch the latest shared data-model"
group = project.name group = project.name
dependsOn(typescriptEventsSchema) dependsOn(typescriptEventsSchema)
val outputDir = layout.projectDirectory.dir("src/main/typescript/schema")
outputs.dir(outputDir)
from( from(
typescriptEventsSchema.incoming provider { typescriptEventsSchema }
.map { eventsSchema ->
eventsSchema.incoming
.artifactView { lenient(true) } .artifactView { lenient(true) }
.artifacts .artifacts
.artifactFiles .artifactFiles
.filter { file -> file.exists() } .filter { file -> file.exists() }
.files
.map { zipTree(it) } .map { zipTree(it) }
}
) { ) {
// drop the first directory inside the zip // drop the first directory inside the zip
eachFile { eachFile {
@ -108,8 +112,7 @@ val installEventsSchema by tasks.registering(Sync::class) {
} }
includeEmptyDirs = false includeEmptyDirs = false
} }
into(outputDir)
into(layout.projectDirectory.dir("src/main/typescript/schema"))
} }
tasks.distZip { tasks.distZip {
@ -210,7 +213,7 @@ tasks.updatePackageJson {
packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json"))
} }
tasks.assemble { dependsOn(installEventsSchema, tasks.updatePackageJson) } tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) }
// //
//idea { //idea {

View file

@ -2,29 +2,83 @@ import dev.adamko.kafkatorio.gradle.asProvider
import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes
plugins { plugins {
id("dev.adamko.kafkatorio.lang.kotlin-jvm") kotlin("multiplatform")
kotlin("plugin.serialization") kotlin("plugin.serialization")
distribution distribution
} }
kotlin {
js(IR) {
binaries.executable()
nodejs()
}
jvm()
@Suppress("UnstableApiUsage") // enforcedPlatform is incubating
sourceSets {
all {
languageSettings.apply {
optIn("kotlin.RequiresOptIn")
optIn("kotlin.ExperimentalStdlibApi")
optIn("kotlin.time.ExperimentalTime")
optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
optIn("kotlinx.serialization.ExperimentalSerializationApi")
}
}
val commonMain by getting {
dependencies { dependencies {
implementation(platform(libs.kotlinx.serialization.bom)) implementation(project.dependencies.enforcedPlatform(libs.kotlin.bom))
implementation(project.dependencies.enforcedPlatform(libs.kotlinx.serialization.bom))
implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json) implementation(libs.kotlinx.serialization.json)
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(project.dependencies.enforcedPlatform(libs.kotest.bom))
implementation("io.kotest:kotest-assertions-core")
implementation("io.kotest:kotest-property")
implementation("io.kotest:kotest-assertions-json")
}
}
val jvmMain by getting {
dependencies {
implementation("com.github.ntrrgc:ts-generator:1.1.2") implementation("com.github.ntrrgc:ts-generator:1.1.2")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation(libs.kotest.datatest)
} }
}
val jvmTest by getting {
dependencies {
implementation("io.kotest:kotest-runner-junit5")
}
}
}
}
val generateTypescript by tasks.registering(JavaExec::class) { val generateTypescript by tasks.registering(JavaExec::class) {
group = project.name group = project.name
val generatedFile = file("$temporaryDir/${project.name}.ts") val jvmJar by tasks.getting(Jar::class)
val main by kotlin.jvm().compilations.getting
classpath(
jvmJar,
main.runtimeDependencyFiles
)
classpath(sourceSets.main.map { it.runtimeClasspath })
mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt")
val generatedFile = file("$temporaryDir/${project.name}.ts")
args(generatedFile) args(generatedFile)
val buildOutput = layout.buildDirectory.dir("generated/typescript") val buildOutput = layout.buildDirectory.dir("generated/typescript")
@ -36,21 +90,25 @@ val generateTypescript by tasks.registering(JavaExec::class) {
} }
doLast { doLast {
sync { from(temporaryDir); into(buildOutput) } sync {
from(temporaryDir)
into(buildOutput)
include("**/*.ts")
}
} }
} }
distributions { val schemaTs by distributions.registering {
main {
distributionBaseName.set("${rootProject.name}-${project.name}") distributionBaseName.set("${rootProject.name}-${project.name}")
contents { contents {
from(generateTypescript.map { it.outputs.files.asFileTree }) from(generateTypescript.map { it.outputs.files.asFileTree })
} }
} }
}
val typescriptModelGenerated by configurations.registering { val typescriptModelGenerated : Configuration by configurations.creating {
asProvider() asProvider()
typescriptAttributes(objects) typescriptAttributes(objects)
outgoing.artifact(tasks.distZip.flatMap { it.archiveFile })
val schemaTsZipTask = tasks.named<Zip>("${schemaTs.name}DistZip")
outgoing.artifact(schemaTsZipTask.flatMap { it.archiveFile })
} }

View file

@ -3,6 +3,7 @@
package dev.adamko.kafkatorio.events.schema package dev.adamko.kafkatorio.events.schema
import kotlin.jvm.JvmInline
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View file

@ -1,7 +1,7 @@
package dev.adamko.kafkatorio.events.schema package dev.adamko.kafkatorio.events.schema
import kotlin.reflect.full.starProjectedType //import kotlin.reflect.full.starProjectedType
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonClassDiscriminator import kotlinx.serialization.json.JsonClassDiscriminator
@ -35,8 +35,12 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name"
sealed class FactorioObjectData { sealed class FactorioObjectData {
// workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664
// val objectName: String by lazy {
// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName
// }
val objectName: String by lazy { val objectName: String by lazy {
kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName serializer().descriptor.serialName
// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName
} }
// alternative: find the @SerialName annotation // alternative: find the @SerialName annotation

View file

@ -9,6 +9,7 @@ plugins {
kotlin { kotlin {
js(IR) { js(IR) {
// nodejs()
browser { browser {
runTask { runTask {
outputFileName = "main.bundle.js" outputFileName = "main.bundle.js"