Skip to content

Commit

Permalink
Improve Gradle build setup
Browse files Browse the repository at this point in the history
  • Loading branch information
Erdragh committed Feb 8, 2025
1 parent 1c7ee2f commit 6061ac7
Show file tree
Hide file tree
Showing 23 changed files with 602 additions and 499 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ faq

# Minecraft
**/run
**/runs

# Architectury
.architectury-transformer
356 changes: 6 additions & 350 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,356 +1,12 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.utils.extendsFrom
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.*
import dev.architectury.plugin.ArchitectPluginExtension
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import net.fabricmc.loom.task.RemapJarTask

plugins {
// This is an Architectury repository, as such the relevant plugins are needed
id("architectury-plugin") version "3.4-SNAPSHOT"
id("dev.architectury.loom") version "1.7-SNAPSHOT" apply false
// The shadow plugin is used by the fabric subproject to include dependencies
// I'm temporarily using a fork of the original plugin to resolve "Unsupported java classfile major version 65"
// see: https://github.com/johnrengelman/shadow/issues/911
id("io.github.goooler.shadow") version "8.1.8" apply false
// Since this mod/bot is written in Kotlin and expected to run on Minecraft and as such
// the JVM, the Kotlin plugin is needed
kotlin("jvm") version "2.0.10"
// For generating documentation based on comments in the code
id("org.jetbrains.dokka") version "1.9.10"
java
// For publishing the mod
id("me.modmuss50.mod-publish-plugin") version "0.5.1"
}

val minecraftVersion: String by project

architectury {
minecraft = minecraftVersion
}

repositories {
mavenCentral()
}

