diff --git a/build.gradle.kts b/build.gradle.kts index 8e2e73d..c802f4b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,8 @@ plugins { base `project-report` `build-dashboard` + + kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" @@ -15,7 +17,7 @@ val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) val projectTokens: MapProperty by extra { objects.mapProperty().apply { - put("project.version", provider { "$version" }) + put("project.version", provider { "${project.version}" }) put("rootProject.name", provider { rootProject.name }) put("date.year", provider { "${LocalDate.now().year}" }) put("author.email", "adam@adamko.dev") diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 71a85d1..3bb8f13 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -3,7 +3,9 @@ package dev.adamko.kafkatorio.gradle import java.io.ByteArrayOutputStream import org.gradle.api.Project import org.gradle.api.file.Directory +import org.gradle.api.file.FileCopyDetails import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RelativePath import org.gradle.api.specs.NotSpec import org.gradle.api.specs.Spec import org.gradle.plugins.ide.idea.model.IdeaModule @@ -14,8 +16,8 @@ import org.jetbrains.kotlin.incremental.md5 operator fun Spec.not(): NotSpec = NotSpec(this) -// -// + + //fun isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = // Spec { // ByteArrayOutputStream().use { outputStream -> @@ -59,6 +61,7 @@ fun Project.execCapture(spec: ExecSpec.() -> Unit): String { } } + /** https://youtrack.jetbrains.com/issue/KT-50848 */ fun Project.yarn(configure: YarnRootExtension.() -> Unit) = with(yarn, configure) @@ -68,3 +71,8 @@ fun Directory.filesChecksum() = asFileTree .map { it.readBytes() + it.absolutePath.toByteArray() } .fold(byteArrayOf()) { acc, bytes -> acc + bytes } .md5() + + +/** Drop the first [count] directories from the path */ +fun FileCopyDetails.dropDirectories(count: Int = 1): RelativePath = + RelativePath(true, *relativePath.segments.drop(count).toTypedArray()) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 4a309db..59c1c21 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -16,11 +16,14 @@ node { distBaseUrl.set(null as String?) // set by dependencyResolutionManagement } +val projectVersion: Provider = providers.provider { "${project.version}" } + val updatePackageJson by tasks.registering(UpdatePackageJson::class) { // group = NodePlugin.NODE_GROUP // description = "Read the package.json file and update the version and name, based on the project." - propertiesToCheck.put("version", providers.provider { "${project.version}" }) + inputs.property("projectVersion", projectVersion) + propertiesToCheck.put("version", projectVersion) // check to see if the properties are already up-to-date // outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt new file mode 100644 index 0000000..51b7032 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt @@ -0,0 +1,35 @@ +package dev.adamko.kafkatorio.task + +import javax.inject.Inject +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.tasks.JavaExec +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + + +abstract class GenerateTypescriptTask @Inject constructor( + private val fileOps: FileSystemOperations, +) : JavaExec() { + + @get:OutputDirectory + abstract val output: DirectoryProperty + + init { + group = "kt2ts" + } + + @TaskAction + fun generate() { + fileOps.delete { delete(temporaryDir) } + temporaryDir.mkdirs() + + super.exec() + + fileOps.sync { + from(temporaryDir) + into(output) + include("**/*.ts") + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 418bfdd..32ebb08 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -19,7 +19,9 @@ import org.gradle.kotlin.dsl.support.useToRun import org.jetbrains.kotlin.util.suffixIfNot @CacheableTask -abstract class UpdatePackageJson : DefaultTask() { +abstract class UpdatePackageJson @Inject constructor( + private val providers: ProviderFactory +) : DefaultTask() { @get:Input abstract val propertiesToCheck: MapProperty @@ -27,15 +29,10 @@ abstract class UpdatePackageJson : DefaultTask() { @get:OutputFile abstract val packageJsonFile: RegularFileProperty - @get:Inject - abstract val providers: ProviderFactory -// -// @get:Inject -// abstract val fs: FileSystemOperations - init { group = NodePlugin.NODE_GROUP - description = "Read the package.json file and update the version and name, based on the project." + description = + "Read the package.json file and update the version and name, based on the project." outputs.upToDateWhen(JsonPropertiesUpToDateSpec) @@ -47,12 +44,13 @@ abstract class UpdatePackageJson : DefaultTask() { @TaskAction fun exec() { - val pj = packageJsonFile.asFile.get() + val packageJsonFile = packageJsonFile.asFile.get() + val propertiesToCheck = propertiesToCheck.get() - logger.info("updating package.json ${pj.canonicalPath}") - val packageJson = jsonMapper.parseToJsonElement(pj.readText()).jsonObject + logger.info("updating package.json ${packageJsonFile.canonicalPath}") + val packageJson = jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject - val newJsonProps = propertiesToCheck.get().mapValues { (_, newVal) -> JsonPrimitive(newVal) } + val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } val packageJsonUpdate = JsonObject(packageJson + newJsonProps) val packageJsonContentUpdated = @@ -62,7 +60,7 @@ abstract class UpdatePackageJson : DefaultTask() { logger.debug(packageJsonContentUpdated) - packageJsonFile.get().asFile.writer().useToRun { + packageJsonFile.writer().useToRun { write(packageJsonContentUpdated) } } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index acd0431..b6d4976 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider +import dev.adamko.kafkatorio.gradle.dropDirectories import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.TypescriptToLuaTask @@ -11,15 +12,15 @@ plugins { distribution } -description = - "Sends in-game information to a server over the internet (requires Kafkatorio Kafka-Pipe)" +description = "Sends in-game information to a server over the internet (requires additional setup)" // Factorio required format is: // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` + val modName: String by extra { "${rootProject.name}-events" } -val distributionZipName: String by extra { "${modName}_${project.version}.zip" } +val distributionZipName: String by extra { "${modName}_${rootProject.version}.zip" } // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) val modFactorioCompatibility: Provider = @@ -27,10 +28,11 @@ val modFactorioCompatibility: Provider = val licenseFile: RegularFile by rootProject.extra val projectTokens: MapProperty by rootProject.extra +val modDescription: String by project.extra { project.description ?: "" } projectTokens.apply { put("mod.name", modName) put("mod.title", "Kafkatorio Events") - put("mod.description", provider { project.description }.orElse("")) + put("mod.description", modDescription) put("factorio.version", modFactorioCompatibility) } @@ -41,6 +43,7 @@ node { nodeProjectDir.set(tsSrcDir) } + val typescriptEventsSchema: Configuration by configurations.creating { description = "Fetch the TypeScript schema from the event-schema subproject" asConsumer() @@ -82,9 +85,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { } ) { // drop the first directory inside the zip - eachFile { - relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) - } + eachFile { relativePath = dropDirectories() } includeEmptyDirs = false } into(outputDir) @@ -123,7 +124,6 @@ distributions { } } } - } } @@ -163,8 +163,11 @@ val factorioModProvider by configurations.registering { } +val packageJsonName = providers.provider { "${rootProject.name}-${project.name}" } + tasks.updatePackageJson { - propertiesToCheck.put("name", providers.provider { "${rootProject.name}-${project.name}" }) + inputs.property("packageJsonName", packageJsonName) + propertiesToCheck.put("name", packageJsonName) packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 4e784c9..3bbfd52 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes +import dev.adamko.kafkatorio.task.GenerateTypescriptTask plugins { @@ -106,56 +107,78 @@ kotlin { } } +val jvmJar: TaskProvider = tasks.named(kotlin.jvm().artifactsTaskName) +val mainCompilation: Provider = + kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } -val generateTypescript by tasks.registering(JavaExec::class) { - group = "kt2ts" - val jvmJar = tasks.named(kotlin.jvm().artifactsTaskName) +val generateTypescript by tasks.registering(GenerateTypescriptTask::class) { dependsOn(jvmJar) - - val mainCompilation = kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } -// dependsOn(mainCompilation) - inputs.files(mainCompilation) - classpath( jvmJar, - mainCompilation + mainCompilation, ) - -// mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") + output.set(layout.buildDirectory.dir("generated/typescript")) mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") + args(temporaryDir.canonicalPath) +} - val tempOutputDirectory = file("$temporaryDir") - args(tempOutputDirectory) +//val generateTypescript2 by tasks.registering(JavaExec::class) { +// group = "kt2ts" +// +// dependsOn(jvmJar) +// +// inputs.files(mainCompilation) +// +// classpath( +// jvmJar, +// mainCompilation, +// ) +// mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") +// +// args(temporaryDir) +// +// val buildOutput = layout.buildDirectory.dir("generated/typescript") +// outputs.dir(buildOutput) +// +// doFirst { +// delete(temporaryDir) +// mkdir(temporaryDir) +// } +// +// doLast { +// sync { +// from(temporaryDir) +// into(buildOutput) +// include("**/*.ts") +// } +// } +//} - val buildOutput = layout.buildDirectory.dir("generated/typescript") - outputs.dir(buildOutput) - - doFirst { - delete(temporaryDir) - mkdir(temporaryDir) - } - - doLast { - sync { - from(temporaryDir) - into(buildOutput) - include("**/*.ts") - } - } +val schemaTsDistributionName = providers.provider { + "${rootProject.name}-${project.name}" } val schemaTs by distributions.registering { - distributionBaseName.set("${rootProject.name}-${project.name}") + distributionBaseName.set(schemaTsDistributionName) contents { from(generateTypescript.map { it.outputs.files.asFileTree }) } } +val schemaTsZipTask = tasks.named("${schemaTs.name}DistZip") + val typescriptModelGenerated: Configuration by configurations.creating { asProvider() typescriptAttributes(objects) - val schemaTsZipTask = tasks.named("${schemaTs.name}DistZip") outgoing.artifact(schemaTsZipTask.flatMap { it.archiveFile }) } + + +tasks.matching { + it.name == "jsGenerateExternalsIntegrated" +}.configureEach { + @Suppress("UnstableApiUsage") + notCompatibleWithConfigurationCache("try to prevent 'Projects must be configuring' error") +}