Skip to content

Commit

Permalink
allow strings in mods list for quick definition
Browse files Browse the repository at this point in the history
  • Loading branch information
NikkyAI committed Jan 25, 2021
1 parent 182434d commit 2df2086
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 86 deletions.
55 changes: 9 additions & 46 deletions samples/fabricpack/164Version.voodoo.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,23 @@
"intermediateMappings": "Fabric/1.16.4"
},
"mods": [
{
"type": "curse",
"projectName": "Fabric16/fabric-api"
},
{
"type": "curse",
"projectName": "Fabric16/betternether"
},
"curse=Fabric16/fabric-api",
"curse=Fabric16/betternether",
"curse=Fabric16/betternether",
{
"type": "curse",
"projectName": "Fabric16/tab-inventory-fabric",
"validMcVersions": ["1.16", "1.16.1", "1.16.2", "1.16.3"]
},
{
"type": "curse",
"projectName": "Fabric16/campanion"
},
{
"type": "curse",
"applyOverrides": [
"client"
],
"projectName": "Fabric16/roughly-enough-items"
},
{
"type": "curse",
"applyOverrides": [
"client"
],
"projectName": "Fabric16/roughly-enough-resources"
},
{
"type": "curse",
"applyOverrides": [
"client"
],
"projectName": "Fabric16/modmenu"
},
{
"type": "curse",
"applyOverrides": [
"client",
"optionalStarred"
],
"projectName": "Fabric16/mouse-wheelie"
},
{
"type": "curse",
"applyOverrides": [
"client",
"optionalStarred"
],
"projectName": "Fabric16/appleskin"
"projectName": "Fabric16/campanion",
},
"curse:client=Fabric16/roughly-enough-items",
"curse:client=Fabric16/roughly-enough-resources",
"curse:client=Fabric16/modmenu",
"curse:client,optionalStarred=Fabric16/mouse-wheelie",
"curse:client,optionalStarred=Fabric16/appleskin",
{
"type": "curse",
"projectName": "Fabric16/hwyla",
Expand Down
10 changes: 1 addition & 9 deletions samples/fabricpack/lock/0.0.3/lock.pack.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"fabric-api": "REQUIRED"
},
"projectID": 373138,
"fileID": 3139044
"fileID": 3179423
},
{
"type": "curse",
Expand Down Expand Up @@ -94,14 +94,6 @@
"projectID": 317514,
"fileID": 3174695
},
{
"type": "jenkins",
"id": "opencomputers",
"path": "mods",
"jenkinsUrl": "https://ci.cil.li/",
"job": "OpenComputers-MC1.12",
"buildNumber": 213
},
{
"type": "curse",
"id": "roughly-enough-items",
Expand Down
82 changes: 63 additions & 19 deletions voodoo/src/main/kotlin/voodoo/config/Extensions.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package voodoo.config

import com.github.ricky12awesome.jss.buildJsonSchema
import com.github.ricky12awesome.jss.encodeToSchema
import kotlinx.serialization.json.*
import voodoo.data.nested.NestedPack
import voodoo.pack.FileEntry
import voodoo.pack.VersionPack
import voodoo.util.json

Expand All @@ -22,22 +25,63 @@ fun NestedPack.Companion.generateSchema() = json.encodeToSchema(serializer())
Autocompletions.fabricInstallers.keys.joinToString(",") { "\"$it\"" }
)

