diff --git a/build.gradle.kts b/build.gradle.kts index 1e6369a..bfca669 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ plugins { idea base `project-report` + `build-dashboard` } group = "dev.adamko.factoriowebmap" @@ -19,6 +20,6 @@ idea { } } -tasks.withType(HtmlDependencyReportTask::class).configureEach { - projects = project.allprojects -} +//tasks.withType(HtmlDependencyReportTask::class).configureEach { +// projects = project.allprojects +//} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts index 46b5d8c..999ef24 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -8,9 +8,6 @@ plugins { group = "${rootProject.group}.${project.name}" version = rootProject.version -val projectId by extra("fwm-${project.name}") -//val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) - val licenseFile: RegularFile by extra(rootProject.layout.projectDirectory.file("LICENSE")) val tokens: Map by extra( diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts new file mode 100644 index 0000000..c793c71 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts @@ -0,0 +1,23 @@ +package dev.adamko.factoriowebmap.archetype + +plugins { + id("dev.adamko.factoriowebmap.archetype.base") +} + +val processRunnerTaskGroup: String by extra("processes") + +val processRun by tasks.registering { + group = processRunnerTaskGroup +} + +val processKill by tasks.registering { + group = processRunnerTaskGroup +} + +val processRestart by tasks.registering { + group = processRunnerTaskGroup + + processKill.get().state + dependsOn(processKill) + finalizedBy(processRun) +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt new file mode 100644 index 0000000..e158817 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt @@ -0,0 +1,20 @@ +package dev.adamko.factoriowebmap.configurations + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.attributes.Bundling +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.LibraryElements +import org.gradle.api.attributes.Usage +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.named + +fun Configuration.factorioModAttributes(objects: ObjectFactory) = + attributes { factorioMod(objects) } + +fun AttributeContainer.factorioMod(objects: ObjectFactory) { + attribute(Usage.USAGE_ATTRIBUTE, objects.named("factorio")) + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES_AND_RESOURCES)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt b/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt new file mode 100644 index 0000000..0b00148 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt @@ -0,0 +1,21 @@ +package dev.adamko + +import java.io.ByteArrayOutputStream +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.specs.Spec +import org.gradle.kotlin.dsl.invoke + +operator fun Spec.not(): Spec = Spec { !this(it) } + +fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = + Spec { + ByteArrayOutputStream().use { outputStream -> + project.exec { + commandLine("tasklist") + standardOutput = outputStream + } + outputStream.toString() + .contains(process, ignoreCase) + } + } \ No newline at end of file diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts new file mode 100644 index 0000000..26413ae --- /dev/null +++ b/modules/events-mod/build.gradle.kts @@ -0,0 +1,235 @@ +import com.github.gradle.node.npm.task.NpmTask +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.asProvider +import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import dev.adamko.factoriowebmap.configurations.typescriptAttributes +import groovy.json.JsonOutput +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import org.apache.tools.ant.filters.ReplaceTokens +import org.gradle.kotlin.dsl.support.useToRun +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.jetbrains.kotlin.util.suffixIfNot + +plugins { + idea + id("dev.adamko.factoriowebmap.archetype.node") +} + +val tokens: Map by project.extra +val licenseFile: RegularFile by project.extra + +val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") + +node { + nodeProjectDir.set(tsSrcDir) +} + + +val dataModelTs by configurations.registering { + asConsumer() + typescriptAttributes(objects) + defaultDependencies { + project.dependencies.create(projects.modules.eventsSchema) + } +} + + +val typescriptToLua by tasks.registering(NpmTask::class) { + description = "Convert Typescript To Lua" + group = project.name + + dependsOn(tasks.npmInstall) + + execOverrides { standardOutput = System.out } + + npmCommand.set(listOf("run", "build")) + + inputs.dir(project.node.nodeProjectDir) + .skipWhenEmpty() + .withPropertyName("sourceFiles") + .withPathSensitivity(PathSensitivity.RELATIVE) + + val intermediateOutputDir = temporaryDir + args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) + val outputDir = layout.buildDirectory.dir("typescriptToLua") + outputs.dir(outputDir) + .withPropertyName("outputDir") + + ignoreExitValue.set(false) + + doFirst("clean") { + delete(intermediateOutputDir) + } + + doLast("syncTstlOutput") { + sync { + from(intermediateOutputDir) + into(outputDir) + } + } + +} + +val updatePackageJsonVersion by tasks.registering { + group = project.name + description = """ + Read the package.json file and set the version to be the project's version. + """.trimIndent() + + val projectVersion = "${project.version}" + inputs.properties( + "projectVersion" to projectVersion, + ) + + val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json") + outputs.file(packageJsonFile) + + val jsonFormatter = Json { + prettyPrint = true + prettyPrintIndent = " " + } + + onlyIf { + // check to see if the version is already up-to-date + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject + packageJson["version"]?.jsonPrimitive?.content != projectVersion + } + + doLast { + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject + val packageJsonUpdate = JsonObject( + packageJson + ("version" to JsonPrimitive(projectVersion)) + ) + val packageJsonContentUpdated = + jsonFormatter + .encodeToString(packageJsonUpdate) + .suffixIfNot("\n") + packageJsonFile.asFile.writer().useToRun { + write(packageJsonContentUpdated) + } + } +} + +val updateDataModel by tasks.registering(Sync::class) { + group = project.name + description = "Fetch the latest shared data-model" + + dependsOn(dataModelTs) + + from( + dataModelTs.map { c -> + c.incoming + .artifactView { lenient(true) } + .artifacts + .artifactFiles + .filter { file -> file.exists() } + } + ) + + into(layout.projectDirectory.dir("src/main/typescript/model")) +} + + +val packageMod by tasks.registering(Zip::class) { + description = "Package mod files into ZIP" + group = project.name + + dependsOn(typescriptToLua) + + inputs.properties(tokens) + + from(layout.projectDirectory.dir("src/main/resources/mod-data")) { + include("**/**") + filter("tokens" to tokens) + } + dependsOn(typescriptToLua) + from(licenseFile) + + into(rootProject.name) + + // Factorio required format is: + // - filename: `mod-name_version.zip` + // - zip contains one directory, `mod-name` + archiveFileName.set("${rootProject.name}_${project.version}.zip") + destinationDirectory.set(layout.buildDirectory.dir("dist")) + + doLast { + val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) + val outZip = "${archiveFileName.orNull}" + logger.lifecycle("Packaged mod into $outDir/$outZip") + } +} + + +val downloadFactorioApiDocs by tasks.registering { + group = project.name + + val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") + val apiFilename = File(target.path).name + val downloadedFile = file("$temporaryDir/$apiFilename") + + val apiFile = layout.buildDirectory.file(apiFilename) + outputs.file(apiFile) + + doLast { + + ant.invokeMethod( + "get", mapOf( + "src" to target, + "dest" to downloadedFile, + "verbose" to true, + ) + ) + + val json = downloadedFile.readText() + val prettyJson = JsonOutput.prettyPrint(json) + + apiFile.get().asFile.writeText(prettyJson) + + logger.lifecycle("Downloaded Factorio API json: $apiFile") + } +} + + +val factorioModProvider by configurations.registering { + asProvider() + factorioModAttributes(objects) + outgoing.artifact(packageMod) +} + + +tasks.assemble { dependsOn(updateDataModel, updatePackageJsonVersion) } +tasks.build { dependsOn(packageMod) } + + +// +//idea { +// // this doesn't work - no source sets? +// module { +// sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) +// excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) +// resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) +// resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) +// excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) +// } +//} +// +//val typescriptSrcSet = +// project.objects.sourceDirectorySet("typescript", "typescript").apply { +// srcDir(layout.projectDirectory.dir("src/main/typescript")) +// +// destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) +// compiledBy(tstlTask) { +// +// project.objects.directoryProperty().apply { +// set(modBuildDir.dir("typescriptToLua")) +// } +// } +// } diff --git a/modules/mod/src/main/resources/mod-data/changelog.txt b/modules/events-mod/src/main/resources/mod-data/changelog.txt similarity index 100% rename from modules/mod/src/main/resources/mod-data/changelog.txt rename to modules/events-mod/src/main/resources/mod-data/changelog.txt diff --git a/modules/mod/src/main/resources/mod-data/info.json b/modules/events-mod/src/main/resources/mod-data/info.json similarity index 100% rename from modules/mod/src/main/resources/mod-data/info.json rename to modules/events-mod/src/main/resources/mod-data/info.json diff --git a/modules/mod/src/main/resources/mod-data/thumbnail.png b/modules/events-mod/src/main/resources/mod-data/thumbnail.png similarity index 100% rename from modules/mod/src/main/resources/mod-data/thumbnail.png rename to modules/events-mod/src/main/resources/mod-data/thumbnail.png diff --git a/modules/mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts similarity index 100% rename from modules/mod/src/main/typescript/control.ts rename to modules/events-mod/src/main/typescript/control.ts diff --git a/modules/mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts similarity index 100% rename from modules/mod/src/main/typescript/events.ts rename to modules/events-mod/src/main/typescript/events.ts diff --git a/modules/mod/src/main/typescript/generated/data-model.ts b/modules/events-mod/src/main/typescript/model/data-model.ts similarity index 99% rename from modules/mod/src/main/typescript/generated/data-model.ts rename to modules/events-mod/src/main/typescript/model/data-model.ts index 8950029..15f67d9 100644 --- a/modules/mod/src/main/typescript/generated/data-model.ts +++ b/modules/events-mod/src/main/typescript/model/data-model.ts @@ -43,4 +43,4 @@ interface SurfaceData extends FactorioObjectData { index: uint; name: string; object_name: string; -} \ No newline at end of file +} diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json similarity index 99% rename from modules/mod/src/main/typescript/package-lock.json rename to modules/events-mod/src/main/typescript/package-lock.json index f4d614b..ab7b085 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.6", + "version": "0.0.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json similarity index 77% rename from modules/mod/src/main/typescript/package.json rename to modules/events-mod/src/main/typescript/package.json index 95396be..4bc733a 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -21,10 +20,7 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/events-mod/src/main/typescript/serdes/serdes.ts similarity index 100% rename from modules/mod/src/main/typescript/serdes/serdes.ts rename to modules/events-mod/src/main/typescript/serdes/serdes.ts diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json similarity index 100% rename from modules/mod/src/main/typescript/tsconfig.json rename to modules/events-mod/src/main/typescript/tsconfig.json diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts similarity index 89% rename from modules/factorio-events-processor/build.gradle.kts rename to modules/events-processor/build.gradle.kts index 216a19e..9b30683 100644 --- a/modules/factorio-events-processor/build.gradle.kts +++ b/modules/events-processor/build.gradle.kts @@ -11,14 +11,13 @@ description = """ """.trimIndent() val projectId: String by project.extra -val buildDir: Directory = layout.buildDirectory.dir(projectId).get() @Suppress("UnstableApiUsage") dependencies { implementation("org.apache.kafka:kafka-streams:3.0.0") - implementation(projects.modules.factorioEventsDataModel) + implementation(projects.modules.eventsSchema) // implementation("com.ionspin.kotlin:bignum:0.3.3") diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt diff --git a/modules/factorio-events-processor/src/main/resources/logback.xml b/modules/events-processor/src/main/resources/logback.xml similarity index 100% rename from modules/factorio-events-processor/src/main/resources/logback.xml rename to modules/events-processor/src/main/resources/logback.xml diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/events-schema/build.gradle.kts similarity index 91% rename from modules/factorio-events-data-model/build.gradle.kts rename to modules/events-schema/build.gradle.kts index a8ed8a2..c2a9332 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -6,9 +6,6 @@ plugins { kotlin("plugin.serialization") } -val projectId: String by project.extra -val buildDir: Directory = layout.buildDirectory.dir(projectId).get() - dependencies { implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt diff --git a/modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt b/modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt similarity index 100% rename from modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt rename to modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt diff --git a/modules/factorio-events-kafka-pipe/build.gradle.kts b/modules/factorio-events-kafka-pipe/build.gradle.kts deleted file mode 100644 index e36b82f..0000000 --- a/modules/factorio-events-kafka-pipe/build.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - -plugins { - id("dev.adamko.factoriowebmap.archetype.base") -} - -description = - """ - Send events from a Factorio server to a Kafka topic - """.trimIndent() - -val projectId: String by project.extra diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts new file mode 100644 index 0000000..a4415f5 --- /dev/null +++ b/modules/infra-factorio-client/build.gradle.kts @@ -0,0 +1,81 @@ +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import dev.adamko.isProcessRunning +import dev.adamko.not +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { + id("dev.adamko.factoriowebmap.archetype.process-runner") +} + +val tokens: Map by project.extra + +val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") +val factorioGameId = "427520" +val steamExe = """C:\Program Files (x86)\Steam\steam.exe""" + +val factorioMod: Configuration by configurations.creating { + asConsumer() + factorioModAttributes(objects) +} + +dependencies { + factorioMod(projects.modules.eventsMod) +} + +// +val deployModToClient by tasks.registering(Copy::class) { + description = "Copy the mod to the Factorio client" + group = project.name + + from(factorioMod) + into(clientModsDirectory) + + doLast { + logger.lifecycle("Copying mod from ${source.files} to $destinationDir") + } +} +// + +// +fun isFactorioRunning(): Spec = isProcessRunning("factorio.exe") + +val clientLaunch by tasks.registering(Exec::class) { + description = "Run Factorio Steam game client" + group = project.name + + onlyIf(!isFactorioRunning()) + + dependsOn(deployModToClient) + mustRunAfter(clientKill) + + commandLine = parseSpaceSeparatedArgs( +// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working +// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up + """ $steamExe -applaunch $factorioGameId --mp-connect localhost """ + ) + doFirst { logger.lifecycle("Launching factorio.exe") } +} + +val clientKill by tasks.registering(Exec::class) { + description = "Run Factorio Steam game client" + group = project.name + onlyIf(isFactorioRunning()) + commandLine = parseSpaceSeparatedArgs(""" taskkill /im factorio.exe """) + doFirst { logger.lifecycle("Killing factorio.exe") } +} +// + +tasks.build { dependsOn(deployModToClient) } + +tasks.processRun { + dependsOn( + deployModToClient, + clientLaunch, + ) +} + +tasks.processKill { + dependsOn(clientKill) +} + diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts new file mode 100644 index 0000000..9489d07 --- /dev/null +++ b/modules/infra-factorio-server/build.gradle.kts @@ -0,0 +1,77 @@ +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { + id("dev.adamko.factoriowebmap.archetype.process-runner") +} + +val tokens: Map by project.extra + +val modInfraDir: Directory = layout.projectDirectory.dir("infra") +val factorioServerDataDir: Directory = modInfraDir.dir("factorio-server") + +val factorioMod: Configuration by configurations.creating { + asConsumer() + factorioModAttributes(objects) +} + +dependencies { + factorioMod(projects.modules.eventsMod) +} + +val deployModToServer by tasks.registering(Copy::class) { + description = "Copy the mod to the Factorio Docker server" + group = project.name + + from(factorioMod) + into(factorioServerDataDir.dir("mods")) + + doLast { + logger.lifecycle("Copying mods ${source.files} to $destinationDir") + } +} + +// +val factorioServerStop = tasks.register("factorioServerStop") { + group = project.name + + mustRunAfter(deployModToServer) + + workingDir(modInfraDir) + commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") +} + +val factorioServerUp = tasks.register("factorioServerUp") { + group = project.name + + mustRunAfter(deployModToServer) + dependsOn(factorioServerStop) + + workingDir(modInfraDir) + commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") +} + +val factorioServerRestart: Task by tasks.creating { + group = project.name + + dependsOn(factorioServerStop, factorioServerUp) +} +// + +tasks.build { dependsOn(deployModToServer) } + +tasks.processRun { + description = "Build the mod, upload to Server and Client, and start both" + dependsOn( + deployModToServer, + factorioServerRestart, + ) +} + +tasks.processKill { + dependsOn( + factorioServerStop, + ) +} + diff --git a/modules/mod/infra/.env b/modules/infra-factorio-server/infra/.env similarity index 100% rename from modules/mod/infra/.env rename to modules/infra-factorio-server/infra/.env diff --git a/modules/mod/infra/.gitignore b/modules/infra-factorio-server/infra/.gitignore similarity index 100% rename from modules/mod/infra/.gitignore rename to modules/infra-factorio-server/infra/.gitignore diff --git a/modules/infra-factorio-server/infra/docker-compose.yml b/modules/infra-factorio-server/infra/docker-compose.yml new file mode 100644 index 0000000..12fe89d --- /dev/null +++ b/modules/infra-factorio-server/infra/docker-compose.yml @@ -0,0 +1,39 @@ +version: "3.9" + +services: + + factorio-server: + image: factoriotools/factorio:1.1.48 + # logging: + # driver: "json-file" + container_name: "factorio-server" + restart: "unless-stopped" + networks: + - "factorio-events-nw" + ports: + - "34197:34197/udp" # factorio + - "27015:27015/tcp" # rcon + volumes: + - "./factorio-server:/factorio" + # logging: + # driver: "mickyg/kafka-logdriver:latest" + # options: + # KAFKA_BROKER_ADDR: "kafka-kraft" + # LOG_TOPIC: "dockerlogs-factorio-server" + # LOG_TAG: "factorio-server" + + # environment: + # RCON_PORT: 27715 + # environment: + # - PUID=1000 + # - PGID=1000 + # - UPDATE_MODS_ON_START=true + # - USERNAME=FactorioUsername + # - TOKEN=FactorioToken + +networks: + kafka-nw: + name: "kafka-nw" + external: true + factorio-events-nw: + name: "factorio-events-nw" diff --git a/modules/mod/infra/factorioEvents.Dockerfile b/modules/infra-factorio-server/infra/factorioEvents.Dockerfile similarity index 100% rename from modules/mod/infra/factorioEvents.Dockerfile rename to modules/infra-factorio-server/infra/factorioEvents.Dockerfile diff --git a/modules/mod/infra/kafka-pipe.sh b/modules/infra-factorio-server/infra/kafka-pipe.sh similarity index 100% rename from modules/mod/infra/kafka-pipe.sh rename to modules/infra-factorio-server/infra/kafka-pipe.sh diff --git a/modules/mod/infra/kcat.conf b/modules/infra-factorio-server/infra/kcat.conf similarity index 100% rename from modules/mod/infra/kcat.conf rename to modules/infra-factorio-server/infra/kcat.conf diff --git a/modules/mod/infra/docker-compose.yml b/modules/infra-kafka-cluster/docker-compose.yml similarity index 60% rename from modules/mod/infra/docker-compose.yml rename to modules/infra-kafka-cluster/docker-compose.yml index 3b42704..75c7cc6 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/infra-kafka-cluster/docker-compose.yml @@ -2,35 +2,6 @@ version: "3.9" services: - factorio-server: - image: factoriotools/factorio:1.1.48 - # logging: - # driver: "json-file" - container_name: "factorio-server" - restart: "unless-stopped" - networks: - - "factorio-events-nw" - ports: - - "34197:34197/udp" # factorio - - "27015:27015/tcp" # rcon - volumes: - - "./factorio-server:/factorio" - # logging: - # driver: "mickyg/kafka-logdriver:latest" - # options: - # KAFKA_BROKER_ADDR: "kafka-kraft" - # LOG_TOPIC: "dockerlogs-factorio-server" - # LOG_TAG: "factorio-server" - - # environment: - # RCON_PORT: 27715 - # environment: - # - PUID=1000 - # - PGID=1000 - # - UPDATE_MODS_ON_START=true - # - USERNAME=FactorioUsername - # - TOKEN=FactorioToken - kafka: image: dev-adamko/kafka-kraft container_name: "kafka" @@ -74,10 +45,9 @@ services: # - "8083:8083" # - networks: kafka-nw: name: "kafka-nw" factorio-events-nw: name: "factorio-events-nw" - + external: true diff --git a/modules/mod/infra/kafka-server.properties b/modules/infra-kafka-cluster/kafka-server.properties similarity index 100% rename from modules/mod/infra/kafka-server.properties rename to modules/infra-kafka-cluster/kafka-server.properties diff --git a/modules/mod/infra/kafka.Dockerfile b/modules/infra-kafka-cluster/kafka.Dockerfile similarity index 100% rename from modules/mod/infra/kafka.Dockerfile rename to modules/infra-kafka-cluster/kafka.Dockerfile diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts new file mode 100644 index 0000000..2744f98 --- /dev/null +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.process-runner") +} + +description = "Send events from a Factorio server to a Kafka topic " + diff --git a/modules/factorio-events-kafka-pipe/.env b/modules/infra-kafka-pipe/src/.env similarity index 100% rename from modules/factorio-events-kafka-pipe/.env rename to modules/infra-kafka-pipe/src/.env diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml similarity index 100% rename from modules/factorio-events-kafka-pipe/docker-compose.yml rename to modules/infra-kafka-pipe/src/docker-compose.yml diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile b/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile similarity index 100% rename from modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile rename to modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh similarity index 100% rename from modules/factorio-events-kafka-pipe/kafka-pipe.sh rename to modules/infra-kafka-pipe/src/kafka-pipe.sh diff --git a/modules/factorio-events-kafka-pipe/readme.md b/modules/infra-kafka-pipe/src/readme.md similarity index 100% rename from modules/factorio-events-kafka-pipe/readme.md rename to modules/infra-kafka-pipe/src/readme.md diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts deleted file mode 100644 index e3004ed..0000000 --- a/modules/mod/build.gradle.kts +++ /dev/null @@ -1,318 +0,0 @@ -import com.github.gradle.node.npm.task.NpmTask -import dev.adamko.factoriowebmap.configurations.asConsumer -import dev.adamko.factoriowebmap.configurations.typescriptAttributes -import groovy.json.JsonOutput -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive -import org.apache.tools.ant.filters.ReplaceTokens -import org.gradle.kotlin.dsl.support.useToRun -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -import org.jetbrains.kotlin.util.suffixIfNot - -plugins { - idea - id("dev.adamko.factoriowebmap.archetype.node") -} - -val projectId: String by project.extra -val tokens: Map by project.extra - -val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") -val modBuildDir: Directory = layout.buildDirectory.dir(projectId).get() - -node { - nodeProjectDir.set(tsSrcDir) -} - -val tstlTask = tasks.register("typescriptToLua") { - description = "Convert Typescript To Lua" - group = projectId - - dependsOn(tasks.npmInstall) - - execOverrides { standardOutput = System.out } - - npmCommand.set(listOf("run", "build")) - - inputs.dir(project.node.nodeProjectDir) - .skipWhenEmpty() - .withPropertyName("sourceFiles") - .withPathSensitivity(PathSensitivity.RELATIVE) - - val intermediateOutputDir = temporaryDir - args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) - val outputDir: Directory = modBuildDir.dir("typescriptToLua") - outputs.dir(outputDir) - .withPropertyName("outputDir") - - ignoreExitValue.set(false) - - doFirst("clean") { - delete(intermediateOutputDir) - } - - doLast("syncTstlOutput") { - sync { - from(intermediateOutputDir) - into(outputDir) - } - } - -} - -val updatePackageJsonVersion by tasks.registering { - group = project.name - description = """ - Read the package.json file and set the version to be the project's version. - """.trimIndent() - - val projectVersion = "${project.version}" - inputs.properties( - "projectVersion" to projectVersion, - ) - - val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json") - outputs.file(packageJsonFile) - - val jsonFormatter = Json { - prettyPrint = true - prettyPrintIndent = " " - } - - onlyIf { - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject - packageJson["version"]?.jsonPrimitive?.content != projectVersion - } - - doFirst { - delete(temporaryDir) - mkdir(temporaryDir) - } - - doLast { - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject - val packageJsonUpdate = JsonObject( - packageJson + ("version" to JsonPrimitive(projectVersion)) - ) - val packageJsonContentUpdated = - jsonFormatter - .encodeToString(packageJsonUpdate) - .suffixIfNot("\n") - packageJsonFile.asFile.writer().useToRun { - write(packageJsonContentUpdated) - } - } -} - -tasks.assemble { dependsOn(updatePackageJsonVersion) } - - -val dataModelTs: Configuration by configurations.creating { - asConsumer() - typescriptAttributes(objects) -} - -dependencies { - dataModelTs(projects.modules.factorioEventsDataModel) -} - -val updateDataModel by tasks.registering(Sync::class) { - group = project.name - - dependsOn(dataModelTs) - - from( - dataModelTs.incoming - .artifactView { lenient(true) } - .artifacts - .artifactFiles - .filter { it.exists() } - ) - - into(layout.projectDirectory.dir("src/main/typescript/generated")) -} - -tasks.assemble { dependsOn(updateDataModel) } - - - -idea { - module { - sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) - excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) - resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) - resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) - excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) - } -} - -val typescriptSrcSet = - project.objects.sourceDirectorySet("typescript", "typescript").apply { - srcDir(layout.projectDirectory.dir("src/main/typescript")) - - destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) - compiledBy(tstlTask) { - - project.objects.directoryProperty().apply { - set(modBuildDir.dir("typescriptToLua")) - } - } - } - -val modPackageTask = tasks.register("packageMod") { - description = "Package mod files into ZIP" - group = projectId - - dependsOn(tstlTask) - - inputs.properties(tokens) - - from(layout.projectDirectory.dir("src/main/resources/mod-data")) { - include("**/**") - filter("tokens" to tokens) - } - from( - rootProject.layout.projectDirectory.file("LICENSE"), - tstlTask, - ) - - into(rootProject.name) - - // Factorio required format is: - // - filename: `mod-name_version.zip` - // - zip contains one directory, `mod-name` - archiveFileName.set("${rootProject.name}_${project.version}.zip") - destinationDirectory.set(modBuildDir.dir("dist")) - - doLast { - val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) - val outZip = "${archiveFileName.orNull}" - logger.lifecycle("Creating mod zip $outDir/$outZip") - } -} - -//tasks.build { dependsOn(tstlTask, modPackageTask) } - -val modInfraDir: Directory = layout.projectDirectory.dir("infra") -val factorioServerDataDir: Directory = modInfraDir.dir("factorio-server") - -val copyModToServerTask = tasks.register("copyModToServer") { - description = "Copy the mod to the Factorio Docker server" - group = "$projectId.factorioServer" - - dependsOn(modPackageTask) - - from(modPackageTask) - into(factorioServerDataDir.dir("mods")) - - doLast { - logger.lifecycle("Copying mod from ${source.files} to $destinationDir") - } -} - -val factorioServerStop = tasks.register("factorioServerStop") { - group = "$projectId.factorioServer" - - mustRunAfter(copyModToServerTask) - - workingDir(modInfraDir) - commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") -} - -val factorioServerUp = tasks.register("factorioServerUp") { - group = "$projectId.factorioServer" - - mustRunAfter(copyModToServerTask) - dependsOn(factorioServerStop) - - workingDir(modInfraDir) - commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") -} - -val factorioServerRestart: Task by tasks.creating { - group = "$projectId.factorioServer" - - dependsOn(factorioServerStop, factorioServerUp) -} - -//val serverRestartTask = tasks.register("dockerRestart") { -// group = "$projectId.factorioServer" -// -// workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile -// commandLine = parseSpaceSeparatedArgs("docker-compose restart") -//} - -val copyModToClientTask = tasks.register("copyModToClient") { - description = "Copy the mod to the Factorio client" - group = "$projectId.factorioClient" - - dependsOn(modPackageTask) - - from(modPackageTask) - into("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") - - doLast { - logger.lifecycle("Copying mod from ${source.files} to $destinationDir") - } -} - -//val factorioClientLaunch = tasks.register("launch") { -// description = "Run Factorio client" -// group = "$projectId.factorioClient" -// -// dependsOn( -// serverRestartTask, -// copyModToClientTask -// ) -// -//// workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile -// commandLine = parseSpaceSeparatedArgs( -// """explorer "steam://rungameid/427520 --mp-connect localhost" """ -// ) -//} - -val launch = tasks.register("modLauncher") { - description = "Build the mod, upload to Server and Client, and start both" - group = projectId - dependsOn( - copyModToServerTask, - copyModToClientTask, - factorioServerRestart, -// factorioClientLaunch, - ) -} - -tasks.register("downloadFactorioApiDocs") { - group = projectId - - val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") - val apiFilename = File(target.path).name - val downloadedFile = file("$temporaryDir/$apiFilename") - - val apiFile = modBuildDir.file(apiFilename) - outputs.file(apiFile) - - doLast { - - ant.invokeMethod( - "get", mapOf( - "src" to target, - "dest" to downloadedFile, - "verbose" to true, - ) - ) - - val json = downloadedFile.readText() - val prettyJson = JsonOutput.prettyPrint(json) - - apiFile.asFile.writeText(prettyJson) - - logger.lifecycle("Downloaded Factorio API json: $apiFile") - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index c0e4e8b..5c78149 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,11 +1,17 @@ -rootProject.name = "factorio-web-map" +rootProject.name = "kafkatorio" include( - ":modules:mod", + + ":modules:events-mod", + ":modules:events-processor", + ":modules:events-schema", + + ":modules:infra-factorio-client", + ":modules:infra-factorio-server", + ":modules:infra-kafka-cluster", + ":modules:infra-kafka-pipe", + ":modules:kt-rcon", - ":modules:factorio-events-data-model", - ":modules:factorio-events-processor", - ":modules:factorio-events-kafka-pipe", ) enableFeaturePreview("VERSION_CATALOGS")