From a70654abffe05ac7246a10b96792b480077ad4b4 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Thu, 29 Jul 2021 23:05:25 +0800 Subject: [PATCH] Bump to 3.3, support for transformer 4.1 with properties Signed-off-by: shedaniel --- .github/workflows/gradle.yml | 1 + gradle.properties | 4 +- .../architectury/plugin/ArchitecturyPlugin.kt | 26 --- .../plugin/ArchitecturyPluginExtension.kt | 170 +++++++++++++++--- .../architectury/plugin/TransformingTask.kt | 23 ++- 5 files changed, 167 insertions(+), 57 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 7bded7f..6531461 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -4,6 +4,7 @@ on: push: branches: - master + - 3.3 jobs: build: diff --git a/gradle.properties b/gradle.properties index bd74d5e..4afa249 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official loom_version_old=0.6.96 loom_version_new=0.9.0.158 -transformer_version=4.0.49 -base_version=3.2 \ No newline at end of file +transformer_version=4.1.50 +base_version=3.3 \ No newline at end of file diff --git a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPlugin.kt b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPlugin.kt index 304a9a5..22848c3 100644 --- a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPlugin.kt +++ b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPlugin.kt @@ -44,32 +44,6 @@ class ArchitecturyPlugin : Plugin { project.extensions.create("architectury", ArchitectPluginExtension::class.java, project) - project.configurations.create("transformFabric") - project.configurations.create("transformForge") - - project.tasks.register("transformProductionFabric", TransformingTask::class.java) { - it.group = "Architectury" - it.platform = "fabric" - it += RemapMixinVariables() - it += TransformExpectPlatform() - it += RemapInjectables() - it += AddRefmapName() - it += TransformPlatformOnly() - } - - project.tasks.register("transformProductionForge", TransformingTask::class.java) { - it.group = "Architectury" - it.platform = "forge" - it += TransformExpectPlatform() - it += RemapInjectables() - it += AddRefmapName() - it += TransformPlatformOnly() - - it += TransformForgeAnnotations() - it += TransformForgeEnvironment() - it += FixForgeMixin() - } - project.repositories.apply { mavenCentral() maven { it.url = URI("https://maven.architectury.dev/") } diff --git a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt index 35f86cf..3cd48f7 100644 --- a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt +++ b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt @@ -3,22 +3,32 @@ package dev.architectury.plugin import dev.architectury.plugin.loom.LoomInterface +import dev.architectury.plugin.transformers.AddRefmapName import dev.architectury.transformer.Transformer import dev.architectury.transformer.input.OpenedOutputInterface +import dev.architectury.transformer.shadowed.impl.com.google.common.hash.Hashing +import dev.architectury.transformer.shadowed.impl.com.google.gson.Gson +import dev.architectury.transformer.shadowed.impl.com.google.gson.JsonObject import dev.architectury.transformer.transformers.* +import dev.architectury.transformer.transformers.properties.TransformersWriter +import dev.architectury.transformer.util.TransformerPair import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.jvm.tasks.Jar import java.io.File +import java.io.StringWriter +import java.nio.charset.StandardCharsets import java.nio.file.Path import java.util.* +import java.util.function.BiConsumer +import java.util.function.Function import java.util.jar.JarOutputStream import java.util.jar.Manifest open class ArchitectPluginExtension(val project: Project) { - var transformerVersion = "4.0.49" + var transformerVersion = "4.1.50" var injectablesVersion = "1.0.10" var minecraft = "" var injectInjectables = true @@ -45,14 +55,16 @@ open class ArchitectPluginExtension(val project: Project) { it.parentFile.mkdirs() } } - + private val loom: LoomInterface by lazy { try { Class.forName("net.fabricmc.loom.api.LoomGradleExtensionAPI") - return@lazy Class.forName("dev.architectury.plugin.loom.LoomInterface09").getDeclaredConstructor(Project::class.java) + return@lazy Class.forName("dev.architectury.plugin.loom.LoomInterface09") + .getDeclaredConstructor(Project::class.java) .newInstance(project) as LoomInterface } catch (ignored: ClassNotFoundException) { - return@lazy Class.forName("dev.architectury.plugin.loom.LoomInterface06").getDeclaredConstructor(Project::class.java) + return@lazy Class.forName("dev.architectury.plugin.loom.LoomInterface06") + .getDeclaredConstructor(Project::class.java) .newInstance(project) as LoomInterface } } @@ -60,17 +72,20 @@ open class ArchitectPluginExtension(val project: Project) { init { project.afterEvaluate { if (transforms.isNotEmpty()) { - val transformPaths = mutableMapOf>>() - for (transform in transforms.values) { - project.configurations.getByName(transform.configName).forEach { - transformPaths[it.toPath()] = transform.transformers + StringWriter().also { strWriter -> + TransformersWriter(strWriter).use { writer -> + for (transform in transforms.values) { + project.configurations.getByName(transform.configName).forEach { file -> + transform.transformers.map { it.apply(file.toPath()) } + .forEach { pair -> + writer.write(file.toPath(), pair.clazz, pair.properties) + } + } + } } + + runtimeTransformerFile.writeText(strWriter.toString()) } - transformPaths.asSequence().flatMap { it.value.asSequence().map { c -> it.key to c } } - .joinToString(File.pathSeparator) { "${it.first}|${it.second.name}" } - .also { - runtimeTransformerFile.writeText(it) - } val properties = Properties() properties(transforms.keys.first()).forEach { (key, value) -> @@ -97,12 +112,13 @@ open class ArchitectPluginExtension(val project: Project) { } private fun getCompileClasspath(): Iterable { - return project.configurations.findByName("architecturyTransformerClasspath") ?: project.configurations.getByName("compileClasspath") + return project.configurations.findByName("architecturyTransformerClasspath") + ?: project.configurations.getByName("compileClasspath") } fun transform(name: String, action: Action) { transforms.getOrPut(name) { - Transform("development" + name.capitalize()).also { transform -> + Transform(project, "development" + name.capitalize()).also { transform -> project.configurations.create(transform.configName) if (!transformedLoom) { @@ -119,9 +135,15 @@ open class ArchitectPluginExtension(val project: Project) { with(project.dependencies) { add("runtimeOnly", "dev.architectury:architectury-transformer:$transformerVersion:runtime") - add("architecturyJavaAgents", "dev.architectury:architectury-transformer:$transformerVersion:agent") + add( + "architecturyJavaAgents", + "dev.architectury:architectury-transformer:$transformerVersion:agent" + ) if (plsAddInjectables && injectInjectables) { - add("architecturyTransformerClasspath", "dev.architectury:architectury-injectables:$injectablesVersion") + add( + "architecturyTransformerClasspath", + "dev.architectury:architectury-injectables:$injectablesVersion" + ) add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also { it as ModuleDependency it.isTransitive = false @@ -215,7 +237,10 @@ open class ArchitectPluginExtension(val project: Project) { add("compileOnly", "dev.architectury:architectury-injectables:$injectablesVersion") if (plsAddInjectables) { - add("architecturyTransformerClasspath", "dev.architectury:architectury-injectables:$injectablesVersion") + add( + "architecturyTransformerClasspath", + "dev.architectury:architectury-injectables:$injectablesVersion" + ) add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also { it as ModuleDependency it.isTransitive = false @@ -224,6 +249,7 @@ open class ArchitectPluginExtension(val project: Project) { } } + addTasks() if (settings.forgeEnabled) { project.configurations.create("transformProductionForge") } @@ -286,6 +312,47 @@ open class ArchitectPluginExtension(val project: Project) { transformProductionFabricTask.archiveFile.get().asFile.takeUnless { it.exists() }?.createEmptyJar() } + + private fun addTasks() { + project.tasks.register("transformProductionFabric", TransformingTask::class.java) { + it.group = "Architectury" + it.platform = "fabric" + it += RemapMixinVariables() + it.add(TransformExpectPlatform()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } + it.add(RemapInjectables()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } + it += AddRefmapName() + it += TransformPlatformOnly() + } + + project.tasks.register("transformProductionForge", TransformingTask::class.java) { + it.group = "Architectury" + it.platform = "forge" + it.add(TransformExpectPlatform()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } + it.add(RemapInjectables()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } + it += AddRefmapName() + it += TransformPlatformOnly() + + it += TransformForgeAnnotations() + it += TransformForgeEnvironment() + it += FixForgeMixin() + } + } } private fun File.createEmptyJar() { @@ -293,19 +360,39 @@ private fun File.createEmptyJar() { JarOutputStream(outputStream(), Manifest()).close() } -data class Transform(val configName: String, val transformers: MutableList> = mutableListOf()) { +data class Transform( + val project: Project, + val configName: String, + val transformers: MutableList> = mutableListOf() +) { fun setupFabricTransforms() { this += RuntimeMixinRefmapDetector::class.java this += GenerateFakeFabricMod::class.java - this += TransformExpectPlatform::class.java - this += RemapInjectables::class.java + add(TransformExpectPlatform::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } + add(RemapInjectables::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } this += TransformPlatformOnly::class.java } fun setupForgeTransforms() { this += RuntimeMixinRefmapDetector::class.java - this += TransformExpectPlatform::class.java - this += RemapInjectables::class.java + add(TransformExpectPlatform::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } + add(RemapInjectables::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName(); + } this += TransformPlatformOnly::class.java this += TransformForgeAnnotations::class.java @@ -314,9 +401,38 @@ data class Transform(val configName: String, val transformers: MutableList plusAssign(transformer: Class) { - transformers.add(transformer as Class) + operator fun plusAssign(transformer: TransformerPair) { + transformers.add(Function { transformer }) } - fun add(transformer: Class) = plusAssign(transformer as Class) -} \ No newline at end of file + operator fun plusAssign(transformer: Class) { + this += TransformerPair(transformer, null) + } + + fun add(transformer: Class) { + this += TransformerPair(transformer, null) + } + + fun add(transformer: Class, properties: JsonObject) = + plusAssign(TransformerPair(transformer, properties)) + + fun add(transformer: Class, config: BiConsumer>) { + transformers.add(Function { file -> + val properties = mutableMapOf() + config.accept(file, properties) + TransformerPair(transformer, Gson().toJsonTree(properties).asJsonObject) + }) + } + + fun add(transformer: Class, config: MutableMap.(file: Path) -> Unit) { + add(transformer, BiConsumer { file, map -> + config(map, file) + }) + } +} + +fun String.legalizePackageName(): String = + filter { Character.isJavaIdentifierPart(it) } + +private val ByteArray.sha256: String + get() = Hashing.sha256().hashBytes(this).toString() diff --git a/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt b/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt index e77882c..499ae5f 100644 --- a/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt +++ b/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt @@ -3,10 +3,13 @@ package dev.architectury.plugin import dev.architectury.plugin.utils.GradleSupport import dev.architectury.transformer.Transform import dev.architectury.transformer.Transformer +import dev.architectury.transformer.shadowed.impl.com.google.gson.Gson import dev.architectury.transformer.transformers.BuiltinProperties import dev.architectury.transformer.util.Logger +import dev.architectury.transformer.util.TransformerPair import org.gradle.api.Project import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction @@ -14,6 +17,7 @@ import org.gradle.jvm.tasks.Jar import java.io.File import java.nio.file.Path import java.util.* +import java.util.function.BiConsumer import kotlin.properties.Delegates import kotlin.time.ExperimentalTime @@ -22,7 +26,7 @@ open class TransformingTask : Jar() { val input: RegularFileProperty = GradleSupport.getFileProperty(project) @Internal - val transformers = mutableListOf() + val transformers: ListProperty = project.objects.listProperty(Transformer::class.java) @Internal var platform: String? = null @@ -43,7 +47,7 @@ open class TransformingTask : Jar() { Logger.debug("Transforming from $input to $output") Logger.debug("============================") Logger.debug("") - Transform.runTransformers(input, output, transformers) + Transform.runTransformers(input, output, transformers.get()) } operator fun invoke(transformer: Transformer) { @@ -53,6 +57,21 @@ open class TransformingTask : Jar() { operator fun plusAssign(transformer: Transformer) { transformers.add(transformer) } + + fun add(transformer: Transformer, config: BiConsumer>) { + transformers.add(project.provider { + val properties = mutableMapOf() + config.accept(input.asFile.get().toPath(), properties) + transformer.supplyProperties(Gson().toJsonTree(properties).asJsonObject) + transformer + }) + } + + fun add(transformer: Transformer, config: MutableMap.(file: Path) -> Unit) { + add(transformer, BiConsumer { file, map -> + config(map, file) + }) + } } fun Project.projectUniqueIdentifier(): String {