diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml deleted file mode 100644 index df999a1..0000000 --- a/.github/workflows/snapshot.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Snapshot Compile & Release - -on: - [pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Upload to Maven - run: ./gradlew publish - env: - MAVEN_PASS: ${{ secrets.MAVEN_PASS }} - PR_NUM: ${{github.event.number}} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 1b73467..67aff2d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ loom_version_09=0.9.0.158 loom_version_010Legacy=0.10.0.171 loom_version_010=0.10.0.188 loom_version_011=0.11.0.217 -transformer_version=5.2.61 +transformer_version=5.2.64 base_version=3.4 \ No newline at end of file diff --git a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt index c9d622e..7627c69 100644 --- a/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt +++ b/src/main/kotlin/dev/architectury/plugin/ArchitecturyPluginExtension.kt @@ -3,13 +3,12 @@ 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.OpenedFileAccess 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.BuiltinProperties import dev.architectury.transformer.transformers.properties.TransformersWriter import dev.architectury.transformer.util.TransformerPair import org.gradle.api.Action @@ -30,7 +29,7 @@ import java.util.jar.JarOutputStream import java.util.jar.Manifest open class ArchitectPluginExtension(val project: Project) { - var transformerVersion = "5.2.61" + var transformerVersion = "5.2.64" var injectablesVersion = "1.0.10" var minecraft = "" var injectInjectables = true @@ -59,34 +58,7 @@ open class ArchitectPluginExtension(val project: Project) { } private val loom: LoomInterface by lazy { - useIfFound( - "net.fabricmc.loom.util.service.SharedServiceManager", - "dev.architectury.plugin.loom.LoomInterface011" // 0.11.0 - ) ?: useIfFound( - "net.fabricmc.loom.util.ZipUtils", - "dev.architectury.plugin.loom.LoomInterface010" // >0.10.0.188 - ) ?: useIfFound( - "net.fabricmc.loom.api.MixinExtensionAPI", - "dev.architectury.plugin.loom.LoomInterface010Legacy" // 0.10.0 - ) ?: useIfFound( - "net.fabricmc.loom.api.LoomGradleExtensionAPI", - "dev.architectury.plugin.loom.LoomInterface09" // 0.9.0 - ) ?: use("dev.architectury.plugin.loom.LoomInterface06") // 0.6.0 - } - - fun useIfFound(className: String, interfaceName: String): LoomInterface? { - return try { - Class.forName(className) - use(interfaceName) - } catch (ignored: ClassNotFoundException) { - null - } - } - - fun use(interfaceName: String): LoomInterface { - return Class.forName(interfaceName) - .getDeclaredConstructor(Project::class.java) - .newInstance(project) as LoomInterface + LoomInterface.get(project) } init { @@ -117,7 +89,7 @@ open class ArchitectPluginExtension(val project: Project) { BuiltinProperties.UNIQUE_IDENTIFIER to project.projectUniqueIdentifier(), BuiltinProperties.COMPILE_CLASSPATH to getCompileClasspath().joinToString(File.pathSeparator), BuiltinProperties.MAPPINGS_WITH_SRG to loom.tinyMappingsWithSrg.toString(), - "architectury.platform.name" to platform, + BuiltinProperties.PLATFORM_NAME to platform, BuiltinProperties.REFMAP_NAME to loom.refmapName, BuiltinProperties.MCMETA_VERSION to "4" ) @@ -159,7 +131,8 @@ open class ArchitectPluginExtension(val project: Project) { fun transform(name: String, action: Action) { transforms.getOrPut(name) { Transform(project, "development" + name.capitalize()).also { transform -> - project.configurations.create(transform.configName) + project.configurations.maybeCreate(transform.configName) + action.execute(transform) if (!transformedLoom) { var plsAddInjectables = false @@ -188,7 +161,7 @@ open class ArchitectPluginExtension(val project: Project) { "architecturyTransformerClasspath", "dev.architectury:architectury-injectables:$injectablesVersion" ) - add("architecturyTransformerClasspath", "net.fabricmc:fabric-loader:+")?.also { + add("architecturyTransformerClasspath", transform.envAnnotationProvider)?.also { it as ModuleDependency it.isTransitive = false } @@ -217,8 +190,6 @@ open class ArchitectPluginExtension(val project: Project) { } } } - }.also { - action.execute(it) } } @@ -231,35 +202,89 @@ open class ArchitectPluginExtension(val project: Project) { @JvmOverloads fun fabric(action: Action = Action {}) { - transform("fabric", Action { - it.setupFabricTransforms() - action.execute(it) - }) + loader(ModLoader.FABRIC, action) } @JvmOverloads fun forge(action: Action = Action {}) { - transform("forge", Action { - it.setupForgeTransforms() + loader(ModLoader.FORGE, action) + } + + @JvmOverloads + fun loader(id: String, action: Action = Action {}) { + loader(ModLoader.valueOf(id), action) + } + + @JvmOverloads + fun loader(loader: ModLoader, action: Action = Action {}) { + transform(loader.id, Action { + loader.transformDevelopment(it) action.execute(it) }) } fun common() { + project.logger.warn("architectury's common() is deprecated, use common(String... platforms) instead") common {} } data class CommonSettings( - var forgeEnabled: Boolean = true - ) + val loaders: MutableSet = LinkedHashSet(), + ) { + constructor(loaders: Array) : this() { + this.loaders.addAll(loaders.map { ModLoader.valueOf(it) }) + } + + @Deprecated("Use add and remove directly") + var forgeEnabled: Boolean + get() = loaders.any { it.id == "forge" } + set(value) { + if (value) { + loaders.add(ModLoader.FORGE) + } else { + loaders.removeAll { it.id == "forge" } + } + } + + fun add(id: String) { + loaders.add(ModLoader.valueOf(id)) + } + + fun remove(id: String) { + loaders.removeAll { it.id == id } + } + + fun add(vararg id: String) { + loaders.addAll(id.map { ModLoader.valueOf(it) }) + } + + fun remove(vararg id: String) { + loaders.removeAll { id.contains(it.id) } + } + + fun add(id: Iterable) { + loaders.addAll(id.map { ModLoader.valueOf(it) }) + } + + fun remove(id: Iterable) { + loaders.removeAll { id.contains(it.id) } + } + + fun clear() { + loaders.clear() + } + } fun platformSetupLoomIde() { loom.setIdeConfigGenerated() } fun common(forgeEnabled: Boolean) { + project.logger.warn("architectury's common(Boolean forgeEnabled) is deprecated, use common(String... platforms) instead") common { - this.forgeEnabled = forgeEnabled + if (!forgeEnabled) { + remove("forge") + } } } @@ -267,8 +292,31 @@ open class ArchitectPluginExtension(val project: Project) { common(Action { it.action() }) } + @JvmOverloads + fun common(vararg platforms: String, action: CommonSettings.() -> Unit = {}) { + common { + clear() + add(*platforms) + action(this) + } + } + + @JvmOverloads + fun common(platforms: Iterable, action: CommonSettings.() -> Unit = {}) { + common { + clear() + add(platforms) + action(this) + } + } + fun common(action: Action) { - val settings = CommonSettings().also { action.execute(it) } + val settings = CommonSettings().also { + it.loaders += ModLoader.FABRIC + it.loaders += ModLoader.FORGE + action.execute(it) + } + if (injectInjectables) { var plsAddInjectables = false project.configurations.findByName("architecturyTransformerClasspath") @@ -296,28 +344,30 @@ open class ArchitectPluginExtension(val project: Project) { } } - addTasks() - if (settings.forgeEnabled) { - project.configurations.create("transformProductionForge") - } - project.configurations.create("transformProductionFabric") - val buildTask = project.tasks.getByName("build") val jarTask = project.tasks.getByName("jar") { it as AbstractArchiveTask it.archiveClassifier.set("dev") } as AbstractArchiveTask - val transformProductionFabricTask = project.tasks.getByName("transformProductionFabric") { - it as TransformingTask + for (loader in settings.loaders) { + project.configurations.maybeCreate("transformProduction${loader.titledId}") + val transformProductionTask = + project.tasks.register("transformProduction${loader.titledId}", TransformingTask::class.java) { + it.group = "Architectury" + it.platform = loader.id + loader.transformProduction(it, loom) - it.archiveClassifier.set("transformProductionFabric") - it.input.set(jarTask.archiveFile) + it.archiveClassifier.set("transformProduction${loader.titledId}") + it.input.set(jarTask.archiveFile) - project.artifacts.add("transformProductionFabric", it) - it.dependsOn(jarTask) - buildTask.dependsOn(it) - } as TransformingTask + project.artifacts.add("transformProduction${loader.titledId}", it) + it.dependsOn(jarTask) + buildTask.dependsOn(it) + } + + transformProductionTask.get().archiveFile.get().asFile.takeUnless { it.exists() }?.createEmptyJar() + } val remapJarTask = project.tasks.getByName("remapJar") { it as Jar @@ -342,66 +392,6 @@ open class ArchitectPluginExtension(val project: Project) { } }) } as Jar - - if (settings.forgeEnabled) { - val transformProductionForgeTask = project.tasks.getByName("transformProductionForge") { - it as TransformingTask - - it.input.set(jarTask.archiveFile) - it.archiveClassifier.set("transformProductionForge") - - project.artifacts.add("transformProductionForge", it) - it.dependsOn(jarTask) - buildTask.dependsOn(it) - } as TransformingTask - - transformProductionForgeTask.archiveFile.get().asFile.takeUnless { it.exists() }?.createEmptyJar() - - loom.generateSrgTiny = true - } - - 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() - } } } @@ -413,44 +403,9 @@ private fun File.createEmptyJar() { data class Transform( val project: Project, val configName: String, - val transformers: MutableList> = mutableListOf() + val transformers: MutableList> = mutableListOf(), + var envAnnotationProvider: String = "net.fabricmc:fabric-loader:+" ) { - fun setupFabricTransforms() { - this += RuntimeMixinRefmapDetector::class.java - this += GenerateFakeFabricMod::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 - 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 - this += TransformForgeEnvironment::class.java - this += GenerateFakeForgeMod::class.java - this += FixForgeMixin::class.java - } - operator fun plusAssign(transformer: TransformerPair) { transformers.add(Function { transformer }) } @@ -475,14 +430,18 @@ data class Transform( } fun add(transformer: Class, config: MutableMap.(file: Path) -> Unit) { - add(transformer, BiConsumer { file, map -> + add(transformer, BiConsumer> { file, map -> config(map, file) }) } } +fun projectGeneratedPackage(project: Project, file: Path): String = + (project.projectUniqueIdentifier() + "_" + file.toString() + .toByteArray(StandardCharsets.UTF_8).sha256 + file.fileName).legalizePackageName() + fun String.legalizePackageName(): String = filter { Character.isJavaIdentifierPart(it) } -private val ByteArray.sha256: String +internal val ByteArray.sha256: String get() = Hashing.sha256().hashBytes(this).toString() diff --git a/src/main/kotlin/dev/architectury/plugin/ModLoader.kt b/src/main/kotlin/dev/architectury/plugin/ModLoader.kt new file mode 100644 index 0000000..3fe7bec --- /dev/null +++ b/src/main/kotlin/dev/architectury/plugin/ModLoader.kt @@ -0,0 +1,111 @@ +package dev.architectury.plugin + +import dev.architectury.plugin.loom.LoomInterface +import dev.architectury.plugin.transformers.AddRefmapName +import dev.architectury.transformer.transformers.* + +class ModLoader( + val id: String, + val transformDevelopment: Transform.() -> Unit, + val transformProduction: TransformingTask.(loom: LoomInterface) -> Unit, +) { + init { + LOADERS[id] = this + } + + val titledId = id.capitalize() + + companion object { + fun valueOf(id: String): ModLoader = + LOADERS[id] ?: throw IllegalArgumentException("No modloader with id $id") + + val LOADERS = LinkedHashMap() + val FABRIC = ModLoader( + id = "fabric", + transformDevelopment = { + this += RuntimeMixinRefmapDetector::class.java + this += GenerateFakeFabricMod::class.java + add(TransformExpectPlatform::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + add(RemapInjectables::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + this += TransformPlatformOnly::class.java + }, + transformProduction = { + this += RemapMixinVariables() + add(TransformExpectPlatform()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + add(RemapInjectables()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + this += AddRefmapName() + this += TransformPlatformOnly() + } + ) + + val FORGE = ModLoader( + id = "forge", + transformDevelopment = { + this += RuntimeMixinRefmapDetector::class.java + add(TransformExpectPlatform::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + add(RemapInjectables::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + this += TransformPlatformOnly::class.java + + this += TransformForgeAnnotations::class.java + this += TransformForgeEnvironment::class.java + this += GenerateFakeForgeMod::class.java + this += FixForgeMixin::class.java + }, + transformProduction = { loom -> + add(TransformExpectPlatform()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + add(RemapInjectables()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + this += AddRefmapName() + this += TransformPlatformOnly() + + this += TransformForgeAnnotations() + this += TransformForgeEnvironment() + this += FixForgeMixin() + + loom.generateSrgTiny = true + } + ) + + val QUILT = ModLoader( + id = "quilt", + transformDevelopment = { + this += RuntimeMixinRefmapDetector::class.java + this += GenerateFakeQuiltMod::class.java + add(TransformExpectPlatform::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + add(RemapInjectables::class.java) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + this += TransformPlatformOnly::class.java + envAnnotationProvider = "org.quiltmc:quilt-loader:+" + }, + transformProduction = { + this += RemapMixinVariables() + add(TransformExpectPlatform()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + add(RemapInjectables()) { file -> + this[BuiltinProperties.UNIQUE_IDENTIFIER] = projectGeneratedPackage(project, file) + } + this += AddRefmapName() + this += TransformPlatformOnly() + } + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt b/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt index 499ae5f..8415762 100644 --- a/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt +++ b/src/main/kotlin/dev/architectury/plugin/TransformingTask.kt @@ -6,7 +6,6 @@ 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 diff --git a/src/main/kotlin/dev/architectury/plugin/loom/LoomInterface.kt b/src/main/kotlin/dev/architectury/plugin/loom/LoomInterface.kt index d1a0d7c..e2d2dd4 100644 --- a/src/main/kotlin/dev/architectury/plugin/loom/LoomInterface.kt +++ b/src/main/kotlin/dev/architectury/plugin/loom/LoomInterface.kt @@ -1,5 +1,6 @@ package dev.architectury.plugin.loom +import org.gradle.api.Project import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider import org.gradle.jvm.tasks.Jar @@ -7,6 +8,39 @@ import java.io.File import java.nio.file.Path interface LoomInterface { + companion object { + fun get(project: Project): LoomInterface { + fun use(interfaceName: String): LoomInterface { + return Class.forName(interfaceName) + .getDeclaredConstructor(Project::class.java) + .newInstance(project) as LoomInterface + } + + fun useIfFound(className: String, interfaceName: String): LoomInterface? { + return try { + Class.forName(className) + use(interfaceName) + } catch (ignored: ClassNotFoundException) { + null + } + } + + return useIfFound( + "net.fabricmc.loom.util.service.SharedServiceManager", + "dev.architectury.plugin.loom.LoomInterface011" // 0.11.0 + ) ?: useIfFound( + "net.fabricmc.loom.util.ZipUtils", + "dev.architectury.plugin.loom.LoomInterface010" // >0.10.0.188 + ) ?: useIfFound( + "net.fabricmc.loom.api.MixinExtensionAPI", + "dev.architectury.plugin.loom.LoomInterface010Legacy" // 0.10.0 + ) ?: useIfFound( + "net.fabricmc.loom.api.LoomGradleExtensionAPI", + "dev.architectury.plugin.loom.LoomInterface09" // 0.9.0 + ) ?: use("dev.architectury.plugin.loom.LoomInterface06") // 0.6.0 + } + } + val allMixinMappings: Collection val tinyMappingsWithSrg: Path val refmapName: String @@ -28,7 +62,7 @@ interface LoomInterface { interface LoomRunConfig { var mainClass: String - + fun addVmArg(vmArg: String) } } \ No newline at end of file