build: Rename all Gradle build logic modules to build-logic

This commit is contained in:
2026-08-23 10:40:29 +02:00
parent c6ce916e75
commit f268709f02
25 changed files with 14 additions and 11 deletions
+13
View File
@@ -0,0 +1,13 @@
import dev.panuszewski.gradle.pluginMarker
plugins {
`kotlin-dsl`
}
group = "de.siphalor.tweed5"
dependencies {
implementation(project(":tweed5-build-logic-helpers"))
implementation(pluginMarker(libs.plugins.lombok))
implementation(pluginMarker(libs.plugins.shadow))
}
+21
View File
@@ -0,0 +1,21 @@
plugins {
`kotlin-dsl`
`java-gradle-plugin`
}
group = "de.siphalor.tweed5"
gradlePlugin {
plugins.register("minecraftModComponent") {
id = "de.siphalor.tweed5.minecraft.mod.component"
implementationClass = "de.siphalor.tweed5.gradle.plugin.minecraft.mod.MinecraftModComponentPlugin"
}
plugins.register("moduleInfo") {
id = "de.siphalor.tweed5.module-info"
implementationClass = "de.siphalor.tweed5.gradle.plugin.module_info.ModuleInfoPlugin"
}
plugins.register("rootProperties") {
id = "de.siphalor.tweed5.root-properties"
implementationClass = "de.siphalor.tweed5.gradle.plugin.root_properties.RootPropertiesPlugin"
}
}
@@ -0,0 +1,81 @@
package de.siphalor.tweed5.gradle.plugin.minecraft.mod
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.DocsType
import org.gradle.api.attributes.LibraryElements
import org.gradle.api.attributes.Usage
import org.gradle.api.attributes.java.TargetJvmVersion
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.kotlin.dsl.named
import javax.inject.Inject
abstract class MinecraftModComponentPlugin : Plugin<Project> {
@get:Inject
abstract val softwareComponentFactory: SoftwareComponentFactory
@get:Inject
abstract val objectFactory: ObjectFactory
override fun apply(project: Project) {
val modComponent = softwareComponentFactory.adhoc("minecraftMod")
project.components.add(modComponent)
val targetJvmVersion = project.tasks.named<JavaCompile>("compileJava")
.map { JavaVersion.toVersion(it.targetCompatibility).majorVersion }
val modElementsConfiguration = project.configurations.consumable("minecraftModElements") {
attributes {
attribute(MinecraftModded.MINECRAFT_MODDED_ATTRIBUTE, objectFactory.named(MinecraftModded.MODDED))
attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category.LIBRARY))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objectFactory.named(LibraryElements.JAR))
attribute(Bundling.BUNDLING_ATTRIBUTE, objectFactory.named(Bundling.EMBEDDED))
attribute(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.JAVA_RUNTIME))
project.afterEvaluate {
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, targetJvmVersion.get().toInt())
}
}
}
val modApiElementsConfiguration = project.configurations.consumable("minecraftModApiElements") {
attributes {
attribute(MinecraftModded.MINECRAFT_MODDED_ATTRIBUTE, objectFactory.named(MinecraftModded.MODDED))
attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category.LIBRARY))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objectFactory.named(LibraryElements.JAR))
attribute(Bundling.BUNDLING_ATTRIBUTE, objectFactory.named(Bundling.EXTERNAL))
attribute(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.JAVA_API))
project.afterEvaluate {
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, targetJvmVersion.get().toInt())
}
}
}
val apiConfiguration = project.configurations.named("api")
val modSourcesElementsConfiguration = project.configurations.consumable("minecraftModSourcesElements") {
extendsFrom(apiConfiguration.get())
attributes {
attribute(MinecraftModded.MINECRAFT_MODDED_ATTRIBUTE, objectFactory.named(MinecraftModded.MODDED))
attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category.DOCUMENTATION))
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objectFactory.named(DocsType.SOURCES))
attribute(Bundling.BUNDLING_ATTRIBUTE, objectFactory.named(Bundling.EXTERNAL))
}
}
modComponent.addVariantsFromConfiguration(modElementsConfiguration.get()) {
mapToMavenScope("runtime")
}
modComponent.addVariantsFromConfiguration(modApiElementsConfiguration.get()) {
mapToMavenScope("compile")
}
modComponent.addVariantsFromConfiguration(modSourcesElementsConfiguration.get()) {
mapToOptional()
}
}
}
@@ -0,0 +1,12 @@
package de.siphalor.tweed5.gradle.plugin.minecraft.mod
import org.gradle.api.Named
import org.gradle.api.attributes.Attribute
interface MinecraftModded : Named {
companion object {
val MINECRAFT_MODDED_ATTRIBUTE = Attribute.of("de.siphalor.tweed5.minecraft.modded", MinecraftModded::class.java)
const val PLAIN = "plain"
const val MODDED = "modded"
}
}
@@ -0,0 +1,8 @@
package de.siphalor.tweed5.gradle.plugin.module_info
import org.gradle.api.provider.Property
abstract class ModuleInfoExtension {
abstract val name: Property<String>
abstract val description: Property<String>
}
@@ -0,0 +1,10 @@
package de.siphalor.tweed5.gradle.plugin.module_info
import org.gradle.api.Plugin
import org.gradle.api.Project
class ModuleInfoPlugin : Plugin<Project> {
override fun apply(target: Project) {
target.extensions.create("moduleInfo", ModuleInfoExtension::class.java)
}
}
@@ -0,0 +1,10 @@
package de.siphalor.tweed5.gradle.plugin
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Provider
abstract class RootPropertiesExtension {
abstract val properties: MapProperty<String, String>
operator fun get(key: String): Provider<String> = properties.getting(key)
}
@@ -0,0 +1,32 @@
package de.siphalor.tweed5.gradle.plugin.root_properties
import de.siphalor.tweed5.gradle.plugin.RootPropertiesExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.ProviderFactory
import org.gradle.kotlin.dsl.apply
import java.util.Properties
import javax.inject.Inject
abstract class RootPropertiesPlugin : Plugin<Project> {
@get:Inject
abstract val providers: ProviderFactory
override fun apply(project: Project) {
val rootPropertiesFile = if (project.layout.settingsDirectory.file(".gitmodules").asFile.exists()) {
project.layout.settingsDirectory.file("gradle.properties")
} else {
project.layout.settingsDirectory.file("../gradle.properties")
}
val rootProperties = providers.fileContents(rootPropertiesFile).asBytes.map { propsBytes ->
Properties().apply {
load(propsBytes.inputStream())
}.map { it.key.toString() to it.value.toString() }.toMap()
}
project.extensions.create("rootProperties", RootPropertiesExtension::class.java).apply {
properties.value(rootProperties)
}
}
}
+23
View File
@@ -0,0 +1,23 @@
plugins {
id("dev.panuszewski.typesafe-conventions") version "0.9.1"
}
typesafeConventions {
autoPluginDependencies = false
}
dependencyResolutionManagement {
repositories {
gradlePluginPortal()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
include(":tweed5-build-logic-helpers")
project(":tweed5-build-logic-helpers").projectDir = file("helpers")
rootProject.name = "tweed5-build-logic"
@@ -0,0 +1,50 @@
plugins {
java
`java-library`
id("io.freefair.lombok")
id("de.siphalor.tweed5.unit-tests")
id("de.siphalor.tweed5.publishing")
id("de.siphalor.tweed5.local-runtime-only")
id("de.siphalor.tweed5.expanded-sources-jar")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
lombok {
version = libs.versions.lombok.get()
}
dependencies {
compileOnly(libs.autoservice.annotations)
annotationProcessor(libs.autoservice.processor)
testCompileOnly(libs.autoservice.annotations)
testAnnotationProcessor(libs.autoservice.processor)
compileOnly(libs.jetbrains.annotations)
testImplementation(libs.jetbrains.annotations)
compileOnly(libs.jspecify.annotations)
testImplementation(libs.jspecify.annotations)
implementation(libs.acl)
"localRuntimeOnly"(libs.slf4j.rt)
testImplementation(libs.acl)
testImplementation(libs.slf4j.rt)
testImplementation(project(":generic-test-utils"))
}
publishing {
publications {
create<MavenPublication>("lib") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
}
}
}
@@ -0,0 +1,34 @@
import io.freefair.gradle.plugins.lombok.tasks.Delombok
plugins {
java
`java-library`
id("io.freefair.lombok")
}
val expandedSourcesElements = configurations.consumable("expandedSourcesElements") {
extendsFrom(configurations.implementation.get())
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType.SOURCES))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
}
}
val delombok = tasks.getByName<Delombok>("delombok")
val sourcesJar = tasks.register<Jar>("sourcesJar") {
group = LifecycleBasePlugin.BUILD_GROUP
dependsOn(delombok)
from(delombok.target)
archiveClassifier.set("sources")
}
artifacts.add(expandedSourcesElements.name, sourcesJar)
tasks.named("build") { dependsOn(sourcesJar) }
components.named<AdhocComponentWithVariants>("java") {
addVariantsFromConfiguration(expandedSourcesElements.get()) {}
}
@@ -0,0 +1,6 @@
plugins {
java
}
val localRuntimeOnly = configurations.create("localRuntimeOnly")
sourceSets.main.get().runtimeClasspath += localRuntimeOnly
@@ -0,0 +1,77 @@
plugins {
id("com.gradleup.shadow")
java
`java-library`
id("de.siphalor.tweed5.root-properties")
id("de.siphalor.tweed5.module-info")
id("de.siphalor.tweed5.shadow.explicit")
id("de.siphalor.tweed5.minecraft.mod.component")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
val minecraftJijElements = configurations.resolvable("minecraftJijElements")
tasks.shadowJar {
relocate("org.apache.commons", "de.siphalor.tweed5.shadowed.org.apache.commons")
}
fun formatJarsForJson(jars: FileCollection): String {
return jars.files.joinToString(",") { "{\"file\":\"META-INF/jars/${it.name}\"}"}
}
tasks.register<Sync>("processMinecraftModResources") {
inputs.property("id", project.name)
inputs.property("version", project.version)
inputs.property("name", moduleInfo.name)
inputs.property("description", moduleInfo.description)
inputs.property("repoUrl", rootProperties["git.url"])
inputs.files(minecraftJijElements)
val jars = objects.fileCollection().apply { from(minecraftJijElements) }
from(project.layout.settingsDirectory.dir("../tweed5-minecraft/mod-template/resources")) {
expand(
mapOf(
"id" to project.name.replace('-', '_'),
"version" to project.version,
"name" to moduleInfo.name,
"description" to moduleInfo.description,
"repoUrl" to rootProperties["git.url"].get(),
"jars" to formatJarsForJson(jars)
)
)
}
from(project.layout.settingsDirectory.file("../images/logo-48.png")) {
into("assets/tweed5")
}
into(project.layout.buildDirectory.dir("minecraftModResources"))
}
tasks.register<Sync>("processMinecraftTestmodResources") {
inputs.property("id", project.name)
inputs.property("version", project.version)
inputs.property("name", moduleInfo.name)
inputs.property("description", moduleInfo.description)
inputs.property("repoUrl", rootProperties["git.url"])
inputs.files(minecraftJijElements)
val jars = objects.fileCollection().apply { from(minecraftJijElements) }
from(project.layout.settingsDirectory.dir("../tweed5-minecraft/mod-template/resources")) {
expand(
mapOf(
"id" to "${project.name.replace('-', '_')}_testmod",
"version" to project.version,
"name" to "${moduleInfo.name.get()} (test mod)",
"description" to moduleInfo.description,
"repoUrl" to rootProperties["git.url"].get(),
"jars" to formatJarsForJson(jars)
)
)
}
into(project.layout.buildDirectory.dir("minecraftTestmodResources"))
}
@@ -0,0 +1,72 @@
import org.gradle.api.publish.internal.PublicationInternal
plugins {
`maven-publish`
id("de.siphalor.tweed5.minecraft.mod.base")
id("de.siphalor.tweed5.publishing")
}
val minecraftModJar = tasks.register<Jar>("minecraftModJar") {
group = LifecycleBasePlugin.BUILD_GROUP
dependsOn(tasks.shadowJar)
dependsOn(tasks.named("processMinecraftModResources"))
from(zipTree(tasks.shadowJar.get().archiveFile))
from(project.layout.buildDirectory.dir("minecraftModResources"))
destinationDirectory.set(layout.buildDirectory.dir("minecraftModLibs"))
}
tasks.assemble {
dependsOn(minecraftModJar)
}
val minecraftModSourcesJar = tasks.register<Jar>("minecraftModSourcesJar") {
group = LifecycleBasePlugin.BUILD_GROUP
dependsOn(tasks.named("processMinecraftModResources"))
from(project.layout.buildDirectory.dir("minecraftModResources"))
archiveClassifier = "sources"
destinationDirectory.set(layout.buildDirectory.dir("minecraftModLibs"))
}
artifacts.add("minecraftModElements", minecraftModJar)
artifacts.add("minecraftModApiElements", minecraftModJar)
afterEvaluate {
tasks.findByName("sourcesJar")?.let { sourcesJar ->
artifacts.add("minecraftModSourcesElements", minecraftModSourcesJar)
minecraftModSourcesJar.configure {
val sourcesJar = sourcesJar as Jar
dependsOn(sourcesJar)
val sourcesJarArtifact = objects.fileCollection().from(sourcesJar.archiveFile)
inputs.files(sourcesJarArtifact)
from(files(sourcesJarArtifact).map { zipTree(it) })
}
}
}
publishing {
publications {
create<MavenPublication>("minecraftMod") {
val projectGroup = project.group.toString()
groupId = if (projectGroup.endsWith(".minecraft")) projectGroup else "$projectGroup.minecraft"
artifactId = project.name
version = project.version.toString()
from(components["minecraftMod"])
}
}
}
// Required because the maven publish plugin only supports one publication per project dependency
// to be able to resolve the dependency's coordinates.
// Luckily, this is fine in our case, as the Minecraft mod jars should publish each other as dependencies
// anyway. With proper dependencies in place, missing dependencies tend to become an unexpected runtime
// error in Minecraft modding.
afterEvaluate {
if (publishing.publications.names.size > 1) {
(publishing.publications.findByName("minecraftMod") as? PublicationInternal<*>)?.isAlias = true
}
}
@@ -0,0 +1,37 @@
plugins {
`java-library`
`maven-publish`
id("de.siphalor.tweed5.root-properties")
id("de.siphalor.tweed5.module-info")
}
group = rootProject.group
version = rootProject.version
publishing {
repositories {
if (project.hasProperty("siphalor.maven.user")) {
maven {
name = "Siphalor"
url = uri("https://maven.siphalor.de/upload.php")
credentials {
username = project.property("siphalor.maven.user") as String
password = project.property("siphalor.maven.password") as String
}
}
}
}
publications.all {
if (this is MavenPublication) {
pom {
name = moduleInfo.name
description = moduleInfo.description
url = rootProperties["git.url"]
scm {
url = rootProperties["git.url"]
}
}
}
}
}
@@ -0,0 +1,14 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
id("com.gradleup.shadow")
}
val shadowOnlyConfiguration = configurations.dependencyScope("shadowOnly")
val shadowOnlyElementsConfiguration = configurations.resolvable("shadowOnlyElements") {
extendsFrom(shadowOnlyConfiguration.get())
}
tasks.named<ShadowJar>("shadowJar") {
configurations = listOf(shadowOnlyElementsConfiguration.get())
}
@@ -0,0 +1,21 @@
plugins {
java
id("io.freefair.lombok")
}
dependencies {
implementation(project(":tweed5-serde-api"))
implementation(platform(libs.junit.platform))
implementation(libs.junit.core)
implementation(libs.mockito)
implementation(libs.assertj)
}
lombok {
version = libs.versions.lombok.get()
}
java {
sourceCompatibility = JavaVersion.toVersion(libs.versions.java.test.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.java.test.get())
}
@@ -0,0 +1,48 @@
plugins {
java
jacoco
}
val testAgent = configurations.dependencyScope("mockitoAgent")
val testAgentClasspath = configurations.resolvable("testAgentClasspath") {
isTransitive = false
extendsFrom(testAgent.get())
}
dependencies {
versionCatalogs.find("libs").ifPresent { libs ->
testImplementation(platform(libs.findLibrary("junit.platform").get()))
testImplementation(libs.findLibrary("junit.core").get())
testRuntimeOnly(libs.findLibrary("junit.launcher").get())
testImplementation(libs.findLibrary("mockito").get())
testAgent(libs.findLibrary("mockito").get())
testImplementation(libs.findLibrary("assertj").get())
}
}
tasks.compileTestJava {
versionCatalogs.find("libs").ifPresent { libs ->
sourceCompatibility = libs.findVersion("java.test").get().requiredVersion
targetCompatibility = libs.findVersion("java.test").get().requiredVersion
}
}
tasks.test {
val testAgentFiles = testAgentClasspath.map { it.files }
doFirst {
jvmArgs(testAgentFiles.get().map { file -> "-javaagent:${file.absolutePath}" })
}
dependsOn(testAgentClasspath)
finalizedBy(tasks.jacocoTestReport)
useJUnitPlatform()
systemProperties(
"junit.jupiter.execution.timeout.mode" to "disabled_on_debug",
"junit.jupiter.execution.timeout.testable.method.default" to "30s",
"junit.jupiter.execution.timeout.thread.mode.default" to "SEPARATE_THREAD",
)
}
tasks.jacocoTestReport {
dependsOn(tasks.test)
}