fix: Properly support isolated projects

This commit is contained in:
Siphalor committed 2026-10-25 13:43:51 +01:00
1 parent 3152e4d3f5
commit c1ef6b7dcd
3 files changed
+78 -22

No files matched your search

@@ -1,5 +1,7 @@
package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin 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 net.fabricmc.loom.api.LoomGradleExtensionAPI
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.artifacts.MinimalExternalModuleDependency
@@ -9,8 +11,38 @@ import org.gradle.api.tasks.SourceSet
import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal @ApiStatus.Internal
class SmcmtkLoomProxy(val project: Project, loomGradleExtensionApi: Any) { class SmcmtkLoomProxy(val project: Project, loomGradleExtensionApi: () -> Any?) {
val loom = loomGradleExtensionApi as LoomGradleExtensionAPI 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<MinimalExternalModuleDependency>?) { fun configureOfficialMojangMappings(parchment: Provider<MinimalExternalModuleDependency>?) {
if (parchment == null) { if (parchment == null) {
@@ -15,8 +15,7 @@ import javax.inject.Inject
abstract class SmcmtkProjectPlugin : Plugin<Project> { abstract class SmcmtkProjectPlugin : Plugin<Project> {
companion object { companion object {
private const val LOOM_PLAIN_PLUGIN_ID = "net.fabricmc.fabric-loom" private const val LOOM_SAMPLE_CLASS_NAME = "net.fabricmc.loom.LoomRemapGradlePlugin"
private const val LOOM_REMAP_PLUGIN_ID = "net.fabricmc.fabric-loom-remap"
private val MOD_BASE_CONFIGURATION_NAMES = arrayOf("api", "implementation", "compileOnly", "runtimeOnly", "localRuntime") private val MOD_BASE_CONFIGURATION_NAMES = arrayOf("api", "implementation", "compileOnly", "runtimeOnly", "localRuntime")
@@ -29,12 +28,23 @@ abstract class SmcmtkProjectPlugin : Plugin<Project> {
@get:Inject @get:Inject
protected abstract val projectLayout: ProjectLayout 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 project: Project
private lateinit var extension: SmcmtkProjectExtension 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) { override fun apply(project: Project) {
this.project = project this.project = project
@@ -47,21 +57,28 @@ abstract class SmcmtkProjectPlugin : Plugin<Project> {
extension.mcProps.convention(minecraftProperties.map { mapOf(*it.entries.map { entry -> entry.key.toString() to entry.value.toString() }.toTypedArray()) }) 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") project.configurations.maybeCreate("namedElements")
.extendsFrom(project.configurations.getByName("apiElements")) .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() { fun configureMojangMappings() {
project.plugins.withId(LOOM_REMAP_PLUGIN_ID) { loomProxy?.onRemapPlugin {
val versionCatalogs = project.extensions.getByType(VersionCatalogsExtension::class.java) val versionCatalogs = project.extensions.getByType(VersionCatalogsExtension::class.java)
val mcLibsCatalog = versionCatalogs.find("mcLibs").orElse(null) val mcLibsCatalog = versionCatalogs.find("mcLibs").orElse(null)
val parchment = mcLibsCatalog?.findLibrary("parchment")?.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 { project.tasks.withType(ProcessResources::class.java).findByName("processResources")?.apply {
filesMatching("*.accesswidener") { filesMatching("*.accesswidener") {
it.filter { line -> it.filter { line ->
@@ -77,11 +94,11 @@ abstract class SmcmtkProjectPlugin : Plugin<Project> {
} }
fun createModConfigurations(sourceSets: Collection<SourceSet>) { fun createModConfigurations(sourceSets: Collection<SourceSet>) {
project.plugins.withId(LOOM_REMAP_PLUGIN_ID) { loomProxy?.onRemapPlugin {
sourceSets.filter { it.name != "main" } 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 -> sourceSets.forEach { sourceSet ->
val prefix = if (sourceSet.name == "main") "" else sourceSet.name val prefix = if (sourceSet.name == "main") "" else sourceSet.name
@@ -98,31 +115,35 @@ abstract class SmcmtkProjectPlugin : Plugin<Project> {
} }
fun configureAccessWidener(file: RegularFile) { fun configureAccessWidener(file: RegularFile) {
logger.value.debug("Configuring access widener {}", file) logger.debug("Configuring access widener {}", file)
if (!file.asFile.isFile) { 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 return
} }
val accessWidenerNamesType = if (project.plugins.hasPlugin(LOOM_PLAIN_PLUGIN_ID)) { if (!loomPresent) {
return
}
val accessWidenerNamesType = if (loomProxy?.hasPlainPlugin() ?: false) {
"official" "official"
} else if (project.plugins.hasPlugin(LOOM_REMAP_PLUGIN_ID)) { } else if (loomProxy?.hasRemapPlugin() ?: false) {
"named" "named"
} else { } else {
null null
} }
if (accessWidenerNamesType != 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 -> file.asFile.writeText(file.asFile.readText(Charsets.UTF_8).lines().joinToString("\n") { line ->
ACCESS_WIDENER_DECLARATION_PATTERN.matchAt(line, 0) ACCESS_WIDENER_DECLARATION_PATTERN.matchAt(line, 0)
?.let { match -> line.substring(match.range) + accessWidenerNamesType } ?.let { match -> line.substring(match.range) + accessWidenerNamesType }
?: line ?: line
}) })
} else { } 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)
} }
} }
@@ -61,8 +61,11 @@ abstract class SmcmtkSettingsPlugin : Plugin<Settings> {
settings.gradle.lifecycle.beforeProject { project -> settings.gradle.lifecycle.beforeProject { project ->
project.extensions.findByType(ExtraPropertiesExtension::class.java)?.apply { project.extensions.findByType(ExtraPropertiesExtension::class.java)?.apply {
// Loom uses the same jar for both plugin variants (plain and remap) and tries to determine // 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. // which one is in use by checking the plugin manager by the plugin id.
// This doesn't seem to work when using convention plugins, so we're forcing the remapping off here. // 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.disableObfuscation", "true")
set("fabric.loom.dontRemap", "true") set("fabric.loom.dontRemap", "true")
} }