subprojects {
apply(plugin = "dev.architectury.loom")
apply(plugin = "architectury-plugin")
apply(plugin = "java")
apply(plugin = "kotlin")
apply(plugin = "org.jetbrains.dokka")
apply(plugin = "me.modmuss50.mod-publish-plugin")

// Gets some values from the gradle.properties files in the
// sub- and root projects
val modLoader = project.name
val modId: String by project
val modName = rootProject.name
val modAuthor: String by project
val isCommon = modLoader == rootProject.projects.common.name

base {
// This will be the final name of the exported JAR file
archivesName.set("$modId-$modLoader-$minecraftVersion")
}

configure<LoomGradleExtensionAPI> {
silentMojangMappingsLicense()
}

extensions.configure<JavaPluginExtension> {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
withSourcesJar()
}

repositories {
mavenCentral()
maven(url = "https://maven.architectury.dev/")
maven("https://repo.spongepowered.org/repository/maven-public/") { name = "Sponge / Mixin" }
maven("https://maven.blamejared.com") { name = "BlameJared Maven (JEI / CraftTweaker / Bookshelf)" }
// For the parchment mappings
maven(url = "https://maven.parchmentmc.org")
maven(url = "https://maven.resourcefulbees.com/repository/maven-public/")
maven {
name = "Kotlin for Forge"
setUrl("https://thedarkcolour.github.io/KotlinForForge/")
}
// Forge Config API port
maven {
name = "Fuzs Mod Resources"
setUrl("https://raw.githubusercontent.com/Fuzss/modresources/main/maven/")
}
}

// Bot dependencies
val jdaVersion: String by project
val dcWebhooksVersion: String by project
val exposedVersion: String by project
val sqliteJDBCVersion: String by project
val commonmarkVersion: String by project

// Configuration for shaded dependencies, get relocated to dev.erdragh.astralbot.shadowed
val shadowBotDep by configurations.creating {
isTransitive = true
}
// This shadowCommon configuration is used to shade the
// common project
val shadowCommon by configurations.creating {
isCanBeConsumed = false
isCanBeResolved = true
}
// Configuration for libraries that are needed at runtime
val runtimeLib by configurations.creating {
isTransitive = true
}
configurations.implementation.extendsFrom(configurations.named("shadowBotDep"))
configurations.implementation.extendsFrom(configurations.named("runtimeLib"))

dependencies {
// Minecraft Mod dependencies
"minecraft"("::$minecraftVersion")

@Suppress("UnstableApiUsage")
"mappings"(project.the<LoomGradleExtensionAPI>().layered {
val parchmentVersion: String by project

officialMojangMappings()

parchment(
create(
group = "org.parchmentmc.data",
name = "parchment-$minecraftVersion",
version = parchmentVersion
)
)
})

runtimeLib("org.xerial:sqlite-jdbc:$sqliteJDBCVersion")
if (!isCommon) "include"("org.xerial:sqlite-jdbc:$sqliteJDBCVersion")

runtimeLib("org.commonmark:commonmark:$commonmarkVersion")
if (!isCommon) "include"("org.commonmark:commonmark:$commonmarkVersion")

arrayOf(
// Library used to communicate with Discord, see https://jda.wiki
"net.dv8tion:JDA:$jdaVersion",
// Library used for sending messages via Discord Webhooks
"club.minnced:discord-webhooks:$dcWebhooksVersion",

// Library to interact with the SQLite database,
// see: https://github.com/JetBrains/Exposed
"org.jetbrains.exposed:exposed-core:$exposedVersion",
"org.jetbrains.exposed:exposed-dao:$exposedVersion",
"org.jetbrains.exposed:exposed-jdbc:$exposedVersion",
).forEach {
implementation(it) {
exclude(module = "opus-java")
exclude(group = "org.slf4j")
}
runtimeLib(it) {
exclude(module = "opus-java")
exclude(group = "org.slf4j")
exclude(group = "org.jetbrains.kotlin")
exclude(group = "org.jetbrains.kotlinx")
}
shadowBotDep(it) {
// opus-java is for audio, which this bot doesn't need
exclude(module = "opus-java")
// Kotlin would be included as a transitive dependency
// on JDA and Exposed, but is already provided by the
// respective Kotlin implementation of the mod loaders
exclude(group = "org.jetbrains.kotlin")
exclude(group = "org.jetbrains.kotlinx")
// Minecraft already ships with a logging system
exclude(group = "org.slf4j")
}
}
}

java {
withSourcesJar()
modularity.inferModulePath = true
}

tasks.jar {
// Results in the not remapped jars having a -dev at the end
archiveClassifier.set("dev")

from(rootProject.file("LICENSE")) {
rename { "${it}_$modId" }
}

manifest {
attributes(
"Specification-Title" to modId,
"Specification-Vendor" to modAuthor,
"Specification-Version" to archiveVersion,
"Implementation-Title" to project.name,
"Implementation-Version" to archiveVersion,
"Implementation-Vendor" to modAuthor,
"Implementation-Timestamp" to SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(Date()),
"Timestamp" to System.currentTimeMillis(),
"Built-On-Java" to "${System.getProperty("java.vm.version")} (${System.getProperty("java.vm.vendor")})",
"Built-On-Minecraft" to minecraftVersion
)
}
}

tasks.processResources {
val version: String by project
val group: String by project
val fabricApiVersion: String by project
val fabricLoaderVersion: String by project
val fabricKotlinVersion: String by project
val license: String by project
val description: String by project
val credits: String by project
val title: String by project

val expandProps = mapOf(
"version" to version,
"group" to group, //Else we target the task's group.
"minecraft_version" to minecraftVersion,
"fabric_version" to fabricApiVersion,
"fabric_loader_version" to fabricLoaderVersion,
"fabric_kotlin_version" to fabricKotlinVersion,
"mod_name" to modName,
"mod_author" to modAuthor,
"mod_id" to modId,
"license" to license,
"description" to description,
"credits" to credits,
"title" to title
)

filesMatching(listOf("pack.mcmeta", "*.mixins.json", "META-INF/mods.toml", "fabric.mod.json")) {
expand(expandProps)
}
inputs.properties(expandProps)
}

if (!isCommon) {
apply(plugin = "io.github.goooler.shadow")

configure<ArchitectPluginExtension> {
platformSetupLoomIde()
}

tasks.named<ShadowJar>("shadowJar") {
// The shadowBotDep configuration was explicitly made to be shaded in, this is where that happens
configurations.clear()
configurations = listOf(shadowBotDep, shadowCommon)

// This transforms the service files to make relocated Exposed work (see: https://github.com/JetBrains/Exposed/issues/1353)
mergeServiceFiles()

// Forge restricts loading certain classes for security reasons.
// Luckily, shadow can relocate them to a different package.
relocate("org.apache.commons.collections4", "dev.erdragh.shadowed.org.apache.commons.collections4")

// Relocating Exposed somewhere different so other mods not doing that don't run into issues (e.g. Ledger)
relocate("org.jetbrains.exposed", "dev.erdragh.shadowed.org.jetbrains.exposed")

// Relocating jackson to prevent incompatibilities with other mods also bundling it (e.g. GroovyModLoader on Forge)
relocate("com.fasterxml.jackson", "dev.erdragh.shadowed.com.fasterxml.jackson")

// relocate discord interaction stuff to maybe allow other discord integrations mods to work
relocate("club.minnced.discord", "dev.erdragh.shadowed.club.minnced.discord")
relocate("net.dv8tion.jda", "dev.erdragh.shadowed.net.dv8tion.jda")

// relocate dependencies of discord stuff
relocate("okhttp3", "dev.erdragh.shadowed.okhttp3")
relocate("okio", "dev.erdragh.shadowed.okio")
relocate("gnu.trove", "dev.erdragh.shadowed.gnu.trove")
relocate("com.iwebpp.crypto", "dev.erdragh.shadowed.com.iwebpp.crypto")
relocate("com.neovisionaries.ws", "dev.erdragh.shadowed.com.neovisionaries.ws")
relocate("org.json", "dev.erdragh.shadowed.org.json")
relocate("net.bytebuddy", "dev.erdragh.shadowed.net.bytebuddy")

relocate("com.google", "dev.erdragh.shadowed.com.google")
relocate("google", "dev.erdragh.shadowed.google")
relocate("javax.annotation", "dev.erdragh.shadowed.javax.annotation")

exclude("**/org/slf4j/**")

exclude("**/org/jetbrains/annotations/*")
exclude("**/org/intellij/**")
}

tasks.named<RemapJarTask>("remapJar") {
inputFile.set(tasks.named<ShadowJar>("shadowJar").get().archiveFile)
dependsOn("shadowJar")
// Results in the remapped jar not having any extra bit in
// its file name, identifying it as the main distribution
archiveClassifier.set(null as String?)
}
}

// Disables Gradle's custom module metadata from being published to maven. The
// metadata includes mapped dependencies which are not reasonably consumable by
// other mod developers.
tasks.withType<GenerateModuleMetadata> {
enabled = false
}

tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
targetCompatibility = JavaVersion.VERSION_17.majorVersion
sourceCompatibility = JavaVersion.VERSION_17.majorVersion
}

