UpdatePackageJson task is updated based on a json object, and move npm versions to libs.versions.toml

This commit is contained in:
Adam 2022-08-13 11:59:30 +02:00
parent 2733dc4f62
commit d9f5d6d46d
7 changed files with 152 additions and 58 deletions

View file

@ -3,12 +3,15 @@ package dev.adamko.kafkatorio.lang
import com.github.gradle.node.npm.task.NpmInstallTask import com.github.gradle.node.npm.task.NpmInstallTask
import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.Versions
import dev.adamko.kafkatorio.task.UpdatePackageJson import dev.adamko.kafkatorio.task.UpdatePackageJson
import kotlinx.serialization.json.put
plugins { plugins {
id("com.github.node-gradle.node") id("com.github.node-gradle.node")
id("dev.adamko.kafkatorio.base") id("dev.adamko.kafkatorio.base")
} }
node { node {
download.set(true) download.set(true)
version.set(Versions.node) version.set(Versions.node)
@ -23,7 +26,11 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
// 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."
inputs.property("projectVersion", projectVersion) inputs.property("projectVersion", projectVersion)
propertiesToCheck.put("version", projectVersion) // propertiesToCheck.put("version", projectVersion)
updateExpectedJson {
put("version", projectVersion.get())
}
// check to see if the properties are already up-to-date // check to see if the properties are already up-to-date
// outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) // outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck))

View file

@ -1,15 +1,23 @@
package dev.adamko.kafkatorio.task package dev.adamko.kafkatorio.task
import dev.adamko.kafkatorio.task.UpdatePackageJson.Companion.foldParseToJsonObject
import dev.adamko.kafkatorio.task.UpdatePackageJson.Companion.parseToJsonObject
import kotlinx.serialization.json.JsonObject
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.internal.specs.ExplainingSpec import org.gradle.api.internal.specs.ExplainingSpec
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
object JsonPropertiesUpToDateSpec : ExplainingSpec<Task> { object JsonPropertiesUpToDateSpec : ExplainingSpec<Task> {
private val logger: Logger = Logging.getLogger(this::class.java)
override fun isSatisfiedBy(element: Task?): Boolean { override fun isSatisfiedBy(element: Task?): Boolean {
val reason = whyUnsatisfied(element) val reason = whyUnsatisfied(element)
if (reason != null) { if (reason != null) {
println("JsonProperties not up to date:\n$reason") logger.lifecycle("JsonProperties not up to date:\n$reason")
} }
return reason == null return reason == null
@ -21,26 +29,31 @@ object JsonPropertiesUpToDateSpec : ExplainingSpec<Task> {
override fun whyUnsatisfied(task: Task?): String? { override fun whyUnsatisfied(task: Task?): String? {
require(task is UpdatePackageJson) { "$task is not a UpdatePackageJson task" } require(task is UpdatePackageJson) { "$task is not a UpdatePackageJson task" }
val current = task.currentPackageJson() val current = task.packageJsonFile.asFile.orNull?.parseToJsonObject()
val updated = task.updatedPackageJson(current) ?: return "no package.json file"
return if (current != updated) { val updates = task.expectedJsonUpdates.orNull?.toList()?.foldParseToJsonObject()
(current.keys + updated.keys) ?: return "no package.json updates"
val expected = JsonObject(current + updates)
if (current != expected) {
return (current.keys + expected.keys)
.asSequence() .asSequence()
.distinct() .distinct()
.sorted() .sorted()
.mapNotNull { .mapNotNull {
val currentVal = current[it] val currentVal = current[it]
val updatedVal = updated[it] val expectedVal = expected[it]
if (currentVal == updatedVal) { if (currentVal == expectedVal) {
null null
} else { } else {
"'$it' - expected:$updatedVal, actual:$currentVal" "'$it' - expected:$expectedVal, actual:$currentVal"
} }
}.joinToString(separator = "\n\t", prefix = "package.json is not up to date.\n\t") }.joinToString(separator = "\n\t", prefix = "package.json is not up to date.\n\t")
} else {
null
} }
return null
} }
} }

View file

@ -1,15 +1,19 @@
package dev.adamko.kafkatorio.task package dev.adamko.kafkatorio.task
import com.github.gradle.node.NodePlugin import com.github.gradle.node.NodePlugin
import dev.adamko.kafkatorio.jsonMapper import dev.adamko.kafkatorio.*
import java.io.File
import javax.inject.Inject import javax.inject.Inject
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.JsonObjectBuilder
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.MapProperty import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
@ -18,13 +22,19 @@ import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.support.useToRun import org.gradle.kotlin.dsl.support.useToRun
import org.jetbrains.kotlin.util.suffixIfNot import org.jetbrains.kotlin.util.suffixIfNot
@CacheableTask @CacheableTask
abstract class UpdatePackageJson @Inject constructor( abstract class UpdatePackageJson @Inject constructor(
private val providers: ProviderFactory, private val providers: ProviderFactory,
) : DefaultTask() { ) : DefaultTask(),
ProviderFactory by providers {
// @get:Input
// abstract val propertiesToCheck: MapProperty<String, String>
/** Cumulative updates */
@get:Input @get:Input
abstract val propertiesToCheck: MapProperty<String, String> internal abstract val expectedJsonUpdates: ListProperty<String>
@get:OutputFile @get:OutputFile
abstract val packageJsonFile: RegularFileProperty abstract val packageJsonFile: RegularFileProperty
@ -32,51 +42,93 @@ abstract class UpdatePackageJson @Inject constructor(
init { init {
group = NodePlugin.NPM_GROUP group = NodePlugin.NPM_GROUP
description = description = "Update package.json properties"
"Read the package.json file and update the version and name, based on the current project."
outputs.upToDateWhen(JsonPropertiesUpToDateSpec) outputs.upToDateWhen(JsonPropertiesUpToDateSpec)
// expectedJson.convention("{}")
} }
@TaskAction @TaskAction
fun exec() { fun exec() {
val packageJsonFile = packageJsonFile.asFile.get() val packageJsonFile = packageJsonFile.asFile.get()
val expectedJsonUpdates: List<String> = expectedJsonUpdates.get().toList()
logger.lifecycle("updating package.json ${packageJsonFile.canonicalPath}") logger.lifecycle("updating package.json ${packageJsonFile.canonicalFile}")
val updatedPackageJson = updatedPackageJson() val expectedJson = expectedJsonUpdates.fold(JsonObject(emptyMap())) { acc, update ->
val updateJson = jsonMapper.parseToJsonElement(update).jsonObject
JsonObject(acc + updateJson)
}
val packageJsonContentUpdated = val updatedPackageJson = JsonObject(
packageJsonFile.parseToJsonObject() + expectedJson
)
val packageJsonContentFormatted =
jsonMapper jsonMapper
.encodeToString(updatedPackageJson) .encodeToString(updatedPackageJson)
// change empty arrays/objects, because `npm install` also formats package.json, but // change empty arrays/objects, because `npm install` also formats package.json,
// slightly differently to kxs. // but slightly differently to kxs.
.replace( ": {\n }", ": {}") .replace(": {\n }", ": {}")
.replace( ": [\n ]", ": []") .replace(": [\n ]", ": []")
.suffixIfNot("\n") .suffixIfNot("\n")
logger.debug(packageJsonContentUpdated) logger.info(packageJsonContentFormatted)
packageJsonFile.writer().useToRun { packageJsonFile.writer().useToRun {
write(packageJsonContentUpdated) write(packageJsonContentFormatted)
} }
} }
internal fun currentPackageJson(): JsonObject {
val packageJsonFile = packageJsonFile.get().asFile /** Update [expectedJson] by merging [updateJsonProvider] with the existing value. */
return jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject fun updateExpectedJson(
expectedJsonUpdate: JsonObjectBuilder.() -> Unit
) {
val expectedJsonUpdateProvider = provider {
buildJsonObject(expectedJsonUpdate).toString()
}
expectedJsonUpdates.add(expectedJsonUpdateProvider)
// val newJson =
// expectedJson.zip(expectedJsonUpdateProvider) { currentJsonString, inputJsonString ->
// val currentJson = jsonMapper.encodeToJsonElement(currentJsonString).jsonObject
//
// val inputJson = jsonMapper.encodeToJsonElement(inputJsonString).jsonObject
//
// val newJson = JsonObject(currentJson + inputJson)
//
// jsonMapper.encodeToString(newJson)
// }
//
// expectedJson.set(newJson)
} }
internal fun updatedPackageJson(
currentPackageJson: JsonObject = currentPackageJson(), companion object {
): JsonObject { private val jsonMapper = Json {
val propertiesToCheck: Map<String, String> = propertiesToCheck.get() prettyPrint = true
val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> prettyPrintIndent = " "
JsonPrimitive(newVal)
} }
return JsonObject(currentPackageJson + newJsonProps)
internal fun File.parseToJsonObject(): JsonObject =
jsonMapper.parseToJsonElement(readText()).jsonObject
internal fun Property<String>.parseToJsonObject(): JsonObject =
jsonMapper.parseToJsonElement(get()).jsonObject
internal fun List<String>.foldParseToJsonObject(): JsonObject =
fold(JsonObject(emptyMap())) { acc, update ->
val updateJson = jsonMapper.parseToJsonElement(update).jsonObject
JsonObject(acc + updateJson)
}
} }
} }

View file

@ -45,6 +45,15 @@ kotkaStreams = "dev-SNAPSHOT"
marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform
## npm ##
npm-luaTypes = "2.12.0"
npm-typescriptToLua = "1.8.2"
npm-typedFactorio = "1.6.1"
npm-typescript = "4.7.4"
## test ## ## test ##
junit = "5.8.2" junit = "5.8.2"
kotest = "5.3.1" kotest = "5.3.1"

View file

@ -4,6 +4,8 @@ import dev.adamko.kafkatorio.gradle.asProvider
import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.factorioModAttributes
import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes
import dev.adamko.kafkatorio.task.TypescriptToLuaTask import dev.adamko.kafkatorio.task.TypescriptToLuaTask
import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonObject
import net.swiftzer.semver.SemVer import net.swiftzer.semver.SemVer
import org.apache.tools.ant.filters.ReplaceTokens import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule
@ -175,15 +177,26 @@ val factorioModProvider by configurations.registering {
} }
val packageJsonName: Provider<String> = providers.provider { "${rootProject.name}-${project.name}" } val projectPackageJsonName: Provider<String> =
val pjProvider: RegularFileProperty = providers.provider { "${rootProject.name}-${project.name}" }
objects.fileProperty().convention(layout.projectDirectory.file("package.json")) val projectPackageJsonFile: RegularFile = layout.projectDirectory.file("package.json")
val projectVersion: Provider<String> = providers.provider { "${project.version}" }
tasks.updatePackageJson { tasks.updatePackageJson {
// mustRunAfter(tasks.npmInstall) // mustRunAfter(tasks.npmInstall)
inputs.property("packageJsonName", packageJsonName)
propertiesToCheck.put("name", packageJsonName) updateExpectedJson {
packageJsonFile.set(pjProvider) put("name", projectPackageJsonName.get())
putJsonObject("dependencies") {
put("lua-types", libs.versions.npm.luaTypes.get())
put("typescript-to-lua", libs.versions.npm.typescriptToLua.get())
put("typed-factorio", libs.versions.npm.typedFactorio.get())
put("typescript", libs.versions.npm.typescript.get())
}
}
packageJsonFile.set(projectPackageJsonFile)
} }

View file

@ -32,17 +32,17 @@
} }
}, },
"is-core-module": { "is-core-module": {
"version": "2.9.0", "version": "2.10.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
"integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
"requires": { "requires": {
"has": "^1.0.3" "has": "^1.0.3"
} }
}, },
"lua-types": { "lua-types": {
"version": "2.11.0", "version": "2.12.0",
"resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.0.tgz",
"integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==" "integrity": "sha512-s96z1Zcz3KRXfWyNFM3KP2zpNYTfZwgHo8X/yFXveyS8Dux+cUuyT+zA5tFZbmGh8VViwNs9bFbzNevAR/18uw=="
}, },
"path-parse": { "path-parse": {
"version": "1.0.7", "version": "1.0.7",
@ -75,9 +75,9 @@
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
}, },
"typed-factorio": { "typed-factorio": {
"version": "1.4.0", "version": "1.6.1",
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.4.0.tgz", "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.6.1.tgz",
"integrity": "sha512-hT5YDtdJk/hVIm83hYlXx2vOSmhElQhHhcI0OIrdx2nmrx18zKEnjGk4abJ6WHjuy4xoVZ+00mjnC3mWclvrzw==" "integrity": "sha512-ehxUmRUPO4IEhtXIOkwhosDGGEVgRBFVaoNkTOvko/3yLKwese/6IB1/9ItSRNspqOoNh4UBPscjvQWM3SIFBA=="
}, },
"typescript": { "typescript": {
"version": "4.7.4", "version": "4.7.4",
@ -85,9 +85,9 @@
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ=="
}, },
"typescript-to-lua": { "typescript-to-lua": {
"version": "1.7.1", "version": "1.8.2",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.1.tgz", "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.8.2.tgz",
"integrity": "sha512-iDjCnel38p3Cxv+Las8rBzd6BaRIE49DQSyFOgupg4gSw36+8H1xtwde3lRdGMPZx19/zVwXEO8UspiACYJc+A==", "integrity": "sha512-2ZFJlF9R9HgTryM+Vwk3X3Dexnvpm5vT75Eh66E0rDFZGK+vW70aqkw6s47/ytdJg/9IyN+Oz7ITUzZxXEOxlA==",
"requires": { "requires": {
"enhanced-resolve": "^5.8.2", "enhanced-resolve": "^5.8.2",
"resolve": "^1.15.1", "resolve": "^1.15.1",

View file

@ -11,9 +11,9 @@
}, },
"devDependencies": {}, "devDependencies": {},
"dependencies": { "dependencies": {
"lua-types": "^2.11.0", "lua-types": "2.12.0",
"typescript-to-lua": "1.7.1", "typescript-to-lua": "1.8.2",
"typed-factorio": "1.4.0", "typed-factorio": "1.6.1",
"typescript": "4.7.4" "typescript": "4.7.4"
}, },
"license": "UNLICENSED", "license": "UNLICENSED",