From c1ef6b7dcdb381db00cf31ae8b1ff3c1feeb650e Mon Sep 17 00:00:00 2001 From: Siphalor Date: Sun, 25 Oct 2026 13:43:51 +0100 Subject: [PATCH] fix: Properly support isolated projects --- .../gradle/project_plugin/SmcmtkLoomProxy.kt | 36 +++++++++++- .../project_plugin/SmcmtkProjectPlugin.kt | 57 +++++++++++++------ .../settings_plugin/SmcmtkSettingsPlugin.kt | 7 ++- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt index 204c2bd..bf65255 100644 --- a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt @@ -1,5 +1,7 @@ package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin +import net.fabricmc.loom.LoomNoRemapGradlePlugin +import net.fabricmc.loom.LoomRemapGradlePlugin import net.fabricmc.loom.api.LoomGradleExtensionAPI import org.gradle.api.Project import org.gradle.api.artifacts.MinimalExternalModuleDependency @@ -9,8 +11,38 @@ import org.gradle.api.tasks.SourceSet import org.jetbrains.annotations.ApiStatus @ApiStatus.Internal -class SmcmtkLoomProxy(val project: Project, loomGradleExtensionApi: Any) { - val loom = loomGradleExtensionApi as LoomGradleExtensionAPI +class SmcmtkLoomProxy(val project: Project, loomGradleExtensionApi: () -> Any?) { + val loom by lazy { + val extension = loomGradleExtensionApi() ?: throw IllegalStateException( + "SMCMTK tried to access Loom extension but it was not present" + ) + extension as LoomGradleExtensionAPI + } + + fun hasPlainPlugin(): Boolean { + return project.plugins.hasPlugin(LoomNoRemapGradlePlugin::class.java) + } + + fun onPlainPlugin(action: () -> Unit) { + project.plugins.withType(LoomNoRemapGradlePlugin::class.java) { + action() + } + } + + fun hasRemapPlugin(): Boolean { + return project.plugins.hasPlugin(LoomRemapGradlePlugin::class.java) + } + + fun onRemapPlugin(action: () -> Unit) { + project.plugins.withType(LoomRemapGradlePlugin::class.java) { + action() + } + } + + fun isLoomPlainDetectionIssue(): Boolean { + return !project.plugins.hasPlugin(LoomNoRemapGradlePlugin.NAME) + && hasPlainPlugin() + } fun configureOfficialMojangMappings(parchment: Provider?) { if (parchment == null) { diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt index 17b5acd..207cfa4 100644 --- a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt @@ -15,8 +15,7 @@ import javax.inject.Inject abstract class SmcmtkProjectPlugin : Plugin { companion object { - private const val LOOM_PLAIN_PLUGIN_ID = "net.fabricmc.fabric-loom" - private const val LOOM_REMAP_PLUGIN_ID = "net.fabricmc.fabric-loom-remap" + private const val LOOM_SAMPLE_CLASS_NAME = "net.fabricmc.loom.LoomRemapGradlePlugin" private val MOD_BASE_CONFIGURATION_NAMES = arrayOf("api", "implementation", "compileOnly", "runtimeOnly", "localRuntime") @@ -29,12 +28,23 @@ abstract class SmcmtkProjectPlugin : Plugin { @get:Inject protected abstract val projectLayout: ProjectLayout - private val logger = lazy { Logging.getLogger(javaClass) } + private val logger by lazy { Logging.getLogger(javaClass) } private lateinit var project: Project private lateinit var extension: SmcmtkProjectExtension - private var loomProxy = lazy { project.extensions.findByName("loom")?.let { SmcmtkLoomProxy(project, it)} } + private var loomPresent = try { + Class.forName(LOOM_SAMPLE_CLASS_NAME, false, javaClass.classLoader); true + } catch (_: ClassNotFoundException) { + false + } + private val loomProxy by lazy { + if (loomPresent) { + SmcmtkLoomProxy(project) { project.extensions.findByName("loom") } + } else { + null + } + } override fun apply(project: Project) { this.project = project @@ -47,21 +57,28 @@ abstract class SmcmtkProjectPlugin : Plugin { extension.mcProps.convention(minecraftProperties.map { mapOf(*it.entries.map { entry -> entry.key.toString() to entry.value.toString() }.toTypedArray()) }) - project.plugins.withId(LOOM_PLAIN_PLUGIN_ID) { + loomProxy?.onPlainPlugin { project.configurations.maybeCreate("namedElements") .extendsFrom(project.configurations.getByName("apiElements")) + + if (loomProxy!!.isLoomPlainDetectionIssue()) { + logger.warn(""" + |Plain loom plugin is applied as a class not via a plugin id, this may cause issues with Loom not disabling remapping. + |If you apply the loom plugin through a convention plugin, make sure the convention build uses compileOnly instead of implementation. + """.trimMargin()) + } } } fun configureMojangMappings() { - project.plugins.withId(LOOM_REMAP_PLUGIN_ID) { + loomProxy?.onRemapPlugin { val versionCatalogs = project.extensions.getByType(VersionCatalogsExtension::class.java) val mcLibsCatalog = versionCatalogs.find("mcLibs").orElse(null) val parchment = mcLibsCatalog?.findLibrary("parchment")?.orElse(null) - loomProxy.value?.configureOfficialMojangMappings(parchment) + loomProxy?.configureOfficialMojangMappings(parchment) } - project.plugins.withId(LOOM_PLAIN_PLUGIN_ID) { + loomProxy?.onPlainPlugin { project.tasks.withType(ProcessResources::class.java).findByName("processResources")?.apply { filesMatching("*.accesswidener") { it.filter { line -> @@ -77,11 +94,11 @@ abstract class SmcmtkProjectPlugin : Plugin { } fun createModConfigurations(sourceSets: Collection) { - project.plugins.withId(LOOM_REMAP_PLUGIN_ID) { + loomProxy?.onRemapPlugin { sourceSets.filter { it.name != "main" } - .forEach { sourceSet -> loomProxy.value?.createRemapConfiguration(sourceSet) } + .forEach { sourceSet -> loomProxy?.createRemapConfiguration(sourceSet) } } - project.plugins.withId(LOOM_PLAIN_PLUGIN_ID) { + loomProxy?.onPlainPlugin { sourceSets.forEach { sourceSet -> val prefix = if (sourceSet.name == "main") "" else sourceSet.name @@ -98,31 +115,35 @@ abstract class SmcmtkProjectPlugin : Plugin { } fun configureAccessWidener(file: RegularFile) { - logger.value.debug("Configuring access widener {}", file) + logger.debug("Configuring access widener {}", file) if (!file.asFile.isFile) { - logger.value.debug("Skipping access widener configuration for non-existing file {}", file) + logger.debug("Skipping access widener configuration for non-existing file {}", file) return } - val accessWidenerNamesType = if (project.plugins.hasPlugin(LOOM_PLAIN_PLUGIN_ID)) { + if (!loomPresent) { + return + } + + val accessWidenerNamesType = if (loomProxy?.hasPlainPlugin() ?: false) { "official" - } else if (project.plugins.hasPlugin(LOOM_REMAP_PLUGIN_ID)) { + } else if (loomProxy?.hasRemapPlugin() ?: false) { "named" } else { null } if (accessWidenerNamesType != null) { - logger.value.info("Changing access widener names type of $file to $accessWidenerNamesType") + logger.info("Changing access widener names type of $file to $accessWidenerNamesType") file.asFile.writeText(file.asFile.readText(Charsets.UTF_8).lines().joinToString("\n") { line -> ACCESS_WIDENER_DECLARATION_PATTERN.matchAt(line, 0) ?.let { match -> line.substring(match.range) + accessWidenerNamesType } ?: line }) } else { - logger.value.warn("Could not determine access widener names type for $file") + logger.warn("Could not determine access widener names type for $file") } - loomProxy.value?.setAccessWidenerPath(file) + loomProxy?.setAccessWidenerPath(file) } } diff --git a/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt index 23c8937..6d81582 100644 --- a/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt +++ b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt @@ -61,8 +61,11 @@ abstract class SmcmtkSettingsPlugin : Plugin { settings.gradle.lifecycle.beforeProject { project -> project.extensions.findByType(ExtraPropertiesExtension::class.java)?.apply { // Loom uses the same jar for both plugin variants (plain and remap) and tries to determine - // which one is in use by checking the plugin manager. - // This doesn't seem to work when using convention plugins, so we're forcing the remapping off here. + // which one is in use by checking the plugin manager by the plugin id. + // This doesn't work when the Loom plugin is in the classpath already due to convention plugins. + // Since in this case Gradle doesn't register the plugin id, we're forcing the remapping off here. + // This notably doesn't work in isolated projects as Loom uses providers.gradleProperty there + // which can't be overwritten programmatically. set("fabric.loom.disableObfuscation", "true") set("fabric.loom.dontRemap", "true") }