// Publishing settings
if (!isCommon) {
publishMods {
// These titles get used based on subproject name
val titles by extra {
mapOf(
"fabric" to "Fabric",
"neoforge" to "NeoForge",
"forge" to "Forge",
"quilt" to "Quilt"
)
}
val curseforgePublish by extra {
curseforgeOptions {
accessToken = providers.environmentVariable("CURSEFORGE_TOKEN")
minecraftVersions.add(minecraftVersion)
projectId = providers.environmentVariable("CURSEFORGE_ID")
embeds("sqlite-jdbc")
}
}
val modrinthPublish by extra {
modrinthOptions {
accessToken = providers.environmentVariable("MODRINTH_TOKEN")
minecraftVersions.add(minecraftVersion)
projectId = providers.environmentVariable("MODRINTH_ID")
embeds("sqlite-jdbc")
}
}
val changelog by extra {
// Only gets the lines for the latest version from the Changelog
// file. This allows me to keep all previous changes in the file
// without having to worry about them being included on new file
// uploads.
File(rootDir, "CHANGELOG.md")
.readText(StandardCharsets.UTF_8)
.replace(Regex("[^^](#(#|\\n|.)+)|(^#.+)"), "")
.trim()
}
val type by extra {
STABLE
}
}
}
}

kotlin {
jvmToolchain(17)
// see https://fabricmc.net/develop/ for new versions
alias(libs.plugins.loom) apply false
// see https://projects.neoforged.net/neoforged/moddevgradle for new versions
alias(libs.plugins.moddev) apply false
// so we can enable soruce download
idea
}


// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
idea {
module {
Expand Down
14 changes: 14 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("groovy-gradle-plugin")
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:${libs.versions.dokka.get()}")
implementation("me.modmuss50:mod-publish-plugin:${libs.versions.publish.get()}")
}

repositories {
mavenCentral()
gradlePluginPortal()
}
7 changes: 7 additions & 0 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
register("libs") {
from(files("../libs.versions.toml"))
}
}
}
Loading

0 comments on commit 6061ac7

Please sign in to comment.