fun VersionPack.Companion.generateSchema(overridesKeys: Set<String>) = json.encodeToSchema(serializer())
.replace("\"replace_with_overrides\"",
overridesKeys.joinToString(",") { "\"${it}\"" }
)
.replace("\"replace_with_curseforge_projects\"",
Autocompletions.curseforge.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_forge_versions\"",
Autocompletions.forge.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_fabric_intermediaries\"",
Autocompletions.fabricIntermediaries.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_fabric_loaders\"",
Autocompletions.fabricLoaders.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_fabric_installers\"",
Autocompletions.fabricInstallers.keys.joinToString(",") { "\"$it\"" }
)
fun VersionPack.Companion.generateSchema(overridesKeys: Set<String>): String {
val fileEntrySchemaObject = buildJsonSchema(FileEntry.serializer(), generateDefinitions = true)

val fileEntryRef: String = fileEntrySchemaObject["\$ref"]!!.jsonPrimitive.content
val fileEntryDefinitions = fileEntrySchemaObject["definitions"]!!.jsonObject

val schema = buildJsonSchema(serializer(), generateDefinitions = true).toMutableMap()
val definitions = schema["definitions"]!!.jsonObject.toMutableMap()
val fileEntryOrStringId = definitions["FileEntryList"]!!.jsonObject["items"]!!.jsonObject["\$ref"]!!.jsonPrimitive
.content.substringAfter("#/definitions/")

definitions[fileEntryOrStringId] = buildJsonObject {
putJsonArray("oneOf") {
val oneOfOverrides = overridesKeys.joinToString("|", "(", ")") { """(\Q$it\E)""" }
val overridesRegex = "$oneOfOverrides,)*$oneOfOverrides"
addJsonObject {
put("type", "string")
putJsonArray("oneOf") {
addJsonObject {
val group = """\w+"""
val slug = """(\w+-)*\w+"""
put("pattern", """^curse(:($oneOfOverrides,)*$oneOfOverrides)?=$group/$slug$""")
}
addJsonObject {
put("pattern", """^jenkins(:($oneOfOverrides,)*$oneOfOverrides)?=""")
}
addJsonObject {
put("pattern", """^direct(:($oneOfOverrides,)*$oneOfOverrides)?=""")
}
}
}
addJsonObject {
put("\$ref", fileEntryRef)
}
}
}
definitions.putAll(fileEntryDefinitions)

schema["definitions"] = JsonObject(definitions)

return json.encodeToString(JsonObject.serializer(), JsonObject(schema))
.replace("\"replace_with_overrides\"",
overridesKeys.joinToString(",") { "\"${it}\"" }
)
.replace("\"replace_with_curseforge_projects\"",
Autocompletions.curseforge.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_forge_versions\"",
Autocompletions.forge.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_fabric_intermediaries\"",
Autocompletions.fabricIntermediaries.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_fabric_loaders\"",
Autocompletions.fabricLoaders.keys.joinToString(",") { "\"$it\"" }
)
.replace("\"replace_with_fabric_installers\"",
Autocompletions.fabricInstallers.keys.joinToString(",") { "\"$it\"" }
)
}
19 changes: 11 additions & 8 deletions voodoo/src/main/kotlin/voodoo/pack/FileEntry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ sealed class FileEntry(
) : FileEntry() {

override fun applyTag(tag: EntryOverride): Curse {
return when(tag) {
return when (tag) {
is EntryOverride.Curse -> copy(
curse = curse.copy(
useOriginalUrl = tag.useOriginalUrl ?: curse.useOriginalUrl,
Expand All @@ -116,7 +116,7 @@ sealed class FileEntry(
}
}

override fun toEntry(): FlatEntry = FlatEntry.Curse (
override fun toEntry(): FlatEntry = FlatEntry.Curse(
common = toCommonComponent(),
curse = curse.copy()
).apply {
Expand All @@ -135,7 +135,7 @@ sealed class FileEntry(
val direct: DirectComponent = DirectComponent(),
) : FileEntry() {
override fun applyTag(tag: EntryOverride): Direct {
return when(tag) {
return when (tag) {
is EntryOverride.Direct -> copy(
direct = direct.copy(
url = tag.url ?: direct.url,
Expand All @@ -151,8 +151,8 @@ sealed class FileEntry(
}
}

override fun toEntry(): FlatEntry =FlatEntry.Direct(
common = toCommonComponent(),
override fun toEntry(): FlatEntry = FlatEntry.Direct(
common = toCommonComponent(direct.url.split(":|&|=".toRegex()).joinToString("_")),
direct = direct.copy()
)
}
Expand All @@ -164,7 +164,7 @@ sealed class FileEntry(
val jenkins: JenkinsComponent = JenkinsComponent(),
) : FileEntry() {
override fun applyTag(tag: EntryOverride): Jenkins {
return when(tag) {
return when (tag) {
is EntryOverride.Jenkins -> copy(
jenkins = jenkins.copy(
jenkinsUrl = tag.jenkinsUrl ?: jenkins.jenkinsUrl,
Expand All @@ -180,6 +180,7 @@ sealed class FileEntry(
else -> this
}
}

override fun toEntry(): FlatEntry = FlatEntry.Jenkins(
common = toCommonComponent(jenkins.job),
jenkins = jenkins.copy()
Expand All @@ -193,7 +194,7 @@ sealed class FileEntry(
val local: LocalComponent = LocalComponent(),
) : FileEntry() {
override fun applyTag(tag: EntryOverride): Local {
return when(tag) {
return when (tag) {
is EntryOverride.Local -> copy(
local = local.copy(
fileSrc = tag.fileSrc ?: local.fileSrc
Expand All @@ -207,6 +208,7 @@ sealed class FileEntry(
else -> this
}
}

override fun toEntry(): FlatEntry = FlatEntry.Local(
common = toCommonComponent(local.fileSrc),
local = local.copy()
Expand All @@ -217,13 +219,14 @@ sealed class FileEntry(
@SerialName("noop")
class Noop() : FileEntry() {
override fun applyTag(tag: EntryOverride): Noop {
return when(tag) {
return when (tag) {
is EntryOverride.Common -> this.apply {
applyCommonOverride(tag)
}
else -> this
}
}

override fun toEntry(): FlatEntry = FlatEntry.Noop(
common = toCommonComponent()
)
Expand Down
59 changes: 55 additions & 4 deletions voodoo/src/main/kotlin/voodoo/pack/VersionPack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import kotlinx.serialization.Required
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import mu.KotlinLogging
import voodoo.config.Autocompletions
import voodoo.data.ModloaderPattern
import voodoo.data.PackOptions
import voodoo.data.components.DirectComponent
import voodoo.data.components.JenkinsComponent
import voodoo.data.curse.ProjectID
import voodoo.data.flat.FlatModPack
import voodoo.util.json
Expand All @@ -30,27 +35,73 @@ data class VersionPack(
val modloader: Modloader,
val packageConfiguration: VersionPackageConfig = VersionPackageConfig(),
// val overrides: Map<String, EntryOverride> = mapOf(),
val mods: List<FileEntry>,
@JsonSchema.Definition("FileEntryList")
val mods: List<JsonElement>,
) {
@Transient
lateinit var baseDir: File
@Transient
lateinit var modEntries: List<FileEntry>

companion object {
private val logger = KotlinLogging.logger {}
const val extension = "voodoo.json"
const val defaultSchema = "../schema/versionPack.schema.json"

fun parseEntry(jsonElement: JsonElement): FileEntry {
return when(jsonElement) {
is JsonPrimitive -> {
require(jsonElement.isString) { "element $jsonElement is not a string" }
val str = jsonElement.content
val overrides = str.substringBefore("=").takeIf { it.contains(":") }?.substringAfter(":")?.split(",") ?: listOf()
when {
str.startsWith("curse") -> {
FileEntry.Curse(
projectName = str.substringAfter(":").substringAfter("=")
)
}
str.startsWith("jenkins:") -> {
FileEntry.Jenkins(
jenkins = JenkinsComponent(
job = str.substringAfter(":").substringAfter("=")
)
)
}
str.startsWith("direct:") -> {
FileEntry.Direct(
direct = DirectComponent(
url = str.substringAfter(":").substringAfter("=")
)
)
}
else -> error("unknown prefix: ${str.substringBefore(":")}")
}.apply {
applyOverrides = overrides
}
}
is JsonObject -> {
json.decodeFromJsonElement(FileEntry.serializer(), jsonElement)
}
else -> {
error("element $jsonElement needs to be a object or string")
}
}
}

fun parse(packFile: File): VersionPack {
return json.decodeFromString(
VersionPack.serializer(),
packFile.readText()
).run {
copy(
modloader = modloader.replaceAutoCompletes(),
mods = mods.map { entry ->
).apply {
modEntries = mods.map { element ->
parseEntry(element)
}.map { entry ->
transformFileEntry(entry)
}
)
}
}.apply {
baseDir = packFile.absoluteFile.parentFile
}
Expand Down Expand Up @@ -136,7 +187,7 @@ data class VersionPack(
instanceCfg = packageConfiguration.multimc.instanceCfg
)
),
entrySet = mods.map { intitalEntry ->
entrySet = modEntries.map { intitalEntry ->
val entryId = intitalEntry.id
val entry = intitalEntry.applyOverrides.fold(intitalEntry) { acc, overrideId ->
val entryOverride =
Expand Down

0 comments on commit 2df2086

Please sign in to comment.