properly generate and collect and create source sets for jvm+kt+ts (but kotlin multiplatform js doesn't work????)

todo: clean up this is really messy
This commit is contained in:
Adam 2021-11-02 23:22:30 +01:00
parent 00b3dc3554
commit ac8428f36d
6 changed files with 167 additions and 280 deletions

View file

@ -1,13 +1,6 @@
plugins {
idea
base
// val kotlinVersion = "1.5.31"
// kotlin("jvm") version kotlinVersion apply false
// kotlin("js") version kotlinVersion apply false
// kotlin("multiplatform") version kotlinVersion apply false
// id("com.github.node-gradle.node") version "3.1.1" apply false
}
group = "dev.adamko.factoriowebmap"

View file

@ -1,5 +1,6 @@
package dev.adamko.gradle.pbandg.pattern
import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.findByType
@ -18,30 +19,36 @@ class KotlinMultiplatformProjectConfiguration : Plugin<Project> {
project.extensions.findByType<KotlinMultiplatformExtension>()?.apply {
project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}")
sourceSets.whenObjectAdded {
this.name
// sourceSets.whenObjectAdded {
// this.name
// }
//
val jvmProto = this.sourceSets.maybeCreate("jvmProto").apply {
kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/java"))
kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/kotlin"))
dependsOn(sourceSets.maybeCreate("jvmMain"))
}
//
val protoJvm = this.sourceSets.maybeCreate("protoJvm").apply {
kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java"))
kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin"))
val tsProto = this.sourceSets.maybeCreate("tsProto").apply {
kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/typescript"))
dependsOn(sourceSets.maybeCreate("jsMain"))
}
val protoTypescript = this.sourceSets.maybeCreate("protoJvm").apply {
kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript"))
}
this.sourceSets.findByName("jvmMain")?.apply {
// protoJvm.dependsOn(this)
// dependsOn(protoJvm)
kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java"))
kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin"))
}
this.sourceSets.findByName("jsMain")?.apply {
// protoTypescript.dependsOn(this)
// dependsOn(protoTypescript)
kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript"))
}
// this.sourceSets.findByName("jvmMain")?.apply {
//// protoJvm.dependsOn(this)
//// dependsOn(protoJvm)
// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java"))
// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin"))
// }
// this.sourceSets.findByName("jsMain")?.apply {
//// protoTypescript.dependsOn(this)
//// dependsOn(protoTypescript)
// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript"))
// }
project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}")

View file

@ -1,16 +1,11 @@
package dev.adamko.gradle.pbandg
import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir
import dev.adamko.gradle.pbandg.pattern.KotlinJvmProjectConfiguration
import dev.adamko.gradle.pbandg.pattern.KotlinMultiplatformProjectConfiguration
import dev.adamko.gradle.pbandg.settings.PBAndGSettings
import dev.adamko.gradle.pbandg.task.ProtobufCompileTask
import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask
import dev.adamko.gradle.pbandg.task.options.ProtocOutput.JavaOutput
import dev.adamko.gradle.pbandg.task.options.ProtocOutput.KotlinOutput
//plugins {
// `kotlin-dsl`
//}
plugins {
base
@ -63,6 +58,9 @@ project.dependencies {
protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1")
// implementation("com.google.protobuf:protobuf-javalite:3.19.1")
// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1")
// protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1")
//// implementation("com.google.protobuf:protobuf-javalite:3.19.1")
//// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1")
}
val protobufPrepareLibrariesTask =
@ -70,12 +68,6 @@ val protobufPrepareLibrariesTask =
librarySources.set(protobufLibraryDependencies)
}
//project.dependencies {
// protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1")
//// implementation("com.google.protobuf:protobuf-javalite:3.19.1")
//// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1")
//}
project.tasks.withType<ProtobufCompileTask> {
dependsOn(protocDep, protobufPrepareLibrariesTask)
protobufLibraryDirectories.add(protobufPrepareLibrariesTask.flatMap { it.librariesDirectory })
@ -85,10 +77,25 @@ project.tasks.withType<ProtobufCompileTask> {
protocExecutable.set(exe)
}
/** Convert `.proto` files to Kotlin */
val pbCompileTask = project.tasks.register<ProtobufCompileTask>(Constants.PBG_TASK_COMPILE) {
protocOutputs += KotlinOutput()
protocOutputs += JavaOutput()
}
val aggregateTask = project.tasks.register<Sync>("protobufCompileAll") {
group = Constants.PBG_TASK_GROUP
dependsOn(tasks.withType<ProtobufCompileTask>())
val genSrcDir = project.layout.pbAndGBuildDir.map { it.dir("generated-sources") }
val pbCompileTasks = tasks.withType<ProtobufCompileTask>()
from(pbCompileTasks.map { it.temporaryDir })
into(genSrcDir)
includeEmptyDirs = false
}
//project.tasks.assemble { dependsOn(aggregateTask) }
///** Convert `.proto` files to Kotlin */
//val pbCompileTask = project.tasks.create<ProtobufCompileTask>("protobufJava") {
// protocOutputs += KotlinOutput()
// protocOutputs += JavaOutput()
//}
project.tasks.assemble { dependsOn(pbCompileTask) }

View file

@ -1,36 +1,32 @@
package dev.adamko.gradle.pbandg.task
import dev.adamko.gradle.pbandg.Constants
import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir
import dev.adamko.gradle.pbandg.task.options.ProtocOutput
import org.gradle.api.DefaultTask
import org.gradle.api.DomainObjectSet
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.property
import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir
abstract class ProtobufCompileTask : DefaultTask() {
@get:InputFile
abstract val protocExecutable: RegularFileProperty
@get:OutputDirectory
val generatedSources: DirectoryProperty = project.objects.directoryProperty()
.convention(project.pbAndGBuildDir.map { it.dir("generated-sources") })
@get:InputFiles
abstract val protobufLibraryDirectories: ListProperty<Directory>
@get:Input
abstract val protocOutputs: DomainObjectSet<ProtocOutput>
// @get:Input
// abstract val protocOutputs: DomainObjectSet<ProtocOutput>
// = project.objects.domainObjectSet(ProtocOutput::class.java)
@get:Input
@ -43,35 +39,37 @@ abstract class ProtobufCompileTask : DefaultTask() {
val cliParamProtoPath: Property<String> =
project.objects.property<String>().convention("--proto_path=")
@get:OutputDirectory
val outputDir: RegularFileProperty =
project.objects.fileProperty().convention { temporaryDir }
// @get:Internal
// val outputPath: Provider<String> = outputDir.map { it.asFile.canonicalPath }
init {
group = Constants.PBG_TASK_GROUP
}
@TaskAction
fun compile() {
val workDir = temporaryDir
// project.delete(workDir)
// prepare directories
project.mkdir(outputDir)
project.exec {
executable(protocExecutable.asFile.get())
workingDir(workDir)
workingDir(outputDir.asFile.get())
// prepare directories
project.mkdir(workingDir)
project.mkdir(generatedSources)
val mapOutputsToOutputDir =
protocOutputs.associateWith { workingDir.resolve(it.outputDirectoryName) }
mapOutputsToOutputDir.values.forEach { project.mkdir(it) }
// set args
mapOutputsToOutputDir
.map { (opt, dir) ->
val optionsSuffix = if (opt.protocOptions.isBlank()) "" else ":"
"${opt.cliParam}=${opt.protocOptions}$optionsSuffix$dir"
}
.also { args(it) }
// val mapOutputsToOutputDir =
// protocOutputs.associateWith { outputDir.get().asFile.resolve(it.outputDirectoryName) }
// mapOutputsToOutputDir.values.forEach { project.mkdir(it) }
//
// // set args
// mapOutputsToOutputDir
// .map { (opt, dir) ->
// val optionsSuffix = if (opt.protocOptions.isBlank()) "" else ":"
// "${opt.cliParam}=${opt.protocOptions}$optionsSuffix$dir"
// }
// .also { args(it) }
args(cliArgs.get())
val protoPath = cliParamProtoPath.get()
@ -83,76 +81,6 @@ abstract class ProtobufCompileTask : DefaultTask() {
args("$targetProtoFile")
}
// sync compiled files
project.sync {
from(workDir)
into(generatedSources)
includeEmptyDirs = false
}
// clean up temp-dir
project.delete(workDir)
}
}
/*
{
group = "protobuf"
dependsOn(protobufCompiler, protoLibsTask)
standardOutput = System.out
executable(protobufCompiler.singleFile)
workingDir(temporaryDirFactory)
val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources")
outputs.dir(outDir)
val protoLibsDir: Provider<File> = protoLibsTask.map { it.destinationDir }
val javaOut = workingDir.resolve("java")
val kotlinOut = workingDir.resolve("kotlin")
val protoFile by project.objects.fileProperty()
.convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto"))
val protoFileParent = project.provider { protoFile.asFile.parentFile }
val isLiteEnabled: Boolean by project.objects.property<Boolean>().convention(true)
doFirst {
project.delete(workingDir)
project.mkdir(outDir)
project.mkdir(javaOut)
project.mkdir(kotlinOut)
val liteOpt: String = when (isLiteEnabled) {
true -> "lite:"
false -> ""
}
args(
parseSpaceSeparatedArgs(
"""
--proto_path=${protoLibsDir.get()}
--proto_path=${protoFileParent.get()}
--java_out=$liteOpt$javaOut
--kotlin_out=$liteOpt$kotlinOut
$protoFile
"""
)
)
}
doLast {
project.sync {
from(workingDir)
into(outDir)
}
project.delete(workingDir)
}
}
*/

View file

@ -1,6 +1,6 @@
import dev.adamko.gradle.pbandg.task.ProtobufCompileTask
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
//import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
//import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
plugins {
id("dev.adamko.factoriowebmap.archetype.base")
@ -21,31 +21,25 @@ dependencies {
// api("com.google.protobuf:protobuf-kotlin-lite:3.19.1")
}
idea {
workspace {
}
}
kotlin {
sourceSets.all {
languageSettings.apply {
languageVersion = "1.5"
// enableLanguageFeature("InlineClasses") // language feature name
optIn("kotlin.OptIn")
optIn("kotlin.ExperimentalStdlibApi")
optIn("kotlin.time.ExperimentalTime")
optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
optIn("kotlin.js.ExperimentalJsExport")
// progressiveMode = true // false by default
}
}
// sourceSets.all {
// languageSettings.apply {
// languageVersion = "1.5"
//// enableLanguageFeature("InlineClasses") // language feature name
// optIn("kotlin.OptIn")
// optIn("kotlin.ExperimentalStdlibApi")
// optIn("kotlin.time.ExperimentalTime")
// optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
// optIn("kotlin.js.ExperimentalJsExport")
//// progressiveMode = true // false by default
// }
// }
//<editor-fold desc="Protobuf">
sourceSets {
val proto by creating {
}
}
// sourceSets {
// val proto by creating {
// }
// }
//</editor-fold>
//<editor-fold desc="Java">
@ -57,6 +51,22 @@ kotlin {
}
}
//</editor-fold>
//<editor-fold desc="JS">
// js(IR) {
// binaries.executable()
//// browser {
////// commonWebpackConfig {
////// cssSupport.enabled = true
////// }
//// }
//
// useCommonJs()
// nodejs()
//
// }
sourceSets {
val jvmMain by getting {
dependencies {
@ -66,74 +76,18 @@ kotlin {
}
val jvmTest by getting {
}
}
//</editor-fold>
//<editor-fold desc="JS">
js(IR) {
binaries.executable()
browser {
commonWebpackConfig {
cssSupport.enabled = true
}
}
useCommonJs()
nodejs()
compilations["main"].apply {
packageJson {
customField(
"scripts",
mapOf(
"build" to "tstl",
"dev" to "tstl --watch",
)
)
}
}
}
sourceSets {
val jsMain by getting {
kotlin.srcDir("externals02")
// kotlin.srcDir("externals")
dependencies {
val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31"
implementation(
project.dependencies.enforcedPlatform(
"org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}"
)
)
// implementation("org.jetbrains.kotlin-wrappers:kotlin-react")
// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom")
// implementation(npm("react", "17.0.2"))
// implementation(npm("react-dom", "17.0.2"))
// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") {
// because("https://github.com/Kotlin/kotlinx-nodejs")
// }
// implementation(npm("typescript-to-lua", "1.0.1"))
// implementation(npm("typed-factorio", "0.7.1"))
// implementation(npm("lua-types", "2.11.0"))
// implementation(npm("typescript", "4.4.3"))
implementation(npm("ts-proto", "1.83.3"))
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
// val jsMain by getting {
// dependencies {
// implementation(npm("ts-proto", "1.83.3"))
// }
// }
//
// val jsTest by getting {
// dependencies {
// implementation(kotlin("test-js"))
// }
// }
}
//</editor-fold>
@ -142,58 +96,56 @@ kotlin {
//rootProject.tasks.withType<RootPackageJsonTask>().configureEach {
//}
val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class)
val nodePath: Directory by extra {
val file = rootPackageJson.rootPackageJson.parentFile.normalize()
logger.lifecycle("Kotlin/JS NODE_PATH: $file")
project.layout.dir(provider { file }).get()
}
val nodeModulesDir: Directory by extra {
val file = nodePath.dir(NpmProject.NODE_MODULES)
logger.lifecycle("Kotlin/JS NODE_MODULES: $file")
file
}
//val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class)
//val nodePath: Directory by extra {
// val file = rootPackageJson.rootPackageJson.parentFile.normalize()
// logger.lifecycle("Kotlin/JS NODE_PATH: $file")
// project.layout.dir(provider { file }).get()
//}
//
//val nodeModulesDir: Directory by extra {
// val file = nodePath.dir(NpmProject.NODE_MODULES)
// logger.lifecycle("Kotlin/JS NODE_MODULES: $file")
// file
//}
// build/js/node_modules/ts-proto/node_modules/.bin
tasks.protobufCompile {
//
tasks.register<ProtobufCompileTask>("protobufJava") {
description = "proto2java"
protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto"))
protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto"))
cliArgs.add("--java_out=lite:${project.mkdir("$temporaryDir/java").canonicalPath}")
}
tasks.create<ProtobufCompileTask>("protobufKotlin") {
description = "proto2kotlin"
protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto"))
cliArgs.add("--kotlin_out=lite:${project.mkdir("$temporaryDir/kotlin").canonicalPath}")
}
tasks.create<ProtobufCompileTask>("protobufTypescript") {
description = "proto2typescript"
// data class PluginTs(
// override val cliParam: String = "--plugin",
// override val protocOptions: String = "",
// override val outputDirectoryName: String =
// "${project.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd",
// ) : ProtocOutput
//
//
// data class OutputTs(
// override val cliParam: String = "--ts_proto_out",
// override val protocOptions: String = "",
// override val outputDirectoryName: String = "${project.buildDir}/pbAndG/generated-sources/typescript",
// ) : ProtocOutput
//
// protocOutputs.add(PluginTs())
// protocOutputs.add(OutputTs())
// linux:
// cliArgs.add("--plugin=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd")
// windows:
cliArgs.add("--plugin=protoc-gen-ts_proto=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd")
val outdir = temporaryDir.resolve("typescript")
val f: File = project.mkdir(outdir)
cliArgs.add("--ts_proto_out=${project.mkdir("$temporaryDir/typescript").canonicalPath}")
cliArgs.add("--ts_proto_out=${outdir.canonicalPath}")
cliArgs.add("--ts_proto_opt=useOptionals=true")
// cliArgs.add("--proto_path=${rootProject.rootDir}")
cliArgs.addAll(
"--ts_proto_opt=useOptionals=true",
"--ts_proto_opt=outputServices=false",
"--ts_proto_opt=outputJsonMethods=false",
"--ts_proto_opt=outputEncodeMethods=false",
"--ts_proto_opt=forceLong=string",
"--ts_proto_opt=forceLong=number",
"--ts_proto_opt=esModuleInterop=true",
"--ts_proto_opt=exportCommonSymbols=false",
// "--proto_path=${rootProject.rootDir}",
)
protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto"))
protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto"))
}

View file

@ -5,8 +5,8 @@ option java_multiple_files = true;
package dev.adamko.factorioevents;
import "google/protobuf/any.proto";
import "google/protobuf/timestamp.proto";
//import "google/protobuf/any.proto";
//import "google/protobuf/timestamp.proto";
message FactorioServerLogRecord {
string mod_version = 1;
@ -54,7 +54,7 @@ message LuaPlayer {
// https://lua-api.factorio.com/next/LuaEntity.html
message LuaEntity {
uint32 unit_number = 1; // (optional) unique ID
optional uint32 unit_number = 1; // (optional) unique ID
string name = 2;
string type = 3;
string status = 4; // https://lua-api.factorio.com/next/defines.html#defines.entity_status
@ -62,8 +62,8 @@ message LuaEntity {
bool is_active = 8;
bool is_moving = 9;
uint32 player_index = 50; // (optional) The player connected to this character or nil if none.
uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity.
optional uint32 player_index = 50; // (optional) The player connected to this character or nil if none.
optional uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity.
Colour colour = 100; // (optional)
}