aboutsummaryrefslogtreecommitdiff
path: root/build-logic/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'build-logic/src/main/kotlin')
-rw-r--r--build-logic/src/main/kotlin/EnvFile.kt13
-rw-r--r--build-logic/src/main/kotlin/FabricModTransform.kt80
-rw-r--r--build-logic/src/main/kotlin/InnerJarsUnpacker.kt70
-rw-r--r--build-logic/src/main/kotlin/RepoDownload.kt41
-rw-r--r--build-logic/src/main/kotlin/firmament.base.gradle.kts1
-rw-r--r--build-logic/src/main/kotlin/firmament.common.gradle.kts2
-rw-r--r--build-logic/src/main/kotlin/firmament.license-management.gradle.kts5
-rw-r--r--build-logic/src/main/kotlin/firmament.repositories.gradle.kts46
-rw-r--r--build-logic/src/main/kotlin/licenseinfo.kt144
-rw-r--r--build-logic/src/main/kotlin/lookupversion.kt25
10 files changed, 427 insertions, 0 deletions
diff --git a/build-logic/src/main/kotlin/EnvFile.kt b/build-logic/src/main/kotlin/EnvFile.kt
new file mode 100644
index 0000000..ceec763
--- /dev/null
+++ b/build-logic/src/main/kotlin/EnvFile.kt
@@ -0,0 +1,13 @@
+
+import java.io.File
+
+fun parseEnvFile(file: File): Map<String, String> {
+ if (!file.exists()) return mapOf()
+ val map = mutableMapOf<String, String>()
+ for (line in file.readText().lines()) {
+ if (line.isEmpty() || line.startsWith("#")) continue
+ val parts = line.split("=", limit = 2)
+ map[parts[0]] = parts.getOrNull(1) ?: ""
+ }
+ return map
+}
diff --git a/build-logic/src/main/kotlin/FabricModTransform.kt b/build-logic/src/main/kotlin/FabricModTransform.kt
new file mode 100644
index 0000000..53affbe
--- /dev/null
+++ b/build-logic/src/main/kotlin/FabricModTransform.kt
@@ -0,0 +1,80 @@
+import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer
+import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
+import com.google.gson.Gson
+import com.google.gson.JsonObject
+import com.google.gson.JsonPrimitive
+import java.io.Serializable
+import net.fabricmc.accesswidener.AccessWidenerReader
+import net.fabricmc.accesswidener.AccessWidenerWriter
+import org.apache.tools.zip.ZipEntry
+import org.apache.tools.zip.ZipOutputStream
+import org.gradle.api.file.FileTreeElement
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Internal
+
+open class FabricModTransform : ResourceTransformer {
+
+ enum class AccessWidenerInclusion : Serializable {
+ ALL,
+ NONE,
+ }
+
+ @get:Input
+ var mergeAccessWideners: AccessWidenerInclusion = AccessWidenerInclusion.ALL
+
+ @get:Internal
+ internal var mergedFmj: JsonObject? = null
+
+ @get:Internal
+ internal val foundAccessWideners = AccessWidenerWriter()
+
+ @get:Internal
+ internal var foundAnyAccessWidener = false
+
+ override fun canTransformResource(element: FileTreeElement): Boolean {
+ if (mergeAccessWideners == AccessWidenerInclusion.ALL && element.name.endsWith(".accesswidener"))
+ return true
+ return element.path == "fabric.mod.json"
+ }
+
+ override fun transform(context: TransformerContext) {
+ if (context.path.endsWith(".accesswidener")) {
+ foundAnyAccessWidener = true
+ // TODO: allow filtering for only those mentioned in a fabric.mod.json, potentially
+ context.inputStream.use { stream ->
+ AccessWidenerReader(foundAccessWideners).read(stream.bufferedReader())
+ }
+ return
+ }
+ // TODO: mixins.json relocations
+ val fmj = context.inputStream.use { stream ->
+ Gson().fromJson(stream.bufferedReader(), JsonObject::class.java)
+ }
+ val mergedFmj = this.mergedFmj
+ println("${fmj["id"]} is first? ${mergedFmj == null}")
+ if (mergedFmj == null) {
+ this.mergedFmj = fmj
+ } else {
+ // TODO: merge stuff
+ }
+ }
+
+ override fun hasTransformedResource(): Boolean {
+ return mergedFmj != null
+ }
+
+ override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
+ val mergedFmj = mergedFmj!!
+ if (foundAnyAccessWidener) {
+ val awFile = mergedFmj["accessWidener"]
+ require(awFile is JsonPrimitive && awFile.isString)
+ os.putNextEntry(ZipEntry(awFile.asString))
+ os.write(foundAccessWideners.write())
+ os.closeEntry()
+ }
+ os.putNextEntry(ZipEntry("fabric.mod.json"))
+ os.write(mergedFmj.toString().toByteArray())
+ os.closeEntry()
+ }
+}
diff --git a/build-logic/src/main/kotlin/InnerJarsUnpacker.kt b/build-logic/src/main/kotlin/InnerJarsUnpacker.kt
new file mode 100644
index 0000000..de06467
--- /dev/null
+++ b/build-logic/src/main/kotlin/InnerJarsUnpacker.kt
@@ -0,0 +1,70 @@
+import com.google.gson.Gson
+import com.google.gson.JsonArray
+import com.google.gson.JsonObject
+import com.google.gson.JsonPrimitive
+import java.io.File
+import java.util.zip.ZipInputStream
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.ConfigurableFileCollection
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.OutputFiles
+import org.gradle.api.tasks.TaskAction
+import kotlin.io.path.createDirectories
+import kotlin.io.path.outputStream
+
+abstract class InnerJarsUnpacker : DefaultTask() {
+ @get:InputFiles
+ abstract val inputJars: ConfigurableFileCollection
+
+ @get:OutputDirectory
+ abstract val outputDir: DirectoryProperty
+
+ private fun getFabricModJson(inputFile: File): JsonObject {
+ inputFile.inputStream().use {
+ val zis = ZipInputStream(it)
+ while (true) {
+ val entry = zis.nextEntry ?: error("Failed to find fabric.mod.json")
+ if (entry.name == "fabric.mod.json") {
+ return Gson().fromJson(zis.reader(), JsonObject::class.java)
+ }
+ }
+ }
+ }
+
+ @TaskAction
+ fun unpack() {
+ inputJars.forEach { inputFile ->
+ val fabricModObject = getFabricModJson(inputFile)
+ val jars = fabricModObject["jars"] as? JsonArray ?: error("No jars to unpack in $inputFile")
+ val jarPaths = jars.map {
+ ((it as? JsonObject)?.get("file") as? JsonPrimitive)?.asString
+ ?: error("Invalid Jar $it in $inputFile")
+ }
+ extractJars(inputFile, jarPaths)
+ }
+ }
+
+ private fun extractJars(inputFile: File, jarPaths: List<String>) {
+ val outputFile = outputDir.get().asFile.toPath()
+ val jarPathSet = jarPaths.toMutableSet()
+ inputFile.inputStream().use {
+ val zis = ZipInputStream(it)
+ while (true) {
+ val entry = zis.nextEntry ?: break
+ if (jarPathSet.remove(entry.name)) {
+ val resolvedPath = outputFile.resolve(entry.name)
+ resolvedPath.parent.createDirectories()
+ resolvedPath.outputStream().use { os ->
+ zis.copyTo(os)
+ }
+ }
+ }
+ }
+ if (jarPathSet.isNotEmpty()) {
+ error("Could not extract all jars: $jarPathSet")
+ }
+ }
+}
diff --git a/build-logic/src/main/kotlin/RepoDownload.kt b/build-logic/src/main/kotlin/RepoDownload.kt
new file mode 100644
index 0000000..42a09b3
--- /dev/null
+++ b/build-logic/src/main/kotlin/RepoDownload.kt
@@ -0,0 +1,41 @@
+import java.net.URI
+import java.util.zip.ZipInputStream
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+
+abstract class RepoDownload : DefaultTask() {
+ @get:Input
+ abstract val hash: Property<String>
+
+ @get:OutputDirectory
+ abstract val outputDirectory: DirectoryProperty
+
+ init {
+ outputDirectory.convention(project.layout.buildDirectory.dir("extracted-test-repo"))
+ }
+
+ @TaskAction
+ fun performDownload() {
+ val outputDir = outputDirectory.asFile.get().absoluteFile
+ outputDir.mkdirs()
+ URI("https://github.com/notEnoughUpdates/notEnoughUpdates-rEPO/archive/${hash.get()}.zip").toURL().openStream()
+ .let(::ZipInputStream)
+ .use { zipInput ->
+ while (true) {
+ val entry = zipInput.nextEntry ?: break
+ val destination = outputDir.resolve(
+ entry.name.substringAfter('/')).absoluteFile
+ require(outputDir in generateSequence(destination) { it.parentFile })
+ if (entry.isDirectory) continue
+ destination.parentFile.mkdirs()
+ destination.outputStream().use { output ->
+ zipInput.copyTo(output)
+ }
+ }
+ }
+ }
+}
diff --git a/build-logic/src/main/kotlin/firmament.base.gradle.kts b/build-logic/src/main/kotlin/firmament.base.gradle.kts
new file mode 100644
index 0000000..8c512a4
--- /dev/null
+++ b/build-logic/src/main/kotlin/firmament.base.gradle.kts
@@ -0,0 +1 @@
+group = "moe.nea.firmament"
diff --git a/build-logic/src/main/kotlin/firmament.common.gradle.kts b/build-logic/src/main/kotlin/firmament.common.gradle.kts
new file mode 100644
index 0000000..a359b3d
--- /dev/null
+++ b/build-logic/src/main/kotlin/firmament.common.gradle.kts
@@ -0,0 +1,2 @@
+apply(plugin = "firmament.base")
+apply(plugin = "firmament.repositories")
diff --git a/build-logic/src/main/kotlin/firmament.license-management.gradle.kts b/build-logic/src/main/kotlin/firmament.license-management.gradle.kts
new file mode 100644
index 0000000..0a2626b
--- /dev/null
+++ b/build-logic/src/main/kotlin/firmament.license-management.gradle.kts
@@ -0,0 +1,5 @@
+apply(plugin = "moe.nea.licenseextractificator")
+
+configure<moe.nea.licenseextractificator.LicenseExtension> {
+ addExtraLicenseMatchers()
+}
diff --git a/build-logic/src/main/kotlin/firmament.repositories.gradle.kts b/build-logic/src/main/kotlin/firmament.repositories.gradle.kts
new file mode 100644
index 0000000..07a5709
--- /dev/null
+++ b/build-logic/src/main/kotlin/firmament.repositories.gradle.kts
@@ -0,0 +1,46 @@
+repositories {
+ mavenCentral()
+ maven("https://maven.terraformersmc.com/releases/")
+ maven("https://maven.shedaniel.me")
+ maven("https://maven.fabricmc.net")
+ maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
+ maven("https://api.modrinth.com/maven") {
+ content {
+ includeGroup("maven.modrinth")
+ }
+ }
+ maven("https://repo.sleeping.town") {
+ content {
+ includeGroup("com.unascribed")
+ }
+ }
+ ivy("https://github.com/HotswapProjects/HotswapAgent/releases/download") {
+ patternLayout {
+ artifact("[revision]/[artifact]-[revision].[ext]")
+ }
+ content {
+ includeGroup("virtual.github.hotswapagent")
+ }
+ metadataSources {
+ artifact()
+ }
+ }
+ maven("https://server.bbkr.space/artifactory/libs-release")
+ maven("https://repo.nea.moe/releases")
+ maven("https://maven.notenoughupdates.org/releases")
+ maven("https://repo.nea.moe/mirror")
+ maven("https://jitpack.io/") {
+ content {
+ includeGroupByRegex("(com|io)\\.github\\..+")
+ excludeModule("io.github.cottonmc", "LibGui")
+ }
+ }
+ maven("https://repo.hypixel.net/repository/Hypixel/")
+ maven("https://maven.azureaaron.net/snapshots")
+ maven("https://maven.azureaaron.net/releases")
+ maven("https://www.cursemaven.com")
+ maven("https://maven.isxander.dev/releases") {
+ name = "Xander Maven"
+ }
+ mavenLocal()
+}
diff --git a/build-logic/src/main/kotlin/licenseinfo.kt b/build-logic/src/main/kotlin/licenseinfo.kt
new file mode 100644
index 0000000..50e4593
--- /dev/null
+++ b/build-logic/src/main/kotlin/licenseinfo.kt
@@ -0,0 +1,144 @@
+// SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+//
+// SPDX-License-Identifier: CC0-1.0
+
+import moe.nea.licenseextractificator.LicenseExtension
+
+fun LicenseExtension.addExtraLicenseMatchers() {
+ solo {
+ name = "Firmament"
+ description = "A Hypixel SkyBlock mod"
+ developer("Linnea Gräf") {
+ webPresence = "https://nea.moe/"
+ }
+ spdxLicense.`GPL-3-0-or-later`()
+ webPresence = "https://git.nea.moe/nea/Firmament/"
+ }
+ match {
+ if (group == "net.minecraft") useLicense {
+ name = "Minecraft"
+ description = "Minecraft - The critically acclaimed video game"
+ license("All Rights Reserved", "https://www.minecraft.net/en-us/eula")
+ developer("Mojang") {
+ webPresence = "https://mojang.com"
+ }
+ webPresence = "https://www.minecraft.net/en-us"
+ }
+ if (module == "architectury") useLicense {
+ name = "Architectury API"
+ description = "An intermediary api aimed at easing development of multiplatform mods."
+ spdxLicense.`LGPL-3-0-or-later`()
+ developer("Architectury") {
+ webPresence = "https://docs.architectury.dev/"
+ }
+ webPresence = "https://github.com/architectury/architectury-api"
+ }
+ if (module.startsWith("RoughlyEnoughItems")) useLicense {
+ name = module
+ description = "Your recipe viewer mod for 1.13+."
+ spdxLicense.MIT()
+ developer("Shedaniel") {
+ webPresence = "https://shedaniel.me/"
+ }
+ webPresence = "https://github.com/shedaniel/RoughlyEnoughItems"
+ }
+ if (module == "cloth-config") useLicense {
+ name = "Cloth Config"
+ description = "Client sided configuration API"
+ spdxLicense.`LGPL-3-0-or-later`()
+ developer("Shedaniel") {
+ webPresence = "https://shedaniel.me/"
+ }
+ webPresence = "https://github.com/shedaniel/cloth-config"
+ }
+ if (module == "basic-math") useLicense {
+ name = "Cloth BasicMath"
+ description = "Basic Math Operations"
+ spdxLicense.Unlicense()
+ developer("Shedaniel") {
+ webPresence = "https://shedaniel.me/"
+ }
+ webPresence = "https://github.com/shedaniel/cloth-basic-math"
+ }
+ if (module == "fabric-language-kotlin") useLicense {
+ name = "Fabric Language Kotlin"
+ description = "Kotlin Language Support for Fabric mods"
+ webPresence = "https://github.com/FabricMC/fabric-language-kotlin"
+ spdxLicense.`Apache-2-0`()
+ developer("FabricMC") {
+ webPresence = "https://fabricmc.net/"
+ }
+ }
+ if (group == "com.mojang") useLicense {
+ name = module
+ description = "Mojang library packaged by Minecraft"
+ }
+ }
+ module("net.fabricmc", "yarn") {
+ name = "Yarn"
+ description = "Libre Minecraft mappings, free to use for everyone. No exceptions."
+ spdxLicense.`CC0-1-0`()
+ developer("FabricMC") {
+ webPresence = "https://fabricmc.net/"
+ }
+ webPresence = "https://github.com/FabricMC/yarn/"
+ }
+ module("com.mojang", "datafixerupper") {
+ name = "DataFixerUpper"
+ description =
+ "A set of utilities designed for incremental building, merging and optimization of data transformations."
+ spdxLicense.MIT()
+ developer("Mojang") {
+ webPresence = "https://mojang.com"
+ }
+ webPresence = "https://github.com/Mojang/DataFixerUpper"
+ }
+ module("com.mojang", "brigadier") {
+ name = "Brigadier"
+ description = "Brigadier is a command parser & dispatcher, designed and developed for Minecraft: Java Edition."
+ spdxLicense.MIT()
+ developer("Mojang") {
+ webPresence = "https://mojang.com"
+ }
+ webPresence = "https://github.com/Mojang/brigadier"
+ }
+ module("net.fabricmc", "tiny-remapper") {
+ name = "Tiny Remapper"
+ description = "Tiny JAR remapping tool"
+ spdxLicense.`LGPL-3-0-or-later`()
+ webPresence = "https://github.com/FabricMC/tiny-remapper"
+ developer("FabricMC") {
+ webPresence = "https://fabricmc.net/"
+ }
+ }
+ module("net.fabricmc", "sponge-mixin") {
+ name = "Mixin"
+ description = "Mixin is a trait/mixin framework for Java using ASM"
+ spdxLicense.MIT()
+ webPresence = "https://github.com/FabricMC/mixin"
+ developer("FabricMC") {
+ webPresence = "https://fabricmc.net/"
+ }
+ developer("SpongePowered") {
+ webPresence = "https://spongepowered.org/"
+ }
+ }
+ module("net.fabricmc", "tiny-mappings-parser") {
+ name = "Tiny Mappings Parser"
+ webPresence = "https://github.com/fabricMC/tiny-mappings-parser"
+ description = "Library for parsing .tiny mapping files"
+ developer("FabricMC") {
+ webPresence = "https://fabricmc.net/"
+ }
+ spdxLicense.`Apache-2-0`()
+ }
+ module("net.fabricmc", "fabric-loader") {
+ name = "Fabric Loader"
+ description = " Fabric's mostly-version-independent mod loader."
+ spdxLicense.`Apache-2-0`()
+ developer("FabricMC") {
+ webPresence = "https://fabricmc.net/"
+ }
+ webPresence = "https://github.com/FabricMC/fabric-loader/"
+ }
+}
diff --git a/build-logic/src/main/kotlin/lookupversion.kt b/build-logic/src/main/kotlin/lookupversion.kt
new file mode 100644
index 0000000..8a7c2de
--- /dev/null
+++ b/build-logic/src/main/kotlin/lookupversion.kt
@@ -0,0 +1,25 @@
+fun execString(vararg args: String): String {
+ val pb = ProcessBuilder(*args)
+ .redirectOutput(ProcessBuilder.Redirect.PIPE)
+ .start()
+ pb.waitFor()
+ return pb.inputStream.readAllBytes().decodeToString().trim()
+}
+
+private val tag = "([0-9.]+)(?:\\+[^-]*)?".toRegex()
+private val tagOffset = "([0-9.]+)(?:\\+.*)?-([0-9]+)-(.+)".toRegex()
+
+inline fun <T> Regex.useMatcher(string: String, block: (MatchResult) -> T): T? {
+ return matchEntire(string)?.let(block)
+}
+
+fun getGitTagInfo(mcVersion: String): String {
+ val str = execString("git", "describe", "--tags", "HEAD")
+ tag.useMatcher(str) {
+ return it.groupValues[1] + "+mc$mcVersion"
+ }
+ tagOffset.useMatcher(str) {
+ return it.groupValues[1] + "-dev+mc$mcVersion+" + it.groupValues[3]
+ }
+ return "nogitversion+mc$mcVersion"
+}