Bump to 3.3, support for transformer 4.1 with properties

Signed-off-by: shedaniel <daniel@shedaniel.me>
This commit is contained in:
shedaniel
2021-07-29 23:05:25 +08:00
parent 6383e74daa
commit a70654abff
5 changed files with 167 additions and 57 deletions

View File

@@ -4,6 +4,7 @@ on:
push: push:
branches: branches:
- master - master
- 3.3
jobs: jobs:
build: build:

View File

@@ -1,5 +1,5 @@
kotlin.code.style=official kotlin.code.style=official
loom_version_old=0.6.96 loom_version_old=0.6.96
loom_version_new=0.9.0.158 loom_version_new=0.9.0.158
transformer_version=4.0.49 transformer_version=4.1.50
base_version=3.2 base_version=3.3

View File

@@ -44,32 +44,6 @@ class ArchitecturyPlugin : Plugin<Project> {
project.extensions.create("architectury", ArchitectPluginExtension::class.java, project) 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 { project.repositories.apply {
mavenCentral() mavenCentral()
maven { it.url = URI("https://maven.architectury.dev/") } maven { it.url = URI("https://maven.architectury.dev/") }

View File

@@ -3,22 +3,32 @@
package dev.architectury.plugin package dev.architectury.plugin
import dev.architectury.plugin.loom.LoomInterface import dev.architectury.plugin.loom.LoomInterface
import dev.architectury.plugin.transformers.AddRefmapName
import dev.architectury.transformer.Transformer import dev.architectury.transformer.Transformer
import dev.architectury.transformer.input.OpenedOutputInterface 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.*
import dev.architectury.transformer.transformers.properties.TransformersWriter
import dev.architectury.transformer.util.TransformerPair
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import java.io.File import java.io.File
import java.io.StringWriter
import java.nio.charset.StandardCharsets
import java.nio.file.Path import java.nio.file.Path
import java.util.* import java.util.*
import java.util.function.BiConsumer
import java.util.function.Function
import java.util.jar.JarOutputStream import java.util.jar.JarOutputStream
import java.util.jar.Manifest import java.util.jar.Manifest
open class ArchitectPluginExtension(val project: Project) { open class ArchitectPluginExtension(val project: Project) {
var transformerVersion = "4.0.49" var transformerVersion = "4.1.50"
var injectablesVersion = "1.0.10" var injectablesVersion = "1.0.10"
var minecraft = "" var minecraft = ""
var injectInjectables = true var injectInjectables = true
@@ -45,14 +55,16 @@ open class ArchitectPluginExtension(val project: Project) {
it.parentFile.mkdirs() it.parentFile.mkdirs()
} }
} }
private val loom: LoomInterface by lazy { private val loom: LoomInterface by lazy {
try { try {
Class.forName("net.fabricmc.loom.api.LoomGradleExtensionAPI") 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 .newInstance(project) as LoomInterface
} catch (ignored: ClassNotFoundException) { } 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 .newInstance(project) as LoomInterface
} }
} }
@@ -60,17 +72,20 @@ open class ArchitectPluginExtension(val project: Project) {
init { init {
project.afterEvaluate { project.afterEvaluate {
if (transforms.isNotEmpty()) { if (transforms.isNotEmpty()) {
val transformPaths = mutableMapOf<Path, List<Class<Transformer>>>() StringWriter().also { strWriter ->
for (transform in transforms.values) { TransformersWriter(strWriter).use { writer ->
project.configurations.getByName(transform.configName).forEach { for (transform in transforms.values) {
transformPaths[it.toPath()] = transform.transformers 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() val properties = Properties()
properties(transforms.keys.first()).forEach { (key, value) -> properties(transforms.keys.first()).forEach { (key, value) ->
@@ -97,12 +112,13 @@ open class ArchitectPluginExtension(val project: Project) {
} }
private fun getCompileClasspath(): Iterable<File> { private fun getCompileClasspath(): Iterable<File> {
return project.configurations.findByName("architecturyTransformerClasspath") ?: project.configurations.getByName("compileClasspath") return project.configurations.findByName("architecturyTransformerClasspath")
?: project.configurations.getByName("compileClasspath")
} }
fun transform(name: String, action: Action<Transform>) { fun transform(name: String, action: Action<Transform>) {
transforms.getOrPut(name) { transforms.getOrPut(name) {
Transform("development" + name.capitalize()).also { transform -> Transform(project, "development" + name.capitalize()).also { transform ->
project.configurations.create(transform.configName) project.configurations.create(transform.configName)
if (!transformedLoom) { if (!transformedLoom) {
@@ -119,9 +135,15 @@ open class ArchitectPluginExtension(val project: Project) {
with(project.dependencies) { with(project.dependencies) {
add("runtimeOnly", "dev.architectury:architectury-transformer:$transformerVersion:runtime") 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) { if (plsAddInjectables && injectInjectables) {
add("architecturyTransformerClasspath", "dev.architectury:architectury-injectables:$injectablesVersion") add(
"architecturyTransformerClasspath",
"dev.architectury:architectury-injectables:$injectablesVersion"
)
add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also { add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also {
it as ModuleDependency it as ModuleDependency
it.isTransitive = false it.isTransitive = false
@@ -215,7 +237,10 @@ open class ArchitectPluginExtension(val project: Project) {
add("compileOnly", "dev.architectury:architectury-injectables:$injectablesVersion") add("compileOnly", "dev.architectury:architectury-injectables:$injectablesVersion")
if (plsAddInjectables) { if (plsAddInjectables) {
add("architecturyTransformerClasspath", "dev.architectury:architectury-injectables:$injectablesVersion") add(
"architecturyTransformerClasspath",
"dev.architectury:architectury-injectables:$injectablesVersion"
)
add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also { add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also {
it as ModuleDependency it as ModuleDependency
it.isTransitive = false it.isTransitive = false
@@ -224,6 +249,7 @@ open class ArchitectPluginExtension(val project: Project) {
} }
} }
addTasks()
if (settings.forgeEnabled) { if (settings.forgeEnabled) {
project.configurations.create("transformProductionForge") project.configurations.create("transformProductionForge")
} }
@@ -286,6 +312,47 @@ open class ArchitectPluginExtension(val project: Project) {
transformProductionFabricTask.archiveFile.get().asFile.takeUnless { it.exists() }?.createEmptyJar() 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() { private fun File.createEmptyJar() {
@@ -293,19 +360,39 @@ private fun File.createEmptyJar() {
JarOutputStream(outputStream(), Manifest()).close() JarOutputStream(outputStream(), Manifest()).close()
} }
data class Transform(val configName: String, val transformers: MutableList<Class<Transformer>> = mutableListOf()) { data class Transform(
val project: Project,
val configName: String,
val transformers: MutableList<Function<Path, TransformerPair>> = mutableListOf()
) {
fun setupFabricTransforms() { fun setupFabricTransforms() {
this += RuntimeMixinRefmapDetector::class.java this += RuntimeMixinRefmapDetector::class.java
this += GenerateFakeFabricMod::class.java this += GenerateFakeFabricMod::class.java
this += TransformExpectPlatform::class.java add(TransformExpectPlatform::class.java) { file ->
this += RemapInjectables::class.java 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 += TransformPlatformOnly::class.java
} }
fun setupForgeTransforms() { fun setupForgeTransforms() {
this += RuntimeMixinRefmapDetector::class.java this += RuntimeMixinRefmapDetector::class.java
this += TransformExpectPlatform::class.java add(TransformExpectPlatform::class.java) { file ->
this += RemapInjectables::class.java 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 += TransformPlatformOnly::class.java
this += TransformForgeAnnotations::class.java this += TransformForgeAnnotations::class.java
@@ -314,9 +401,38 @@ data class Transform(val configName: String, val transformers: MutableList<Class
this += FixForgeMixin::class.java this += FixForgeMixin::class.java
} }
operator fun <T : Transformer> plusAssign(transformer: Class<T>) { operator fun plusAssign(transformer: TransformerPair) {
transformers.add(transformer as Class<Transformer>) transformers.add(Function { transformer })
} }
fun <T : Transformer> add(transformer: Class<T>) = plusAssign(transformer as Class<Transformer>) operator fun <T : Transformer> plusAssign(transformer: Class<T>) {
} this += TransformerPair(transformer, null)
}
fun <T : Transformer> add(transformer: Class<T>) {
this += TransformerPair(transformer, null)
}
fun <T : Transformer> add(transformer: Class<T>, properties: JsonObject) =
plusAssign(TransformerPair(transformer, properties))
fun <T : Transformer> add(transformer: Class<T>, config: BiConsumer<Path, MutableMap<String, Any>>) {
transformers.add(Function { file ->
val properties = mutableMapOf<String, Any>()
config.accept(file, properties)
TransformerPair(transformer, Gson().toJsonTree(properties).asJsonObject)
})
}
fun <T : Transformer> add(transformer: Class<T>, config: MutableMap<String, Any>.(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()

View File

@@ -3,10 +3,13 @@ package dev.architectury.plugin
import dev.architectury.plugin.utils.GradleSupport import dev.architectury.plugin.utils.GradleSupport
import dev.architectury.transformer.Transform import dev.architectury.transformer.Transform
import dev.architectury.transformer.Transformer 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.transformers.BuiltinProperties
import dev.architectury.transformer.util.Logger import dev.architectury.transformer.util.Logger
import dev.architectury.transformer.util.TransformerPair
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
@@ -14,6 +17,7 @@ import org.gradle.jvm.tasks.Jar
import java.io.File import java.io.File
import java.nio.file.Path import java.nio.file.Path
import java.util.* import java.util.*
import java.util.function.BiConsumer
import kotlin.properties.Delegates import kotlin.properties.Delegates
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
@@ -22,7 +26,7 @@ open class TransformingTask : Jar() {
val input: RegularFileProperty = GradleSupport.getFileProperty(project) val input: RegularFileProperty = GradleSupport.getFileProperty(project)
@Internal @Internal
val transformers = mutableListOf<Transformer>() val transformers: ListProperty<Transformer> = project.objects.listProperty(Transformer::class.java)
@Internal @Internal
var platform: String? = null var platform: String? = null
@@ -43,7 +47,7 @@ open class TransformingTask : Jar() {
Logger.debug("Transforming from $input to $output") Logger.debug("Transforming from $input to $output")
Logger.debug("============================") Logger.debug("============================")
Logger.debug("") Logger.debug("")
Transform.runTransformers(input, output, transformers) Transform.runTransformers(input, output, transformers.get())
} }
operator fun invoke(transformer: Transformer) { operator fun invoke(transformer: Transformer) {
@@ -53,6 +57,21 @@ open class TransformingTask : Jar() {
operator fun plusAssign(transformer: Transformer) { operator fun plusAssign(transformer: Transformer) {
transformers.add(transformer) transformers.add(transformer)
} }
fun add(transformer: Transformer, config: BiConsumer<Path, MutableMap<String, Any>>) {
transformers.add(project.provider {
val properties = mutableMapOf<String, Any>()
config.accept(input.asFile.get().toPath(), properties)
transformer.supplyProperties(Gson().toJsonTree(properties).asJsonObject)
transformer
})
}
fun add(transformer: Transformer, config: MutableMap<String, Any>.(file: Path) -> Unit) {
add(transformer, BiConsumer { file, map ->
config(map, file)
})
}
} }
fun Project.projectUniqueIdentifier(): String { fun Project.projectUniqueIdentifier(): String {