From de665ab4989bceb4ff323ebc0851ef781a0ef5de Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Thu, 20 May 2021 23:47:48 +0100 Subject: [PATCH 01/56] Add SignedProjectTest #404 --- .../test/integration/SignedProjectTest.groovy | 96 +++++++++++++++++++ .../loom/test/util/ProjectTestTrait.groovy | 2 +- .../resources/projects/signed/build.gradle | 57 +++++++++++ .../java/net/fabricmc/example/ExampleLib.java | 13 +++ .../signed/main/resources/fabric.mod.json | 4 + .../resources/projects/signed/settings.gradle | 2 + 6 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy create mode 100644 src/test/resources/projects/signed/build.gradle create mode 100644 src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java create mode 100644 src/test/resources/projects/signed/main/resources/fabric.mod.json create mode 100644 src/test/resources/projects/signed/settings.gradle diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy new file mode 100644 index 00000000..3570b220 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy @@ -0,0 +1,96 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.integration + +import net.fabricmc.loom.test.util.ArchiveAssertionsTrait + +import net.fabricmc.loom.test.util.MockMavenServerTrait +import spock.lang.Specification +import spock.lang.Stepwise +import spock.lang.Unroll +import spock.util.environment.RestoreSystemProperties + +import static java.lang.System.setProperty +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +/** + * This tests publishing signed artifacts to a maven server + */ +@Stepwise +class SignedProjectTest extends Specification implements MockMavenServerTrait, ArchiveAssertionsTrait { + @Unroll + @RestoreSystemProperties + def "sign and publish lib #gradle"() { + given: + setProperty('loom.test.secretKey', PRIVATE_KEY) + when: + def result = create("publish", gradle) + then: + result.task(":publish").outcome == SUCCESS + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } + + @Override + String name() { + "signed" + } + + static final String PRIVATE_KEY = """ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQPGBGCm5LMBCADUeHXbe4TmP3qELtz6he7CLaVMFXqL/fU+M7GIrj0qtLU6pJ9v +KSbF3tQATKlU91zkQCIPg41VBlqkx85bOm0u7Nvv4JhWMqE+ZsNoNVXS2xQEyEIW +rX9Cd0/YibU2FpWOlo1l/UZPPD/lYUrkZEhgoKHMHP3SYb5Ohgpy4klTeQdXTRMF +q0IeyFynw3eqrdWmktOEApd7qeu/Hs1NEnZssSZQdAYB4R+tL/ePgIYXsViWvqbT +XDYfmd+AiRnACGtrt5P8tSmKhLPzth36cvqLXI+hSBGHu0PRfvQnfjn3CWq8AaIj +dLsmRYw8NedYZ5DgY3NIRMBkG561Uc1Kj5c7ABEBAAH+BwMCfh5aZV7x7zP/HCCP +WwbuNO9fLKss4J7sNVWdkX/ZsOy5OMLBql70F8PKEovObkYiAWsPUjrQ50VMhCUc +V2443FErPTC9A+5NsJ3Sx+BazbsUd9cprnJIW0tVGP4ij9j14A0VOogJUbzrxonQ +aCQ4OMJi5cxk/o2z/N5WDG92Qb/CxNlp6oxuUgdxXWdhWSpW6XBlBKfMsjK6acpo +gAQg+e8m0FCRrpd+vMoHFPYa0UdY8s2YH88te7YiQYYPf9FI3Uk8FeKRCqgRIwTr +fWd7Ubh2vK0h3ua3gyJm1aqQbIYVk/a2L1KF6tsuh1AYGbyXitx6cujSOukwz3xi +ej4CutY60PoIFihSiBBsRwpvcGr9RoYkJ8tKBqq67xTttYhdlBiedM4/05gdCglw +UXm7O1LVOro6vaI6RzP1hL5Q/OLkx4mxXtaNbsjP1/Urml7bB1aqzeoMXUSlSqB+ +LHavKxonYcEj2cRKRg1v/t2UV0lXyimammJ5c4Hq49bLygYITrT9pL3n9OOmAYBL +/+uv7h640cYWeR8YBQ7jCbdaqP+bJNmIbKlLMZfcS49Bt/WM1kFa6CqvAyNFewuL +CnRbMcdteYGWYvSyvmzKDa7tQ6TILt9ZrJOGPTGrEM2zLIR8H6eDpzXSVwJb/0Nk +apaCzB9GqMDtYpEu+nMg1/EI2oSzj0Ng0pV+rAJr6oLc6Y0iesVKbwg2VgYgzF7U +CG9B15hPofUDKXb43Fig4nWieceDzGveY8vlFeSMBxzxhCRsXKP9oWogtNRJiJ9c +t+VkzBADEb82mnG/QuTBgCxceRBVu4Bg9tPGRSHjBZurtdkKvJqEq5ay/lGZ718b +3Za/hMzR6rakVfKdGs7A2HN68iCkX3cZYn+uaKT8aEUSXoSFZXfJqU3pVi2ql2MN +43RseA0og79mtCFsb29tLXRlc3QgPGxvb20tdGVzdEBleGFtcGxlLmNvbT6JAU4E +EwEKADgWIQSP20iY86Edwz6Qcq0M9Z/0ipBcJgUCYKbkswIbLwULCQgHAgYVCgkI +CwIEFgIDAQIeAQIXgAAKCRAM9Z/0ipBcJruCCADNydlXQRAr799Fr58zf9YGBcH5 +7F3TQpzK2zd6iktFy9cjIu04pYtvdrEP+29hLmy1ibUBI3yx8HH1BxHm8Eu2ZTAn +b5EYkmF73CecdtSu3yL0tmk/4GLO6t2r/SN7imFnq9xKyTqJmtftQngBhgoA6KPk +4ZEkOA1MbVpaSjGy5H1U/XusH1UDA3SZWlOwrY3xO8TfycsR9BijtCqxTnuwNXzT +wWoDPJEzJM/KCs0aXRbwwWALcxqk6sevLwx4D4/k3xxEB8cf5cBJC8bJjnBz5FSi +WBVyzTF8wLkcSacL93kE6swpP+iNkIwkO4eoyTA2RmTJUcz/M0zWS7NEM8S0 +=xl+8 +-----END PGP PRIVATE KEY BLOCK-----""" +} \ No newline at end of file diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 56ed8c9c..fdb70c97 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.1-20210511220046+0000" + final static String PRE_RELEASE_GRADLE = "7.1-20210520220048+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() diff --git a/src/test/resources/projects/signed/build.gradle b/src/test/resources/projects/signed/build.gradle new file mode 100644 index 00000000..5da48236 --- /dev/null +++ b/src/test/resources/projects/signed/build.gradle @@ -0,0 +1,57 @@ +plugins { + id 'fabric-loom' + id 'maven-publish' + id 'signing' +} + +archivesBaseName = "fabric-example-lib" +version = "1.0.0" +group = "com.example" + +dependencies { + minecraft "com.mojang:minecraft:1.16.5" + mappings "net.fabricmc:yarn:1.16.5+build.5:v2" + modImplementation "net.fabricmc:fabric-loader:0.11.2" +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +java { + withSourcesJar() +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifact(remapJar) { + builtBy remapJar + } + artifact(remapJar) { + builtBy remapJar + classifier "classifier" + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + repositories { + maven { + url "http://localhost:${System.getProperty("loom.test.mavenPort")}/" + allowInsecureProtocol = true + } + } +} + +signing { + def privateKey = System.getProperty("loom.test.secretKey") ?: "no key!" + useInMemoryPgpKeys(privateKey, 'password') + sign publishing.publications.mavenJava +} diff --git a/src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java b/src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java new file mode 100644 index 00000000..e6ec1e65 --- /dev/null +++ b/src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java @@ -0,0 +1,13 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleLib implements ModInitializer { + @Override + public void onInitialize() { + } + + public static void hello() { + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/signed/main/resources/fabric.mod.json b/src/test/resources/projects/signed/main/resources/fabric.mod.json new file mode 100644 index 00000000..f527100e --- /dev/null +++ b/src/test/resources/projects/signed/main/resources/fabric.mod.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "id": "modid" +} diff --git a/src/test/resources/projects/signed/settings.gradle b/src/test/resources/projects/signed/settings.gradle new file mode 100644 index 00000000..fc4c0f72 --- /dev/null +++ b/src/test/resources/projects/signed/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "fabric-example-lib" + From e955ebb8c56378b166adbd440f237999a346099e Mon Sep 17 00:00:00 2001 From: LogicFan <38597904+LogicFan@users.noreply.github.com> Date: Sat, 22 May 2021 18:28:42 -0400 Subject: [PATCH 02/56] add support for new dependencyResolutionManagement (#400) * move repo declartions - Move repository declartions in MavenConfiguration.java to LoomRepositoryPlugin.java * move repo declartions - Move repository declartions in MinecraftMappedProvider.java to LoomRepositoryPlugin.java * move repo declartions - Move repository declarations in MinecraftProcessedProvider.java to LoomRepositoryPlugin.java * do not add repositories if dependencyResolutionManagement is used * Simplify the change on LoomGradlePlugin - this is the suggestion from liach * change name to follow fabric naming convension - change getProjectUUID to getProjectUuid - change PROJECT_MAPPED_CLASSIFIER to projectMappedClassifier * remove MavenConfiguration.java - the file currently do nothing. * clean-up for all `instanceof` clause * add DependencyResolutionManagementTest * code cleanup * Update src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener * change project uuid to project full name Co-authored-by: modmuss50 --- .../net/fabricmc/loom/LoomGradlePlugin.java | 11 +- .../fabricmc/loom/LoomRepositoryPlugin.java | 200 ++++++++++++++++++ .../configuration/CompileConfiguration.java | 2 - .../configuration/LoomDependencyManager.java | 5 +- .../MinecraftProcessedProvider.java | 12 +- .../minecraft/MinecraftMappedProvider.java | 2 - .../dependencyResolutionManagement.groovy} | 49 ++--- .../basic/build.gradle | 92 ++++++++ .../basic/gradle.properties | 17 ++ .../java/net/fabricmc/example/ExampleMod.java | 14 ++ .../fabricmc/example/mixin/ExampleMixin.java | 15 ++ .../src/main/resources/assets/modid/icon.png | Bin 0 -> 453 bytes .../basic/src/main/resources/fabric.mod.json | 37 ++++ .../src/main/resources/modid.mixins.json | 14 ++ .../projmap/build.gradle | 96 +++++++++ .../projmap/gradle.properties | 17 ++ .../java/net/fabricmc/example/ExampleMod.java | 14 ++ .../fabricmc/example/mixin/ExampleMixin.java | 15 ++ .../src/main/resources/assets/modid/icon.png | Bin 0 -> 453 bytes .../src/main/resources/fabric.mod.json | 38 ++++ .../src/main/resources/modid.accesswidener | 2 + .../src/main/resources/modid.mixins.json | 14 ++ .../settings.gradle | 16 ++ 23 files changed, 643 insertions(+), 39 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java rename src/{main/java/net/fabricmc/loom/configuration/MavenConfiguration.java => test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy} (57%) create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/assets/modid/icon.png create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json create mode 100644 src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/assets/modid/icon.png create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener create mode 100644 src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json create mode 100644 src/test/resources/projects/dependencyResolutionManagement/settings.gradle diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 0a84bdfd..938def6b 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -31,6 +31,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.plugins.PluginAware; import net.fabricmc.loom.configuration.CompileConfiguration; import net.fabricmc.loom.configuration.FabricApiExtension; @@ -40,12 +41,20 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingsCache; import net.fabricmc.loom.decompilers.DecompilerConfiguration; import net.fabricmc.loom.task.LoomTasks; -public class LoomGradlePlugin implements Plugin { +public class LoomGradlePlugin implements Plugin { public static boolean refreshDeps; public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); @Override + public void apply(PluginAware target) { + target.getPlugins().apply(LoomRepositoryPlugin.class); + + if (target instanceof Project project) { + apply(project); + } + } + public void apply(Project project) { project.getLogger().lifecycle("Fabric Loom: " + LoomGradlePlugin.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java new file mode 100644 index 00000000..5d77c0da --- /dev/null +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -0,0 +1,200 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom; + +import java.io.File; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.dsl.RepositoryHandler; +import org.gradle.api.artifacts.repositories.IvyArtifactRepository; +import org.gradle.api.initialization.Settings; +import org.gradle.api.invocation.Gradle; +import org.gradle.api.plugins.PluginAware; + +public class LoomRepositoryPlugin implements Plugin { + @Override + public void apply(PluginAware target) { + RepositoryHandler repositories = null; + + if (target instanceof Settings settings) { + repositories = settings.getDependencyResolutionManagement().getRepositories(); + + // leave a marker so projects don't try to override these + settings.getGradle().getPluginManager().apply(LoomRepositoryPlugin.class); + } else if (target instanceof Project project) { + if (project.getGradle().getPlugins().hasPlugin(LoomRepositoryPlugin.class)) { + return; + } + + repositories = project.getRepositories(); + } else if (target instanceof Gradle) { + return; + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + Cache cache = new Cache(target); + + // MavenConfiguration.java + repositories.flatDir(repo -> { + repo.setName("UserLocalCacheFiles"); + repo.dir(cache.getRootBuildCache()); + }); + repositories.maven(repo -> { + repo.setName("UserLocalRemappedMods"); + repo.setUrl(cache.getRemappedModCache()); + }); + repositories.maven(repo -> { + repo.setName("Fabric"); + repo.setUrl("https://maven.fabricmc.net/"); + }); + repositories.maven(repo -> { + repo.setName("Mojang"); + repo.setUrl("https://libraries.minecraft.net/"); + }); + repositories.mavenCentral(); + + // MinecraftMappedProvider.java + repositories.ivy(repo -> { + repo.setUrl(cache.getUserCache()); + repo.patternLayout(layout -> { + layout.artifact("[revision]/[artifact]-[revision](.[ext])"); + }); + repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + }); + + // MinecraftProcessedProvider.java + repositories.ivy(repo -> { + repo.setUrl(cache.getRootPersistentCache()); + repo.patternLayout(layout -> { + layout.artifact("[revision]/[artifact]-[revision](.[ext])"); + }); + repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + }); + } +} + +final class Cache { + private PluginAware target; + + Cache(PluginAware target) { + if (target instanceof Project || target instanceof Settings) { + this.target = target; + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + } + + File getUserCache() { + File gradleUserHomeDir = null; + + if (target instanceof Settings settings) { + gradleUserHomeDir = settings.getGradle().getGradleUserHomeDir(); + } else if (target instanceof Project project) { + gradleUserHomeDir = project.getGradle().getGradleUserHomeDir(); + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + File userCache = new File(gradleUserHomeDir, "caches" + File.separator + "fabric-loom"); + + if (!userCache.exists()) { + userCache.mkdirs(); + } + + return userCache; + } + + public File getRootPersistentCache() { + File rootDir = null; + + if (target instanceof Settings settings) { + rootDir = settings.getRootDir(); + } else if (target instanceof Project project) { + rootDir = project.getRootDir(); + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + File persistentCache = new File(rootDir, ".gradle" + File.separator + "loom-cache"); + + if (!persistentCache.exists()) { + persistentCache.mkdirs(); + } + + return persistentCache; + } + + public File getRootBuildCache() { + File rootDir = null; + + if (target instanceof Settings settings) { + rootDir = settings.getRootDir(); + } else if (target instanceof Project project) { + rootDir = project.getRootDir(); + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + File buildCache = new File(rootDir, "build" + File.separator + "loom-cache"); + + if (!buildCache.exists()) { + buildCache.mkdirs(); + } + + return buildCache; + } + + public File getRemappedModCache() { + File remappedModCache = new File(getRootPersistentCache(), "remapped_mods"); + + if (!remappedModCache.exists()) { + remappedModCache.mkdir(); + } + + return remappedModCache; + } + + public File getNestedModCache() { + File nestedModCache = new File(getRootPersistentCache(), "nested_mods"); + + if (!nestedModCache.exists()) { + nestedModCache.mkdir(); + } + + return nestedModCache; + } + + public File getNativesJarStore() { + File natives = new File(getUserCache(), "natives/jars"); + + if (!natives.exists()) { + natives.mkdirs(); + } + + return natives; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 343353a1..8e75df82 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -107,8 +107,6 @@ public final class CompileConfiguration { p.afterEvaluate(project -> { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - MavenConfiguration.setup(project); - LoomDependencyManager dependencyManager = new LoomDependencyManager(); extension.setDependencyManager(dependencyManager); diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index 397908c5..55c544cf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -45,6 +45,7 @@ import net.fabricmc.loom.configuration.mods.ModProcessor; import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.SourceRemapper; +import net.fabricmc.loom.LoomRepositoryPlugin; public class LoomDependencyManager { private static class ProviderList { @@ -193,7 +194,9 @@ public class LoomDependencyManager { project.getLogger().debug("Loom adding " + name + " from installer JSON"); - if (jsonElement.getAsJsonObject().has("url")) { + // If user choose to use dependencyResolutionManagement, then they should declare + // these repositories manually in the settings file. + if (jsonElement.getAsJsonObject().has("url") && !project.getGradle().getPlugins().hasPlugin(LoomRepositoryPlugin.class)) { String url = jsonElement.getAsJsonObject().get("url").getAsString(); long count = project.getRepositories().stream().filter(artifactRepository -> artifactRepository instanceof MavenArtifactRepository) .map(artifactRepository -> (MavenArtifactRepository) artifactRepository) diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java index adf85fd2..0a24a75f 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java @@ -37,7 +37,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvid import net.fabricmc.loom.util.Constants; public class MinecraftProcessedProvider extends MinecraftMappedProvider { - public static final String PROJECT_MAPPED_CLASSIFIER = "projectmapped"; + public final String projectMappedClassifier; private File projectMappedJar; @@ -46,6 +46,8 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { public MinecraftProcessedProvider(Project project, JarProcessorManager jarProcessorManager) { super(project); this.jarProcessorManager = jarProcessorManager; + this.projectMappedClassifier = "project-" + project.getPath().replace(':', '@') + + "-mapped"; } @Override @@ -63,14 +65,12 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { jarProcessorManager.process(projectMappedJar); } - getProject().getRepositories().flatDir(repository -> repository.dir(getJarDirectory(getExtension().getProjectPersistentCache(), PROJECT_MAPPED_CLASSIFIER))); - getProject().getDependencies().add(Constants.Configurations.MINECRAFT_NAMED, - getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString(PROJECT_MAPPED_CLASSIFIER))); + getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString(projectMappedClassifier))); } private void invalidateJars() { - File dir = getJarDirectory(getExtension().getUserCache(), PROJECT_MAPPED_CLASSIFIER); + File dir = getJarDirectory(getExtension().getUserCache(), projectMappedClassifier); if (dir.exists()) { getProject().getLogger().warn("Invalidating project jars"); @@ -87,7 +87,7 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { public void initFiles(MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) { super.initFiles(minecraftProvider, mappingsProvider); - projectMappedJar = new File(getJarDirectory(getExtension().getProjectPersistentCache(), PROJECT_MAPPED_CLASSIFIER), "minecraft-" + getJarVersionString(PROJECT_MAPPED_CLASSIFIER) + ".jar"); + projectMappedJar = new File(getJarDirectory(getExtension().getRootProjectPersistentCache(), projectMappedClassifier), "minecraft-" + getJarVersionString(projectMappedClassifier) + ".jar"); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java index 0032a177..a2718090 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java @@ -144,8 +144,6 @@ public class MinecraftMappedProvider extends DependencyProvider { } protected void addDependencies(DependencyInfo dependency, Consumer postPopulationScheduler) { - getProject().getRepositories().flatDir(repository -> repository.dir(getJarDirectory(getExtension().getUserCache(), "mapped"))); - getProject().getDependencies().add(Constants.Configurations.MINECRAFT_NAMED, getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString("mapped"))); } diff --git a/src/main/java/net/fabricmc/loom/configuration/MavenConfiguration.java b/src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy similarity index 57% rename from src/main/java/net/fabricmc/loom/configuration/MavenConfiguration.java rename to src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy index 2fb2ae7c..a8b27336 100644 --- a/src/main/java/net/fabricmc/loom/configuration/MavenConfiguration.java +++ b/src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy @@ -22,36 +22,31 @@ * SOFTWARE. */ -package net.fabricmc.loom.configuration; +package net.fabricmc.loom.test.integration -import org.gradle.api.Project; +import net.fabricmc.loom.test.util.ProjectTestTrait +import spock.lang.Specification +import spock.lang.Unroll -import net.fabricmc.loom.LoomGradleExtension; +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS -public class MavenConfiguration { - public static void setup(Project project) { - LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); +class DependencyResolutionManagementTest extends Specification implements ProjectTestTrait { + @Override + String name() { + "dependencyResolutionManagement" + } - project.getRepositories().flatDir(repo -> { - repo.setName("UserLocalCacheFiles"); - repo.dir(extension.getRootProjectBuildCache()); - }); + @Unroll + def "build (gradle #gradle)"() { + when: + def result = create("build", gradle) + then: + result.task(":basic:build").outcome == SUCCESS + result.task(":projmap:build").outcome == SUCCESS - project.getRepositories().maven(repo -> { - repo.setName("UserLocalRemappedMods"); - repo.setUrl(extension.getRemappedModCache()); - }); - - project.getRepositories().maven(repo -> { - repo.setName("Fabric"); - repo.setUrl("https://maven.fabricmc.net/"); - }); - - project.getRepositories().maven(repo -> { - repo.setName("Mojang"); - repo.setUrl("https://libraries.minecraft.net/"); - }); - - project.getRepositories().mavenCentral(); - } + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } } diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle b/src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle new file mode 100644 index 00000000..f02447c7 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle @@ -0,0 +1,92 @@ +plugins { + id 'fabric-loom' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too + // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used. + // We'll use that if it's available, but otherwise we'll use the older option. + def targetVersion = 8 + if (JavaVersion.current().isJava9Compatible()) { + it.options.release = targetVersion + } +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties b/src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties new file mode 100644 index 00000000..40e9e571 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties + # check these on https://fabricmc.net/use + minecraft_version=1.16.5 + yarn_mappings=1.16.5+build.6 + loader_version=0.11.3 + +# Mod Properties + mod_version = 1.0.0 + maven_group = com.example + archives_base_name = fabric-example-mod + +# Dependencies + # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api + fabric_version=0.32.5+1.16 diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java new file mode 100644 index 00000000..e5ed082e --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java @@ -0,0 +1,14 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java new file mode 100644 index 00000000..83ee1a89 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/assets/modid/icon.png b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/assets/modid/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..047b91f2347de5cf95f23284476fddbe21ba23fe GIT binary patch literal 453 zcmV;$0XqJPP)QAFYGys`80vegN0XDFh0OXKz&i8?Le#x7{1X)R+00000NkvXXu0mjf73i~T literal 0 HcmV?d00001 diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..df92d8b1 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.16.x" + }, + "suggests": { + "another-mod": "*" + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json new file mode 100644 index 00000000..21fe73a4 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle b/src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle new file mode 100644 index 00000000..ca8c73f6 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle @@ -0,0 +1,96 @@ +plugins { + id 'fabric-loom' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too + // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used. + // We'll use that if it's available, but otherwise we'll use the older option. + def targetVersion = 8 + if (JavaVersion.current().isJava9Compatible()) { + it.options.release = targetVersion + } +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +minecraft { + accessWidener = file("src/main/resources/modid.accesswidener") +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties b/src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties new file mode 100644 index 00000000..40e9e571 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties + # check these on https://fabricmc.net/use + minecraft_version=1.16.5 + yarn_mappings=1.16.5+build.6 + loader_version=0.11.3 + +# Mod Properties + mod_version = 1.0.0 + maven_group = com.example + archives_base_name = fabric-example-mod + +# Dependencies + # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api + fabric_version=0.32.5+1.16 diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java new file mode 100644 index 00000000..e5ed082e --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java @@ -0,0 +1,14 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java new file mode 100644 index 00000000..83ee1a89 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/assets/modid/icon.png b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/assets/modid/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..047b91f2347de5cf95f23284476fddbe21ba23fe GIT binary patch literal 453 zcmV;$0XqJPP)QAFYGys`80vegN0XDFh0OXKz&i8?Le#x7{1X)R+00000NkvXXu0mjf73i~T literal 0 HcmV?d00001 diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..4764df8c --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.16.x" + }, + "suggests": { + "another-mod": "*" + }, + "accessWidener" : "modid.accesswidener" +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener new file mode 100644 index 00000000..9684ec8f --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener @@ -0,0 +1,2 @@ +accessWidener v1 named +extendable class net/minecraft/fluid/FluidState diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json new file mode 100644 index 00000000..21fe73a4 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/settings.gradle b/src/test/resources/projects/dependencyResolutionManagement/settings.gradle new file mode 100644 index 00000000..c05e3699 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/settings.gradle @@ -0,0 +1,16 @@ +pluginManagement { + plugins { + id 'fabric-loom' + } +} + +plugins { + id 'fabric-loom' +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) +} + +include 'basic' +include 'projmap' \ No newline at end of file From 1f80e00e8851765c5aff961e8213ec40e468ed41 Mon Sep 17 00:00:00 2001 From: Mitchell Skaggs Date: Sat, 22 May 2021 17:29:02 -0500 Subject: [PATCH 03/56] Add classifier to "fake" mods' id if they have a classifier specified (#394) * Remove unused codepath (`RemapJarTask` is an `AbstractArchiveTask`) * Remove incorrect comment Comment originally added in 02e9616622abed6b266ced329b86d419ac31ee88 * Add classifier to `DependencyInfo` * Add classifier to generated mod ID * Clean up code structure from review Co-authored-by: haykam821 * Inline `file` local variable Co-authored-by: haykam821 Co-authored-by: haykam821 --- .../nesting/NestedDependencyProvider.java | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java b/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java index 8de3103e..60640cb6 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java @@ -32,7 +32,8 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; -import java.util.stream.Collectors; + +import javax.annotation.Nullable; import com.google.gson.JsonObject; import org.apache.commons.io.FileUtils; @@ -42,7 +43,6 @@ import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.DependencySet; import org.gradle.api.artifacts.ProjectDependency; -import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.ResolvedConfiguration; import org.gradle.api.artifacts.ResolvedDependency; import org.gradle.api.tasks.bundling.AbstractArchiveTask; @@ -103,17 +103,17 @@ public final class NestedDependencyProvider implements NestedJarProvider { visited.add(dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion()); - // TODO change this to allow just normal jar tasks, so a project can have a none loom sub project Collection remapJarTasks = dependencyProject.getTasksByName("remapJar", false); Collection jarTasks = dependencyProject.getTasksByName("jar", false); for (Task task : remapJarTasks.isEmpty() ? jarTasks : remapJarTasks) { - if (task instanceof RemapJarTask remapJarTask) { - File file = remapJarTask.getArchiveFile().get().getAsFile(); - fileList.add(new DependencyInfo<>(projectDependency, new ProjectDependencyMetaExtractor(), file)); - } else if (task instanceof AbstractArchiveTask abstractArchiveTask) { - File file = abstractArchiveTask.getArchiveFile().get().getAsFile(); - fileList.add(new DependencyInfo<>(projectDependency, new ProjectDependencyMetaExtractor(), file)); + if (task instanceof AbstractArchiveTask abstractArchiveTask) { + fileList.add(new DependencyInfo<>( + projectDependency, + new ProjectDependencyMetaExtractor(), + abstractArchiveTask.getArchiveFile().get().getAsFile(), + abstractArchiveTask.getArchiveClassifier().getOrNull() + )); } } } @@ -133,14 +133,13 @@ public final class NestedDependencyProvider implements NestedJarProvider { continue; } - List files = dependency - .getModuleArtifacts() - .stream() - .map(ResolvedArtifact::getFile) - .collect(Collectors.toList()); - - for (File file : files) { - fileList.add(new DependencyInfo<>(dependency, new ResolvedDependencyMetaExtractor(), file)); + for (var artifact : dependency.getModuleArtifacts()) { + fileList.add(new DependencyInfo<>( + dependency, + new ResolvedDependencyMetaExtractor(), + artifact.getFile(), + artifact.getClassifier() + )); } } @@ -195,7 +194,12 @@ public final class NestedDependencyProvider implements NestedJarProvider { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("schemaVersion", 1); - jsonObject.addProperty("id", (metaExtractor.group(dependency) + "_" + metaExtractor.name(dependency)).replaceAll("\\.", "_").toLowerCase(Locale.ENGLISH)); + + jsonObject.addProperty("id", + (metaExtractor.group(dependency) + "_" + metaExtractor.name(dependency) + info.getClassifierSuffix()) + .replaceAll("\\.", "_") + .toLowerCase(Locale.ENGLISH) + ); jsonObject.addProperty("version", metaExtractor.version(dependency)); jsonObject.addProperty("name", metaExtractor.name(dependency)); @@ -206,8 +210,8 @@ public final class NestedDependencyProvider implements NestedJarProvider { return LoomGradlePlugin.GSON.toJson(jsonObject); } - private record DependencyInfo(D dependency, DependencyMetaExtractor metaExtractor, File file) { - public void validateInputs() { + private record DependencyInfo(D dependency, DependencyMetaExtractor metaExtractor, File file, @Nullable String classifier) { + void validateInputs() { if (!file.exists()) { throw new RuntimeException("Failed to include nested jars, as it could not be found @ " + file.getAbsolutePath()); } @@ -216,6 +220,14 @@ public final class NestedDependencyProvider implements NestedJarProvider { throw new RuntimeException("Failed to include nested jars, as file was not a jar: " + file.getAbsolutePath()); } } + + String getClassifierSuffix() { + if (classifier == null) { + return ""; + } else { + return "_" + classifier; + } + } } private interface DependencyMetaExtractor { From 8238db17784baf843833f680e750d31083ec8acd Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 26 May 2021 11:41:52 +0100 Subject: [PATCH 04/56] Improve error messages when using outdated Java or Gradle. --- .github/workflows/test-push.yml | 52 +++++++++++++- .gitignore | 3 +- bootstrap/.gitignore | 7 ++ bootstrap/build.gradle | 30 +++++++++ .../loom/bootstrap/BootstrappedPlugin.java | 7 ++ .../bootstrap/LoomGradlePluginBootstrap.java | 67 +++++++++++++++++++ ...ick-gradle-into-thinking-loom-is-signed.SF | 4 ++ bootstrap/test-project/build.gradle | 8 +++ bootstrap/test-project/settings.gradle | 10 +++ build.gradle | 31 ++++++++- settings.gradle | 1 + .../net/fabricmc/loom/LoomGradlePlugin.java | 4 +- 12 files changed, 218 insertions(+), 6 deletions(-) create mode 100644 bootstrap/.gitignore create mode 100644 bootstrap/build.gradle create mode 100644 bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java create mode 100644 bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java create mode 100644 bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF create mode 100644 bootstrap/test-project/build.gradle create mode 100644 bootstrap/test-project/settings.gradle diff --git a/.github/workflows/test-push.yml b/.github/workflows/test-push.yml index 960e82d5..a7be5e6e 100644 --- a/.github/workflows/test-push.yml +++ b/.github/workflows/test-push.yml @@ -89,4 +89,54 @@ jobs: if: ${{ failure() }} with: name: Reproducible Build ${{ matrix.os }} (${{ matrix.java }}) Results - path: build/reports/ \ No newline at end of file + path: build/reports/ + + bootstrap_tests: + needs: build + + strategy: + fail-fast: false + matrix: + java: [ 8, 11, 15, 16 ] + gradle: [ 4.9, 5.2, 6.0.1, 6.9, 7.0.2 ] + exclude: + - java: 16 + gradle: 6.9 + - java: 16 + gradle: 6.0.1 + - java: 16 + gradle: 5.2 + - java: 16 + gradle: 4.9 + - java: 15 + gradle: 6.0.1 + - java: 15 + gradle: 5.2 + - java: 15 + gradle: 4.9 + runs-on: ubuntu-20.04 + container: + image: gradle:7.0.2-jdk16 + options: --user root + + steps: + # Build loom and publish to maven local + - uses: actions/checkout@v2 + - run: gradle build publishToMavenLocal -x test -x check + + - run: gradle wrapper --gradle-version=${{ matrix.gradle }} + working-directory: bootstrap/test-project + - run: gradle --stop + + - uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java }} + distribution: 'adopt' + + - run: ./gradlew --version + working-directory: bootstrap/test-project + - run: ./gradlew build + working-directory: bootstrap/test-project + continue-on-error: true + + # TODO check the output of the previous step here \ No newline at end of file diff --git a/.gitignore b/.gitignore index c316a770..4354f60f 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ !/settings.gradle !/Jenkinsfile !/checkstyle.xml -!/codenarc.groovy \ No newline at end of file +!/codenarc.groovy +!/bootstrap \ No newline at end of file diff --git a/bootstrap/.gitignore b/bootstrap/.gitignore new file mode 100644 index 00000000..f8dc37c9 --- /dev/null +++ b/bootstrap/.gitignore @@ -0,0 +1,7 @@ +# Ignore everything +/* + +!/src +!/build.gradle +!/.gitignore +!/test-project \ No newline at end of file diff --git a/bootstrap/build.gradle b/bootstrap/build.gradle new file mode 100644 index 00000000..7db4d755 --- /dev/null +++ b/bootstrap/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'java' + id 'groovy' +} + +sourceCompatibility = 8 +targetCompatibility = 8 + +tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + it.options.release = 8 +} + +repositories { + mavenCentral() +} + +dependencies { + implementation gradleApi() + + testImplementation(gradleTestKit()) + testImplementation('org.spockframework:spock-core:2.0-M5-groovy-3.0') { + exclude module: 'groovy-all' + } +} + +test { + maxHeapSize = "4096m" + useJUnitPlatform() +} \ No newline at end of file diff --git a/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java new file mode 100644 index 00000000..c64246ef --- /dev/null +++ b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java @@ -0,0 +1,7 @@ +package net.fabricmc.loom.bootstrap; + +import org.gradle.api.plugins.PluginAware; + +public interface BootstrappedPlugin { + void apply(PluginAware project); +} diff --git a/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java new file mode 100644 index 00000000..66408edf --- /dev/null +++ b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java @@ -0,0 +1,67 @@ +package net.fabricmc.loom.bootstrap; + +import java.util.ArrayList; +import java.util.List; + +import org.gradle.api.JavaVersion; +import org.gradle.api.Plugin; +import org.gradle.api.plugins.PluginAware; +import org.gradle.util.GradleVersion; + +/** + * This bootstrap is compiled against a minimal gradle API and java 8, this allows us to show a nice error to users who run on unsupported configurations. + */ +@SuppressWarnings("unused") +public class LoomGradlePluginBootstrap implements Plugin { + private static final int MIN_SUPPORTED_MAJOR_GRADLE_VERSION = 7; + private static final int MIN_SUPPORTED_MAJOR_JAVA_VERSION = 16; + + private static final String PLUGIN_CLASS_NAME = "net.fabricmc.loom.LoomGradlePlugin"; + + @Override + public void apply(PluginAware project) { + List errors = new ArrayList<>(); + + if (!isValidGradleRuntime()) { + errors.add(String.format("You are using an outdated version of Gradle (%s). Gradle %d or higher is required.", GradleVersion.current().getVersion(), MIN_SUPPORTED_MAJOR_GRADLE_VERSION)); + } + + if (!isValidJavaRuntime()) { + errors.add(String.format("You are using an outdated version of Java (%s). Java %d or higher is required.", JavaVersion.current().getMajorVersion(), MIN_SUPPORTED_MAJOR_JAVA_VERSION)); + + String javaHome = System.getenv("JAVA_HOME"); + + if (javaHome != null) { + errors.add(String.format("The JAVA_HOME environment variable is currently set to (%s).", javaHome)); + } + } + + if (!errors.isEmpty()) { + throw new UnsupportedOperationException(String.join("\n", errors)); + } + + getActivePlugin().apply(project); + } + + private static boolean isValidJavaRuntime() { + // Note use compareTo to ensure compatibility with gradle < 6.0 + return JavaVersion.current().compareTo(JavaVersion.toVersion(MIN_SUPPORTED_MAJOR_JAVA_VERSION)) >= 0; + } + + private static boolean isValidGradleRuntime() { + return getMajorGradleVersion() >= MIN_SUPPORTED_MAJOR_GRADLE_VERSION; + } + + private static int getMajorGradleVersion() { + String version = GradleVersion.current().getVersion(); + return Integer.parseInt(version.substring(0, version.indexOf("."))); + } + + BootstrappedPlugin getActivePlugin() { + try { + return (BootstrappedPlugin) Class.forName(PLUGIN_CLASS_NAME).getConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException("Failed to bootstrap loom", e); + } + } +} diff --git a/bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF b/bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF new file mode 100644 index 00000000..9a1b230b --- /dev/null +++ b/bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF @@ -0,0 +1,4 @@ +Trick gradle into thinking that loom is signed to skip over transforming all classes in the jar. +This is required to get the bootstrap to well bootstrap on older gradle versions that dont support java 16. + +See https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/java/org/gradle/internal/classpath/InstrumentingClasspathFileTransformer.java#L129 \ No newline at end of file diff --git a/bootstrap/test-project/build.gradle b/bootstrap/test-project/build.gradle new file mode 100644 index 00000000..2cb6e85a --- /dev/null +++ b/bootstrap/test-project/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'fabric-loom' version '0.8.local' +} + +dependencies { + minecraft "com.mojang:minecraft:1.16.5" + mappings loom.officialMojangMappings() +} \ No newline at end of file diff --git a/bootstrap/test-project/settings.gradle b/bootstrap/test-project/settings.gradle new file mode 100644 index 00000000..37a1b9e0 --- /dev/null +++ b/bootstrap/test-project/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + mavenLocal() + } +} diff --git a/build.gradle b/build.gradle index 9d5f41f2..bc6fe297 100644 --- a/build.gradle +++ b/build.gradle @@ -39,9 +39,19 @@ repositories { mavenCentral() } +configurations { + bootstrap { + transitive false + } + compileClasspath.extendsFrom bootstrap + runtimeClasspath.extendsFrom bootstrap +} + dependencies { implementation gradleApi() + bootstrap project(":bootstrap") + // libraries implementation ('commons-io:commons-io:2.8.0') implementation ('org.zeroturnaround:zt-zip:1.14') @@ -71,7 +81,7 @@ dependencies { implementation ('org.cadixdev:lorenz-io-proguard:0.5.6') // decompilers - implementation ('net.fabricmc:fabric-fernflower:1.4.0') + implementation ('net.fabricmc:fabric-fernflower:1.4.1') implementation ('org.benf:cfr:0.151') // source code remapping @@ -94,6 +104,8 @@ jar { manifest { attributes 'Implementation-Version': project.version } + + from configurations.bootstrap.collect { it.isDirectory() ? it : zipTree(it) } } task sourcesJar(type: Jar, dependsOn: classes) { @@ -128,7 +140,7 @@ gradlePlugin { plugins { fabricLoom { id = 'fabric-loom' - implementationClass = 'net.fabricmc.loom.LoomGradlePlugin' + implementationClass = 'net.fabricmc.loom.bootstrap.LoomGradlePluginBootstrap' } } } @@ -215,6 +227,21 @@ publishing { } } +// Need to tweak this file to pretend we are compatible with j8 so the bootstrap will run. +tasks.withType(GenerateModuleMetadata) { + doLast { + def file = outputFile.get().asFile + + def metadata = new groovy.json.JsonSlurper().parseText(file.text) + + metadata.variants.each { + it.attributes["org.gradle.jvm.version"] = 8 + } + + file.text = groovy.json.JsonOutput.toJson(metadata) + } +} + // A task to output a json file with a list of all the test to run task writeActionsTestMatrix() { doLast { diff --git a/settings.gradle b/settings.gradle index ae239c6c..885070a6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = name +include "bootstrap" \ No newline at end of file diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 938def6b..3d32c4bc 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -29,10 +29,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.plugins.PluginAware; +import net.fabricmc.loom.bootstrap.BootstrappedPlugin; import net.fabricmc.loom.configuration.CompileConfiguration; import net.fabricmc.loom.configuration.FabricApiExtension; import net.fabricmc.loom.configuration.MavenPublication; @@ -41,7 +41,7 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingsCache; import net.fabricmc.loom.decompilers.DecompilerConfiguration; import net.fabricmc.loom.task.LoomTasks; -public class LoomGradlePlugin implements Plugin { +public class LoomGradlePlugin implements BootstrappedPlugin { public static boolean refreshDeps; public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); From 640e1b47215a15480ca0d21da4bf9508c5488ef9 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 26 May 2021 21:10:08 +0100 Subject: [PATCH 05/56] Improve the outdated Java error message when syncing in idea. --- .../loom/bootstrap/LoomGradlePluginBootstrap.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java index 66408edf..54762934 100644 --- a/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java +++ b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java @@ -29,10 +29,15 @@ public class LoomGradlePluginBootstrap implements Plugin { if (!isValidJavaRuntime()) { errors.add(String.format("You are using an outdated version of Java (%s). Java %d or higher is required.", JavaVersion.current().getMajorVersion(), MIN_SUPPORTED_MAJOR_JAVA_VERSION)); - String javaHome = System.getenv("JAVA_HOME"); + if (Boolean.getBoolean("idea.active")) { + // Idea specific error + errors.add("You can change the Java version in the Gradle settings dialog."); + } else { + String javaHome = System.getenv("JAVA_HOME"); - if (javaHome != null) { - errors.add(String.format("The JAVA_HOME environment variable is currently set to (%s).", javaHome)); + if (javaHome != null) { + errors.add(String.format("The JAVA_HOME environment variable is currently set to (%s).", javaHome)); + } } } From 3318a15cc5b9504fa165c96a41e6618e01620417 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Thu, 27 May 2021 22:08:56 +0100 Subject: [PATCH 06/56] Suppress "Inconsistent inner class entries" error when decompiling --- .../fernflower/AbstractFernFlowerDecompiler.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java index 43e9c9d7..449d37d7 100644 --- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java +++ b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java @@ -105,7 +105,14 @@ public abstract class AbstractFernFlowerDecompiler implements LoomDecompiler { spec.getMainClass().set(fernFlowerExecutor().getName()); spec.jvmArgs("-Xms200m", "-Xmx3G"); spec.setArgs(args); - spec.setErrorOutput(System.err); + spec.setErrorOutput(new ConsumingOutputStream(line -> { + if (line.startsWith("Inconsistent inner class entries")) { + // Suppress this + return; + } + + System.err.println(line); + })); spec.setStandardOutput(new ConsumingOutputStream(line -> { if (line.startsWith("Listening for transport") || !line.contains("::")) { System.out.println(line); From 210938d749179b8f3cbbd8cae346bf531f6aac60 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Fri, 28 May 2021 11:31:19 +0100 Subject: [PATCH 07/56] Fix local ivy layout not respecting classifiers. Fixes #407 --- build.gradle | 4 ++++ gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java | 4 ++-- .../net/fabricmc/loom/test/util/ProjectTestTrait.groovy | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index bc6fe297..ff50ae2b 100644 --- a/build.gradle +++ b/build.gradle @@ -266,4 +266,8 @@ task writeActionsTestMatrix() { output.parentFile.mkdir() output.text = json } +} + +tasks.named('wrapper') { + distributionType = Wrapper.DistributionType.ALL } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e5338d37..d435ce29 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java index 5d77c0da..5ea09a12 100644 --- a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -81,7 +81,7 @@ public class LoomRepositoryPlugin implements Plugin { repositories.ivy(repo -> { repo.setUrl(cache.getUserCache()); repo.patternLayout(layout -> { - layout.artifact("[revision]/[artifact]-[revision](.[ext])"); + layout.artifact("[revision]/[artifact]-[revision](-[classifier])(.[ext])"); }); repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); }); @@ -90,7 +90,7 @@ public class LoomRepositoryPlugin implements Plugin { repositories.ivy(repo -> { repo.setUrl(cache.getRootPersistentCache()); repo.patternLayout(layout -> { - layout.artifact("[revision]/[artifact]-[revision](.[ext])"); + layout.artifact("[revision]/[artifact]-[revision](-[classifier])(.[ext])"); }); repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); }); diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index fdb70c97..2d0640a2 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.1-20210520220048+0000" + final static String PRE_RELEASE_GRADLE = "7.2-20210527220045+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() From 6bdfabc228128d9daeab524655b0150aa2bba5c1 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 30 May 2021 19:57:35 +0800 Subject: [PATCH 08/56] Update tiny-remapper to 1.1.0 Signed-off-by: shedaniel --- build.gradle | 2 +- src/main/java/net/fabricmc/loom/build/JarRemapper.java | 1 + .../java/net/fabricmc/loom/configuration/mods/ModProcessor.java | 1 + .../configuration/providers/forge/MinecraftPatchedProvider.java | 1 + .../providers/minecraft/MinecraftMappedProvider.java | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7e8f8eca..3ba3075d 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,7 @@ dependencies { } // tinyfile management - implementation ('dev.architectury:tiny-remapper:1.0.0') + implementation ('dev.architectury:tiny-remapper:1.1.0') implementation ('dev.architectury:mappings-layers-core:1.1.6') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') diff --git a/src/main/java/net/fabricmc/loom/build/JarRemapper.java b/src/main/java/net/fabricmc/loom/build/JarRemapper.java index 116fb135..67088057 100644 --- a/src/main/java/net/fabricmc/loom/build/JarRemapper.java +++ b/src/main/java/net/fabricmc/loom/build/JarRemapper.java @@ -70,6 +70,7 @@ public class JarRemapper { LoggerFilter.replaceSystemOut(); TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper(); remapperBuilder.logger(project.getLogger()::lifecycle); + remapperBuilder.logUnknownInvokeDynamic(false); mappingProviders.forEach(remapperBuilder::withMappings); if (remapOptions != null) { diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index b0629d69..160d467b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -157,6 +157,7 @@ public class ModProcessor { LoggerFilter.replaceSystemOut(); TinyRemapper remapper = TinyRemapper.newRemapper() .logger(project.getLogger()::lifecycle) + .logUnknownInvokeDynamic(false) .withMappings(TinyRemapperMappingsHelper.create(mappings, fromM, toM, false)) .renameInvalidLocals(false) .build(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index 5440854f..cd95c283 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -445,6 +445,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { TinyRemapper remapper = TinyRemapper.newRemapper() .logger(getProject().getLogger()::lifecycle) + .logUnknownInvokeDynamic(false) .withMappings(TinyRemapperMappingsHelper.create(mappingsWithSrg, "srg", "official", true)) .withMappings(InnerClassRemapper.of(input, mappingsWithSrg, "srg", "official")) .renameInvalidLocals(true) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java index fbc9ea86..707c9db6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java @@ -253,6 +253,7 @@ public class MinecraftMappedProvider extends DependencyProvider { public TinyRemapper getTinyRemapper() throws IOException { TinyRemapper.Builder builder = TinyRemapper.newRemapper() .renameInvalidLocals(true) + .logUnknownInvokeDynamic(false) .ignoreConflicts(getExtension().isForge()) .cacheMappings(true) .threads(Runtime.getRuntime().availableProcessors()) From a2ae80239d1bc0d5dc5eb9ee35205fbdc10af03a Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 30 May 2021 20:46:50 +0800 Subject: [PATCH 09/56] Disable module files, we can't have those, they point to the wrong files Signed-off-by: shedaniel --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 3ba3075d..fa862d82 100644 --- a/build.gradle +++ b/build.gradle @@ -345,3 +345,7 @@ task writeActionsTestMatrix() { tasks.named('wrapper') { distributionType = Wrapper.DistributionType.ALL } + +tasks.withType(GenerateModuleMetadata) { + enabled = false +} From b4b2e986d12c63dd3d0c9e12a8ee33b3f3cebeef Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 30 May 2021 20:47:03 +0800 Subject: [PATCH 10/56] Reinitiate the forge repo Signed-off-by: shedaniel --- .../java/net/fabricmc/loom/LoomRepositoryPlugin.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java index 5ea09a12..3dc6c44f 100644 --- a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -75,6 +75,15 @@ public class LoomRepositoryPlugin implements Plugin { repo.setName("Mojang"); repo.setUrl("https://libraries.minecraft.net/"); }); + repositories.maven(repo -> { + repo.setName("Forge"); + repo.setUrl("https://maven.minecraftforge.net/"); + + repo.metadataSources(sources -> { + sources.mavenPom(); + sources.ignoreGradleMetadataRedirection(); + }); + }); repositories.mavenCentral(); // MinecraftMappedProvider.java From 188bbe57d6f0ebe2f9ead02f2f5f60a70bc5e559 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Tue, 1 Jun 2021 18:13:25 +0100 Subject: [PATCH 11/56] Fix MergedNestedJarProvider not calling the child's prepare --- .../nesting/MergedNestedJarProvider.java | 11 +++- .../build/nesting/NestedJarPathProvider.java | 2 + .../unit/MergedNestedJarProviderTest.groovy | 55 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/MergedNestedJarProviderTest.groovy diff --git a/src/main/java/net/fabricmc/loom/build/nesting/MergedNestedJarProvider.java b/src/main/java/net/fabricmc/loom/build/nesting/MergedNestedJarProvider.java index 1b93b44f..61b05eb6 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/MergedNestedJarProvider.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/MergedNestedJarProvider.java @@ -29,12 +29,19 @@ import java.util.Arrays; import java.util.Collection; import java.util.stream.Collectors; -public record MergedNestedJarProvider(NestedJarProvider... parents) implements NestedJarProvider { +import org.gradle.api.Project; + +public record MergedNestedJarProvider(NestedJarProvider... children) implements NestedJarProvider { @Override public Collection provide() { - return Arrays.stream(parents) + return Arrays.stream(children) .map(NestedJarProvider::provide) .flatMap(Collection::stream) .collect(Collectors.toList()); } + + @Override + public void prepare(Project project) { + Arrays.stream(children).forEach(nestedJarProvider -> nestedJarProvider.prepare(project)); + } } diff --git a/src/main/java/net/fabricmc/loom/build/nesting/NestedJarPathProvider.java b/src/main/java/net/fabricmc/loom/build/nesting/NestedJarPathProvider.java index badb2656..184617ff 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/NestedJarPathProvider.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/NestedJarPathProvider.java @@ -58,6 +58,8 @@ public final class NestedJarPathProvider implements NestedJarProvider { } private void validateFiles() { + Preconditions.checkNotNull(files, "null files to nest, was prepare called?"); + for (File file : files) { Preconditions.checkArgument(file.getName().endsWith(".jar"), String.format("Tried to nest %s but it is not a jar", file.getAbsolutePath())); Preconditions.checkArgument(file.exists(), String.format("Tried to nest jar %s but it does not exist", file.getAbsolutePath())); diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/MergedNestedJarProviderTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/MergedNestedJarProviderTest.groovy new file mode 100644 index 00000000..a31d9ccd --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/MergedNestedJarProviderTest.groovy @@ -0,0 +1,55 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit + +import net.fabricmc.loom.build.nesting.MergedNestedJarProvider +import net.fabricmc.loom.build.nesting.NestedJarProvider +import org.gradle.api.Project +import spock.lang.Specification + +class MergedNestedJarProviderTest extends Specification { + def "empty test"() { + given: + def nestedJarProvider = new MergedNestedJarProvider(new TestNestedJarProvider()) + when: + nestedJarProvider.prepare(null) + then: + nestedJarProvider.provide() != null + } + + private class TestNestedJarProvider implements NestedJarProvider { + private Collection files = null + + @Override + Collection provide() { + return files + } + + @Override + void prepare(Project project) { + files = [] + } + } +} From 50d6fd298d7ac450dea1b8475c43e73255e674b5 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 2 Jun 2021 09:06:26 +0100 Subject: [PATCH 12/56] Update mercury (#408) --- build.gradle | 2 +- .../net/fabricmc/loom/test/util/ProjectTestTrait.groovy | 2 +- src/test/resources/projects/java16/build.gradle | 1 + src/test/resources/projects/java16/gradle.properties | 7 ++++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index ff50ae2b..81a11c7c 100644 --- a/build.gradle +++ b/build.gradle @@ -85,7 +85,7 @@ dependencies { implementation ('org.benf:cfr:0.151') // source code remapping - implementation ('org.cadixdev:mercury:0.1.0-rc1') + implementation ('net.fabricmc:mercury:0.2.0') // Kapt integration compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0') diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 2d0640a2..88cea9a9 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.2-20210527220045+0000" + final static String PRE_RELEASE_GRADLE = "7.2-20210531220051+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() diff --git a/src/test/resources/projects/java16/build.gradle b/src/test/resources/projects/java16/build.gradle index b97f5240..dbf1f7e6 100644 --- a/src/test/resources/projects/java16/build.gradle +++ b/src/test/resources/projects/java16/build.gradle @@ -15,6 +15,7 @@ dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" } tasks.withType(JavaCompile).configureEach { diff --git a/src/test/resources/projects/java16/gradle.properties b/src/test/resources/projects/java16/gradle.properties index 0d8b3c77..24ef9a92 100644 --- a/src/test/resources/projects/java16/gradle.properties +++ b/src/test/resources/projects/java16/gradle.properties @@ -1,8 +1,9 @@ org.gradle.jvmargs=-Xmx1G -minecraft_version=21w19a -yarn_mappings=21w19a+build.1 -loader_version=0.11.2 +minecraft_version=1.17-pre3 +yarn_mappings=1.17-pre3+build.1 +loader_version=0.11.3 +fabric_version=0.34.8+1.17 mod_version = 1.0.0 maven_group = com.example From 4763760984c3ed604151f1c2f59b14487ebfd884 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 2 Jun 2021 23:05:51 +0100 Subject: [PATCH 13/56] Revert "Update mercury (#408)" This reverts commit 50d6fd298d7ac450dea1b8475c43e73255e674b5. --- build.gradle | 2 +- .../net/fabricmc/loom/test/util/ProjectTestTrait.groovy | 2 +- src/test/resources/projects/java16/build.gradle | 1 - src/test/resources/projects/java16/gradle.properties | 7 +++---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 81a11c7c..ff50ae2b 100644 --- a/build.gradle +++ b/build.gradle @@ -85,7 +85,7 @@ dependencies { implementation ('org.benf:cfr:0.151') // source code remapping - implementation ('net.fabricmc:mercury:0.2.0') + implementation ('org.cadixdev:mercury:0.1.0-rc1') // Kapt integration compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0') diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 88cea9a9..2d0640a2 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.2-20210531220051+0000" + final static String PRE_RELEASE_GRADLE = "7.2-20210527220045+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() diff --git a/src/test/resources/projects/java16/build.gradle b/src/test/resources/projects/java16/build.gradle index dbf1f7e6..b97f5240 100644 --- a/src/test/resources/projects/java16/build.gradle +++ b/src/test/resources/projects/java16/build.gradle @@ -15,7 +15,6 @@ dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" } tasks.withType(JavaCompile).configureEach { diff --git a/src/test/resources/projects/java16/gradle.properties b/src/test/resources/projects/java16/gradle.properties index 24ef9a92..0d8b3c77 100644 --- a/src/test/resources/projects/java16/gradle.properties +++ b/src/test/resources/projects/java16/gradle.properties @@ -1,9 +1,8 @@ org.gradle.jvmargs=-Xmx1G -minecraft_version=1.17-pre3 -yarn_mappings=1.17-pre3+build.1 -loader_version=0.11.3 -fabric_version=0.34.8+1.17 +minecraft_version=21w19a +yarn_mappings=21w19a+build.1 +loader_version=0.11.2 mod_version = 1.0.0 maven_group = com.example From 1212e56d9ccf6e6025cba3b5bbd8175e45c1ac27 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 5 Jun 2021 01:55:26 +0800 Subject: [PATCH 14/56] Detect tsrg2 Signed-off-by: shedaniel --- build.gradle | 4 +- .../net/fabricmc/loom/util/srg/MCPReader.java | 77 +++++++++++-------- .../net/fabricmc/loom/util/srg/SrgMerger.java | 51 ++++++++++-- 3 files changed, 92 insertions(+), 40 deletions(-) diff --git a/build.gradle b/build.gradle index fa862d82..dff5e013 100644 --- a/build.gradle +++ b/build.gradle @@ -91,7 +91,7 @@ dependencies { // tinyfile management implementation ('dev.architectury:tiny-remapper:1.1.0') - implementation ('dev.architectury:mappings-layers-core:1.1.6') + implementation ('dev.architectury:mappings-layers-core:1.2.7') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' @@ -116,7 +116,7 @@ dependencies { implementation ('net.minecraftforge:binarypatcher:1.1.1') implementation ('org.cadixdev:lorenz:0.5.3') implementation ('org.cadixdev:lorenz-asm:0.5.3') - implementation ('net.minecraftforge:accesstransformers:2.2.0') + implementation ('net.minecraftforge:accesstransformers:3.0.1') implementation ('de.oceanlabs.mcp:mcinjector:3.8.0') implementation ('com.opencsv:opencsv:5.4') diff --git a/src/main/java/net/fabricmc/loom/util/srg/MCPReader.java b/src/main/java/net/fabricmc/loom/util/srg/MCPReader.java index bdb22d73..e0b4ed5b 100644 --- a/src/main/java/net/fabricmc/loom/util/srg/MCPReader.java +++ b/src/main/java/net/fabricmc/loom/util/srg/MCPReader.java @@ -24,7 +24,9 @@ package net.fabricmc.loom.util.srg; +import java.io.BufferedReader; import java.io.IOException; +import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; @@ -35,12 +37,17 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.opencsv.CSVReader; import com.opencsv.exceptions.CsvValidationException; +import dev.architectury.mappingslayers.api.mutable.MutableClassDef; +import dev.architectury.mappingslayers.api.mutable.MutableFieldDef; +import dev.architectury.mappingslayers.api.mutable.MutableMethodDef; +import dev.architectury.mappingslayers.api.mutable.MutableTinyTree; +import dev.architectury.mappingslayers.api.utils.MappingsUtils; +import org.apache.commons.io.IOUtils; import org.cadixdev.lorenz.MappingSet; import org.cadixdev.lorenz.io.srg.tsrg.TSrgReader; import org.cadixdev.lorenz.model.ClassMapping; @@ -180,17 +187,43 @@ public class MCPReader { private Map readSrg() throws IOException { Map tokens = new HashMap<>(); - try (TSrgReader reader = new TSrgReader(Files.newBufferedReader(srgTsrgPath, StandardCharsets.UTF_8))) { - MappingSet mappingSet = reader.read(); + try (BufferedReader reader = Files.newBufferedReader(srgTsrgPath, StandardCharsets.UTF_8)) { + String content = IOUtils.toString(reader); - for (TopLevelClassMapping classMapping : mappingSet.getTopLevelClassMappings()) { - appendClass(tokens, classMapping); + if (content.startsWith("tsrg2")) { + readTsrg2(tokens, content); + } else { + MappingSet mappingSet = new TSrgReader(new StringReader(content)).read(); + + for (TopLevelClassMapping classMapping : mappingSet.getTopLevelClassMappings()) { + appendClass(tokens, classMapping); + } } } return tokens; } + private void readTsrg2(Map tokens, String content) { + MutableTinyTree tree = MappingsUtils.deserializeFromTsrg2(content); + int obfIndex = tree.getMetadata().index("obf"); + int srgIndex = tree.getMetadata().index("srg"); + + for (MutableClassDef classDef : tree.getClassesMutable()) { + MemberToken ofClass = MemberToken.ofClass(classDef.getName(obfIndex)); + tokens.put(ofClass, classDef.getName(srgIndex)); + + for (MutableFieldDef fieldDef : classDef.getFieldsMutable()) { + tokens.put(MemberToken.ofField(ofClass, fieldDef.getName(obfIndex)), fieldDef.getName(srgIndex)); + } + + for (MutableMethodDef methodDef : classDef.getMethodsMutable()) { + tokens.put(MemberToken.ofMethod(ofClass, methodDef.getName(obfIndex), methodDef.getDescriptor(obfIndex)), + methodDef.getName(srgIndex)); + } + } + } + private void injectMcp(Path mcpJar, Map intermediaryToSrgMap, Map intermediaryToDocsMap, Map> intermediaryToParamsMap) throws IOException, CsvValidationException { Map> srgToIntermediary = inverseMap(intermediaryToSrgMap); @@ -304,21 +337,12 @@ public class MCPReader { } } - private static class MemberToken { - private final TokenType type; - @Nullable - private final MemberToken owner; - private final String name; - @Nullable - private final String descriptor; - - MemberToken(TokenType type, @Nullable MemberToken owner, String name, @Nullable String descriptor) { - this.type = type; - this.owner = owner; - this.name = name; - this.descriptor = descriptor; - } - + private record MemberToken( + TokenType type, + @Nullable MCPReader.MemberToken owner, + String name, + @Nullable String descriptor + ) { static MemberToken ofClass(String name) { return new MemberToken(TokenType.CLASS, null, name, null); } @@ -330,19 +354,6 @@ public class MCPReader { static MemberToken ofMethod(MemberToken owner, String name, String descriptor) { return new MemberToken(TokenType.METHOD, owner, name, descriptor); } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - MemberToken that = (MemberToken) o; - return type == that.type && name.equals(that.name) && Objects.equals(descriptor, that.descriptor) && Objects.equals(owner, that.owner); - } - - @Override - public int hashCode() { - return Objects.hash(type, name, descriptor, owner); - } } private enum TokenType { diff --git a/src/main/java/net/fabricmc/loom/util/srg/SrgMerger.java b/src/main/java/net/fabricmc/loom/util/srg/SrgMerger.java index 9f9fbe7d..cfaa34f7 100644 --- a/src/main/java/net/fabricmc/loom/util/srg/SrgMerger.java +++ b/src/main/java/net/fabricmc/loom/util/srg/SrgMerger.java @@ -26,6 +26,7 @@ package net.fabricmc.loom.util.srg; import java.io.BufferedReader; import java.io.IOException; +import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -34,6 +35,12 @@ import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; +import dev.architectury.mappingslayers.api.mutable.MutableClassDef; +import dev.architectury.mappingslayers.api.mutable.MutableFieldDef; +import dev.architectury.mappingslayers.api.mutable.MutableMethodDef; +import dev.architectury.mappingslayers.api.mutable.MutableTinyTree; +import dev.architectury.mappingslayers.api.utils.MappingsUtils; +import org.apache.commons.io.IOUtils; import org.cadixdev.lorenz.MappingSet; import org.cadixdev.lorenz.io.srg.tsrg.TSrgReader; import org.cadixdev.lorenz.model.ClassMapping; @@ -74,13 +81,9 @@ public final class SrgMerger { * or if an element mentioned in the SRG file does not have tiny mappings */ public static void mergeSrg(Path srg, Path tiny, Path out, boolean lenient) throws IOException, MappingException { - MappingSet arr; + MappingSet arr = readSrg(srg); TinyTree foss; - try (TSrgReader reader = new TSrgReader(Files.newBufferedReader(srg))) { - arr = reader.read(); - } - try (BufferedReader reader = Files.newBufferedReader(tiny)) { foss = TinyMappingFactory.loadWithDetection(reader); } @@ -104,6 +107,44 @@ public final class SrgMerger { TinyV2Writer.write(file, out); } + private static MappingSet readSrg(Path srg) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(srg)) { + String content = IOUtils.toString(reader); + + if (content.startsWith("tsrg2")) { + return readTsrg2(content); + } else { + try (TSrgReader srgReader = new TSrgReader(new StringReader(content))) { + return srgReader.read(); + } + } + } + } + + private static MappingSet readTsrg2(String content) { + MappingSet set = MappingSet.create(); + MutableTinyTree tree = MappingsUtils.deserializeFromTsrg2(content); + int obfIndex = tree.getMetadata().index("obf"); + int srgIndex = tree.getMetadata().index("srg"); + + for (MutableClassDef classDef : tree.getClassesMutable()) { + ClassMapping classMapping = set.getOrCreateClassMapping(classDef.getName(obfIndex)); + classMapping.setDeobfuscatedName(classDef.getName(srgIndex)); + + for (MutableFieldDef fieldDef : classDef.getFieldsMutable()) { + FieldMapping fieldMapping = classMapping.getOrCreateFieldMapping(fieldDef.getName(obfIndex)); + fieldMapping.setDeobfuscatedName(fieldDef.getName(srgIndex)); + } + + for (MutableMethodDef methodDef : classDef.getMethodsMutable()) { + MethodMapping methodMapping = classMapping.getOrCreateMethodMapping(methodDef.getName(obfIndex), methodDef.getDescriptor(obfIndex)); + methodMapping.setDeobfuscatedName(methodDef.getName(srgIndex)); + } + } + + return set; + } + private static void classToTiny(TinyTree foss, List namespaces, ClassMapping klass, Consumer classConsumer, boolean lenient) { String obf = klass.getFullObfuscatedName(); String srg = klass.getFullDeobfuscatedName(); From 29822d09116670ba41d3c0e3e54e95aedf703519 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 6 Jun 2021 23:49:16 +0800 Subject: [PATCH 15/56] Use a better structure for the mappings folder Signed-off-by: shedaniel --- build.gradle | 2 +- .../forge/FieldMigratedMappingsProvider.java | 2 +- .../providers/mappings/MappingsProvider.java | 56 +++++++++++++++---- .../mappings/MojangMappingsDependency.java | 14 +++-- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index fa862d82..a40b271c 100644 --- a/build.gradle +++ b/build.gradle @@ -91,7 +91,7 @@ dependencies { // tinyfile management implementation ('dev.architectury:tiny-remapper:1.1.0') - implementation ('dev.architectury:mappings-layers-core:1.1.6') + implementation ('dev.architectury:mappings-layers-core:1.2.7') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java index 4895e879..27f6fb6b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java @@ -105,7 +105,7 @@ public class FieldMigratedMappingsProvider extends MappingsProvider { @Override public void manipulateMappings(Path mappingsJar) throws IOException { LoomGradleExtension extension = getExtension(); - Path mappingsFolder = mappingsDir.resolve(extension.getMinecraftProvider().getMinecraftVersion() + "/forge-" + extension.getPatchProvider().forgeVersion); + Path mappingsFolder = getMappedVersionedDir(removeSuffix).resolve("forge/" + extension.getPatchProvider().forgeVersion); this.rawTinyMappings = tinyMappings.toPath(); this.rawTinyMappingsWithSrg = tinyMappingsWithSrg; String mappingsJarName = mappingsJar.getFileName().toString(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java index 0d929d79..7e5fe745 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java @@ -86,8 +86,10 @@ public class MappingsProvider extends DependencyProvider { public String mappingsName; public String minecraftVersion; public String mappingsVersion; + public String removeSuffix; protected final Path mappingsDir; + protected Path mappingsVersionedDir; private final Path mappingsStepsDir; private Path intermediaryTiny; private boolean hasRefreshed = false; @@ -111,6 +113,28 @@ public class MappingsProvider extends DependencyProvider { mappingsStepsDir = mappingsDir.resolve("steps"); } + public Path getMappingsVersionedDir() throws IOException { + if (mappingsVersionedDir == null) { + mappingsVersionedDir = mappingsDir.resolve(getExtension().getMinecraftProvider().getMinecraftVersion()); + + if (!Files.exists(mappingsVersionedDir)) { + Files.createDirectories(mappingsVersionedDir); + } + } + + return mappingsVersionedDir; + } + + public Path getMappedVersionedDir(String name) throws IOException { + Path dir = getMappingsVersionedDir().resolve(name); + + if (!Files.exists(dir)) { + Files.createDirectories(dir); + } + + return dir; + } + public void clean() throws IOException { FileUtils.deleteDirectory(mappingsDir.toFile()); } @@ -159,11 +183,12 @@ public class MappingsProvider extends DependencyProvider { } // We can save reading the zip file + header by checking the file name - isV2 = mappingsJar.getName().endsWith("-v2.jar"); + isV2 = mappingsJar.getName().endsWith("-v2.jar") || mappingsJar.getName().endsWith("-mergedv2.jar"); } else { isV2 = doesJarContainV2Mappings(mappingsJar.toPath()); } + removeSuffix = StringUtils.removeSuffix(mappingsJar.getName(), ".jar"); this.mappingsVersion = version + (isV2 ? "-v2" : ""); initFiles(); @@ -182,13 +207,13 @@ public class MappingsProvider extends DependencyProvider { jarClassifier = jarClassifier + depStringSplit[3]; } - String removeSuffix = StringUtils.removeSuffix(mappingsJar.getName(), ".jar"); - tinyMappings = mappingsDir.resolve(removeSuffix + ".tiny").toFile(); - unpickDefinitionsFile = mappingsDir.resolve(removeSuffix + ".unpick").toFile(); + Path mappedVersionedDir = getMappedVersionedDir(removeSuffix); + tinyMappings = mappedVersionedDir.resolve("mappings.tiny").toFile(); + unpickDefinitionsFile = mappedVersionedDir.resolve("definitions.unpick").toFile(); tinyMappingsJar = new File(getExtension().getUserCache(), removeSuffix + "-" + jarClassifier + ".jar"); - tinyMappingsWithSrg = mappingsDir.resolve(removeSuffix + "-srg.tiny"); - mixinTinyMappingsWithSrg = mappingsDir.resolve(removeSuffix + "-mixin-srg.tiny").toFile(); - srgToNamedSrg = mappingsDir.resolve(removeSuffix + "-srg-named.srg").toFile(); + tinyMappingsWithSrg = mappedVersionedDir.resolve("mappings-srg.tiny"); + mixinTinyMappingsWithSrg = mappedVersionedDir.resolve("mappings-mixin-srg.tiny").toFile(); + srgToNamedSrg = mappedVersionedDir.resolve("mappings-srg-named.srg").toFile(); if (!tinyMappings.exists() || isRefreshDeps()) { storeMappings(getProject(), minecraftProvider, mappingsJar.toPath(), postPopulationScheduler); @@ -463,8 +488,12 @@ public class MappingsProvider extends DependencyProvider { } } - private void initFiles() { - baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base"); + private void initFiles() throws IOException { + baseTinyMappings = getMappedVersionedDir(removeSuffix).resolve("mappings-base.tiny"); + + if (Files.exists(mappingsStepsDir)) { + Files.walkFileTree(mappingsStepsDir, new DeletingFileVisitor()); + } } public void cleanFiles() { @@ -505,13 +534,18 @@ public class MappingsProvider extends DependencyProvider { intermediaryTiny = mappingsDir.resolve(String.format("intermediary-%s-v2.tiny", minecraftVersion)); - if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) { + if (isRefreshDeps() && !hasRefreshed) { + Files.deleteIfExists(intermediaryTiny); + } + + if (!Files.exists(intermediaryTiny)) { hasRefreshed = true; + intermediaryTiny = getMappingsVersionedDir().resolve("intermediary-v2.tiny"); // Download and extract intermediary String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion); String intermediaryArtifactUrl = getExtension().getIntermediaryUrl().apply(encodedMinecraftVersion); - Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar"); + Path intermediaryJar = getMappingsVersionedDir().resolve("intermediary-v2.jar"); DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger()); extractIntermediary(intermediaryJar, intermediaryTiny); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java index 6e45d2b9..1d17dc1a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java @@ -28,6 +28,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.StringWriter; +import java.io.UncheckedIOException; import java.io.Writer; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -126,10 +127,15 @@ public class MojangMappingsDependency extends AbstractModuleDependency implement @Override public Set resolve() { - Path mappingsDir = extension.getMappingsProvider().getMappingsDir(); - Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion())); - Path clientMappings = mappingsDir.resolve(String.format("%s.%s-%s-client.map", GROUP, MODULE, getVersion())); - Path serverMappings = mappingsDir.resolve(String.format("%s.%s-%s-server.map", GROUP, MODULE, getVersion())); + Path mappingsDir; + try { + mappingsDir = extension.getMappingsProvider().getMappedVersionedDir(String.format("mojang/%s.%s-%s", GROUP, MODULE, getVersion())); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + Path mappingsFile = mappingsDir.resolve("mappings.tiny"); + Path clientMappings = mappingsDir.resolve("client.map"); + Path serverMappings = mappingsDir.resolve("server.map"); if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) { MappingSet mappingSet; From 449868451ef9b4ad84862f6543baf3b61165a424 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 10:50:17 +0100 Subject: [PATCH 16/56] Run tests on windows --- .github/workflows/test-push.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.github/workflows/test-push.yml b/.github/workflows/test-push.yml index a7be5e6e..9bed2ef7 100644 --- a/.github/workflows/test-push.yml +++ b/.github/workflows/test-push.yml @@ -66,6 +66,36 @@ jobs: name: ${{ matrix.test }} (${{ matrix.java }}) Results path: build/reports/ + run_tests_windows: + needs: prepare_test_matrix + + strategy: + fail-fast: false + matrix: + java: [16] + test: ${{ fromJson(needs.prepare_test_matrix.outputs.matrix) }} + exclude: + - java: 16 + test: net.fabricmc.loom.test.integration.KotlinTest + + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v2 + - name: setup jdk ${{ matrix.java }} + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - run: ./gradlew test --tests ${{ matrix.test }} --stacktrace + env: + TEST_WARNING_MODE: fail + + - uses: actions/upload-artifact@v2 + if: ${{ failure() }} + with: + name: ${{ matrix.test }} (${{ matrix.java }}) Results + path: build/reports/ + # Special case this test to run across all os's reproducible_build_test: needs: build From 90c55b66f7d7f13dc631d27130707688410203dd Mon Sep 17 00:00:00 2001 From: KosmX Date: Sun, 13 Jun 2021 12:13:46 +0200 Subject: [PATCH 17/56] Name mappings, so I can work with multiple Minecraft versions at the same time (#26) * Name mappings, so I can work with multiple Minecraft versions at the same time * Update MojangMappingsDependency.java * Update MojangMappingsDependency.java Co-authored-by: shedaniel --- .../providers/mappings/MojangMappingsDependency.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java index 1d17dc1a..18e8bcaf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java @@ -128,12 +128,14 @@ public class MojangMappingsDependency extends AbstractModuleDependency implement @Override public Set resolve() { Path mappingsDir; + try { mappingsDir = extension.getMappingsProvider().getMappedVersionedDir(String.format("mojang/%s.%s-%s", GROUP, MODULE, getVersion())); } catch (IOException e) { throw new UncheckedIOException(e); } - Path mappingsFile = mappingsDir.resolve("mappings.tiny"); + + Path mappingsFile = mappingsDir.resolve(String.format("mojmap-mappings-%s.jar", getVersion())); Path clientMappings = mappingsDir.resolve("client.map"); Path serverMappings = mappingsDir.resolve("server.map"); From 8d2e8c5948b7d863d467418d9e18b2371cca0e1b Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 11:18:10 +0100 Subject: [PATCH 18/56] Start 0.9 dev cycle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ff50ae2b..7fef1b0b 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ tasks.withType(JavaCompile).configureEach { group = 'net.fabricmc' archivesBaseName = project.name -def baseVersion = '0.8' +def baseVersion = '0.9' def ENV = System.getenv() if (ENV.BUILD_NUMBER) { From 0cfa88f73b7b6da200dc5bac3dde3884a854e17f Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 11:23:46 +0100 Subject: [PATCH 19/56] Always fork the java compiler --- .../fabricmc/loom/configuration/CompileConfiguration.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 8e75df82..fb35b975 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -30,6 +30,7 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.bundling.AbstractArchiveTask; +import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.api.tasks.javadoc.Javadoc; import net.fabricmc.loom.LoomGradleExtension; @@ -104,6 +105,11 @@ public final class CompileConfiguration { Javadoc javadoc = (Javadoc) p.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME); javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); + p.getTasks().withType(JavaCompile.class).configureEach(compile -> { + // Fork the java compiler to ensure that it does not keep any files open. + compile.getOptions().setFork(true); + }); + p.afterEvaluate(project -> { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); From 9278f6c4b928480799d00988c66989a76bdd7619 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 13:28:47 +0100 Subject: [PATCH 20/56] Fix new gradle 8.0 deprecation added in 7.2 (#416) * Fix new gradle 8.0 deprecation added in 7.2 * Handle bootstrap tests a bit better * Fix 0.9 wrapper tests --- .github/workflows/test-push.yml | 3 +-- bootstrap/test-project/build.gradle | 2 +- .../loom/configuration/RemapConfiguration.java | 10 +++++++++- .../fabricmc/loom/test/util/ProjectTestTrait.groovy | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-push.yml b/.github/workflows/test-push.yml index 9bed2ef7..ae5306a1 100644 --- a/.github/workflows/test-push.yml +++ b/.github/workflows/test-push.yml @@ -165,8 +165,7 @@ jobs: - run: ./gradlew --version working-directory: bootstrap/test-project - - run: ./gradlew build + - run: ./gradlew build || true working-directory: bootstrap/test-project - continue-on-error: true # TODO check the output of the previous step here \ No newline at end of file diff --git a/bootstrap/test-project/build.gradle b/bootstrap/test-project/build.gradle index 2cb6e85a..f2a0541d 100644 --- a/bootstrap/test-project/build.gradle +++ b/bootstrap/test-project/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.8.local' + id 'fabric-loom' version '0.9.local' } dependencies { diff --git a/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java index 7534c27b..3a19e70a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java @@ -27,6 +27,7 @@ package net.fabricmc.loom.configuration; import java.io.IOException; import com.google.common.base.Preconditions; +import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.UnknownTaskException; @@ -144,7 +145,14 @@ public class RemapConfiguration { remapSourcesJarTask.dependsOn(project.getTasks().getByName(sourcesJarTaskName)); if (isDefaultRemap) { - remapSourcesJarTask.doLast(task -> project.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); + // Do not use lambda here, see: https://github.com/gradle/gradle/pull/17087 + //noinspection Convert2Lambda + remapSourcesJarTask.doLast(new Action<>() { + @Override + public void execute(Task task) { + project.getArtifacts().add("archives", remapSourcesJarTask.getOutput()); + } + }); } if (extension.isShareCaches()) { diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 2d0640a2..0f72662d 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.2-20210527220045+0000" + final static String PRE_RELEASE_GRADLE = "7.2-20210612220215+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() From 60482833b27f43475105137419b1442bab373ffa Mon Sep 17 00:00:00 2001 From: haykam821 <24855774+haykam821@users.noreply.github.com> Date: Sun, 13 Jun 2021 09:34:46 -0400 Subject: [PATCH 21/56] Use tabs for indentation in the Fernflower decompiler (#383) Co-authored-by: modmuss50 --- .../decompilers/fernflower/AbstractFernFlowerDecompiler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java index 449d37d7..a166d575 100644 --- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java +++ b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java @@ -71,6 +71,7 @@ public abstract class AbstractFernFlowerDecompiler implements LoomDecompiler { put(IFernflowerPreferences.REMOVE_SYNTHETIC, "1"); put(IFernflowerPreferences.LOG_LEVEL, "trace"); put(IFernflowerPreferences.THREADS, metaData.numberOfThreads()); + put(IFernflowerPreferences.INDENT_STRING, "\t"); }}; List args = new ArrayList<>(); From 3d3628f0a1a2effe65f1a6048d0a115b51243cf0 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 17:49:18 +0100 Subject: [PATCH 22/56] Update tiny remapper. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7fef1b0b..edca4935 100644 --- a/build.gradle +++ b/build.gradle @@ -70,7 +70,7 @@ dependencies { } // tinyfile management - implementation ('net.fabricmc:tiny-remapper:0.3.2') + implementation ('net.fabricmc:tiny-remapper:0.4.0') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' From 3b30b035a49631bc88f0a0f6210b892b65ae8c1d Mon Sep 17 00:00:00 2001 From: KosmX Date: Sun, 13 Jun 2021 19:54:57 +0200 Subject: [PATCH 23/56] Avoid half-broken forge maven (#27) --- build.gradle | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a40b271c..08e6a318 100644 --- a/build.gradle +++ b/build.gradle @@ -52,9 +52,15 @@ sourceSets { repositories { mavenCentral() + maven { url "https://repo1.maven.org/maven2/"} maven { url "https://maven.fabricmc.net/" } maven { url "https://maven.architectury.dev/" } - maven { url "https://maven.minecraftforge.net/" } + maven { + url "https://maven.minecraftforge.net/" + content{ + excludeGroupByRegex "org.eclipse.*" + } + } } configurations { From 6d815fc4d8c69517ab571a8dc6281ed8009b3b03 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 14 Jun 2021 02:01:28 +0800 Subject: [PATCH 24/56] Remove redundant repo Signed-off-by: shedaniel --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 08e6a318..e0a60edc 100644 --- a/build.gradle +++ b/build.gradle @@ -52,7 +52,6 @@ sourceSets { repositories { mavenCentral() - maven { url "https://repo1.maven.org/maven2/"} maven { url "https://maven.fabricmc.net/" } maven { url "https://maven.architectury.dev/" } maven { From 1ea5dbb1e8ea5d41852feeea28b713f5acb5654d Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 14 Jun 2021 02:16:12 +0800 Subject: [PATCH 25/56] Try switching to a regex and exclude in the repo that loom adds Signed-off-by: shedaniel --- build.gradle | 5 +++-- src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e0a60edc..fac2e5b5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.w3c.dom.Document plugins { id 'java' @@ -56,8 +57,8 @@ repositories { maven { url "https://maven.architectury.dev/" } maven { url "https://maven.minecraftforge.net/" - content{ - excludeGroupByRegex "org.eclipse.*" + content { + excludeGroupByRegex "org\\.eclipse\\.?.*" } } } diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java index 3dc6c44f..de242a72 100644 --- a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -79,6 +79,9 @@ public class LoomRepositoryPlugin implements Plugin { repo.setName("Forge"); repo.setUrl("https://maven.minecraftforge.net/"); + repo.content(descriptor -> { + descriptor.excludeGroupByRegex("org\\.eclipse\\.?.*"); + }); repo.metadataSources(sources -> { sources.mavenPom(); sources.ignoreGradleMetadataRedirection(); From 75aca3b870a81e9e42b22279cd7deb7888be45dc Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 22:46:00 +0100 Subject: [PATCH 26/56] 0.4.1 tiny remapper --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index edca4935..844c3a2e 100644 --- a/build.gradle +++ b/build.gradle @@ -70,7 +70,7 @@ dependencies { } // tinyfile management - implementation ('net.fabricmc:tiny-remapper:0.4.0') + implementation ('net.fabricmc:tiny-remapper:0.4.1') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' From e179cccf64b23de5332852dfdc686ec6b25ab281 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 14 Jun 2021 08:49:43 +0100 Subject: [PATCH 27/56] Update Tiny Remapper to 0.4.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 844c3a2e..ef171a3a 100644 --- a/build.gradle +++ b/build.gradle @@ -70,7 +70,7 @@ dependencies { } // tinyfile management - implementation ('net.fabricmc:tiny-remapper:0.4.1') + implementation ('net.fabricmc:tiny-remapper:0.4.2') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' From 1f9f48052b4ac4ac2658b62128911f6a36127f8c Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 14 Jun 2021 18:39:03 +0100 Subject: [PATCH 28/56] Basic layered mappings with @ParchmentMC support (#413) --- build.gradle | 4 +- .../fabricmc/loom/LoomGradleExtension.java | 30 +- .../configuration/CompileConfiguration.java | 8 +- .../configuration/LoomDependencyManager.java | 8 +- .../loom/configuration/mods/ModProcessor.java | 4 +- .../MinecraftProcessedProvider.java | 6 +- .../providers/LaunchProvider.java | 2 +- .../providers/MinecraftProvider.java | 220 +-------- .../providers/MinecraftProviderImpl.java | 249 +++++++++++ .../mappings/GradleMappingContext.java | 74 +++ .../mappings/LayeredMappingSpec.java | 34 ++ .../mappings/LayeredMappingSpecBuilder.java | 65 +++ .../mappings/LayeredMappingsDependency.java | 143 ++++++ .../mappings/LayeredMappingsProcessor.java | 89 ++++ .../providers/mappings/MappingContext.java | 50 +++ .../providers/mappings/MappingLayer.java | 43 ++ .../providers/mappings/MappingNamespace.java | 37 ++ .../providers/mappings/MappingsProvider.java | 385 +--------------- .../mappings/MappingsProviderImpl.java | 423 ++++++++++++++++++ .../providers/mappings/MappingsSpec.java | 29 ++ .../mappings/MojangMappingsDependency.java | 275 ------------ .../IntermediaryMappingLayer.java | 55 +++ .../IntermediaryMappingsSpec.java | 35 ++ .../mappings/mojmap/MojangMappingLayer.java | 102 +++++ .../mappings/mojmap/MojangMappingsSpec.java | 51 +++ .../parchment/ParchmentMappingLayer.java | 63 +++ .../parchment/ParchmentMappingsSpec.java | 35 ++ .../ParchmentMappingsSpecBuilder.java | 48 ++ ...ParchmentPrefixStripingMappingVisitor.java | 50 +++ .../mappings/parchment/ParchmentTreeV1.java | 165 +++++++ .../minecraft/MinecraftLibraryProvider.java | 6 +- .../minecraft/MinecraftMappedProvider.java | 12 +- .../assets/MinecraftAssetsProvider.java | 6 +- .../loom/task/GenerateSourcesTask.java | 4 +- .../net/fabricmc/loom/task/LoomTasks.java | 4 +- .../loom/task/MigrateMappingsTask.java | 14 +- .../net/fabricmc/loom/task/RemapJarTask.java | 4 +- .../fabricmc/loom/util/SourceRemapper.java | 4 +- ...DependencyResolutionManagementTest.groovy} | 0 .../test/integration/ParchmentTest.groovy | 52 +++ .../IntermediaryMappingLayerTest.groovy | 43 ++ .../LayeredMappingSpecBuilderTest.groovy | 118 +++++ .../LayeredMappingsSpecification.groovy | 121 +++++ .../LayeredMappingsTestConstants.groovy | 47 ++ .../MojangMappingLayerTest.groovy | 49 ++ .../ParchmentMappingLayerTest.groovy | 74 +++ .../resources/projects/parchment/build.gradle | 20 + 47 files changed, 2435 insertions(+), 925 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java delete mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentPrefixStripingMappingVisitor.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentTreeV1.java rename src/test/groovy/net/fabricmc/loom/test/integration/{dependencyResolutionManagement.groovy => DependencyResolutionManagementTest.groovy} (100%) create mode 100644 src/test/groovy/net/fabricmc/loom/test/integration/ParchmentTest.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsTestConstants.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy create mode 100644 src/test/resources/projects/parchment/build.gradle diff --git a/build.gradle b/build.gradle index ef171a3a..3e4cb362 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,7 @@ configurations { } compileClasspath.extendsFrom bootstrap runtimeClasspath.extendsFrom bootstrap + testRuntimeClasspath.extendsFrom bootstrap } dependencies { @@ -74,6 +75,7 @@ dependencies { implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' + implementation 'net.fabricmc:mapping-io:0.1.3' implementation ('net.fabricmc:lorenz-tiny:3.0.0') { transitive = false @@ -92,7 +94,7 @@ dependencies { // Testing testImplementation(gradleTestKit()) - testImplementation('org.spockframework:spock-core:2.0-M5-groovy-3.0') { + testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') { exclude module: 'groovy-all' } testImplementation 'io.javalin:javalin:3.13.7' diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index b451c8d1..4f9f5e94 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -52,10 +52,13 @@ import net.fabricmc.loom.configuration.LoomProjectData; import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.processors.JarProcessor; import net.fabricmc.loom.configuration.processors.JarProcessorManager; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; -import net.fabricmc.loom.configuration.providers.mappings.MojangMappingsDependency; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; +import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext; +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec; +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder; +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; public class LoomGradleExtension { public String refmapName; @@ -114,7 +117,14 @@ public class LoomGradleExtension { } public Dependency officialMojangMappings() { - return new MojangMappingsDependency(project, this); + return layered(LayeredMappingSpecBuilder::officalMojangMappings); + } + + public Dependency layered(Action action) { + LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder(); + action.execute(builder); + LayeredMappingSpec builtSpec = builder.build(); + return new LayeredMappingsDependency(new GradleMappingContext(project, "layers_" + builtSpec.getVersion().replace("+", "_").replace(".", "_")), builtSpec, builtSpec.getVersion()); } public LoomGradleExtension(Project project) { @@ -246,7 +256,7 @@ public class LoomGradleExtension { return new File((String) project.property("fabric.loom.natives.dir")); } - File natives = new File(getUserCache(), "natives/" + getMinecraftProvider().getMinecraftVersion()); + File natives = new File(getUserCache(), "natives/" + getMinecraftProvider().minecraftVersion()); if (!natives.exists()) { natives.mkdirs(); @@ -271,16 +281,16 @@ public class LoomGradleExtension { return dependencyManager; } - public MinecraftProvider getMinecraftProvider() { - return getDependencyManager().getProvider(MinecraftProvider.class); + public MinecraftProviderImpl getMinecraftProvider() { + return getDependencyManager().getProvider(MinecraftProviderImpl.class); } public MinecraftMappedProvider getMinecraftMappedProvider() { return getMappingsProvider().mappedProvider; } - public MappingsProvider getMappingsProvider() { - return getDependencyManager().getProvider(MappingsProvider.class); + public MappingsProviderImpl getMappingsProvider() { + return getDependencyManager().getProvider(MappingsProviderImpl.class); } public void setDependencyManager(LoomDependencyManager dependencyManager) { @@ -342,7 +352,7 @@ public class LoomGradleExtension { // Creates a new file each time its called, this is then held onto later when remapping the output jar // Required as now when using parallel builds the old single file could be written by another sourceset compile task public synchronized File getNextMixinMappings() { - File mixinMapping = new File(getProjectBuildCache(), "mixin-map-" + getMinecraftProvider().getMinecraftVersion() + "-" + getMappingsProvider().mappingsVersion + "." + mixinMappings.size() + ".tiny"); + File mixinMapping = new File(getProjectBuildCache(), "mixin-map-" + getMinecraftProvider().minecraftVersion() + "-" + getMappingsProvider().mappingsVersion + "." + mixinMappings.size() + ".tiny"); mixinMappings.add(mixinMapping); return mixinMapping; } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index fb35b975..df32026e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -39,8 +39,8 @@ import net.fabricmc.loom.build.mixin.KaptApInvoker; import net.fabricmc.loom.build.mixin.ScalaApInvoker; import net.fabricmc.loom.configuration.ide.SetupIntelijRunConfigs; import net.fabricmc.loom.configuration.providers.LaunchProvider; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.Constants; public final class CompileConfiguration { @@ -116,8 +116,8 @@ public final class CompileConfiguration { LoomDependencyManager dependencyManager = new LoomDependencyManager(); extension.setDependencyManager(dependencyManager); - dependencyManager.addProvider(new MinecraftProvider(project)); - dependencyManager.addProvider(new MappingsProvider(project)); + dependencyManager.addProvider(new MinecraftProviderImpl(project)); + dependencyManager.addProvider(new MappingsProviderImpl(project)); dependencyManager.addProvider(new LaunchProvider(project)); dependencyManager.handleDependencies(project); diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index 55c544cf..31ec1b6a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -42,7 +42,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.build.ModCompileRemapper; import net.fabricmc.loom.configuration.DependencyProvider.DependencyInfo; import net.fabricmc.loom.configuration.mods.ModProcessor; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.SourceRemapper; import net.fabricmc.loom.LoomRepositoryPlugin; @@ -86,7 +86,7 @@ public class LoomDependencyManager { public void handleDependencies(Project project) { List afterTasks = new ArrayList<>(); - MappingsProvider mappingsProvider = null; + MappingsProviderImpl mappingsProvider = null; project.getLogger().info(":setting up loom dependencies"); LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); @@ -100,8 +100,8 @@ public class LoomDependencyManager { return list; }).providers.add(provider); - if (provider instanceof MappingsProvider) { - mappingsProvider = (MappingsProvider) provider; + if (provider instanceof MappingsProviderImpl) { + mappingsProvider = (MappingsProviderImpl) provider; } } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index 6eaa1133..23d6138b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -56,7 +56,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.configuration.RemappedConfigurationEntry; import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.TinyRemapperMappingsHelper; @@ -132,7 +132,7 @@ public class ModProcessor { String toM = "named"; MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider(); - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); Path mc = mappedProvider.getIntermediaryJar().toPath(); Path[] mcDeps = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES).getFiles() diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java index 0a24a75f..d0213ebf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java @@ -31,8 +31,8 @@ import java.util.function.Consumer; import org.apache.commons.io.FileUtils; import org.gradle.api.Project; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.util.Constants; @@ -84,7 +84,7 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { } @Override - public void initFiles(MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) { + public void initFiles(MinecraftProviderImpl minecraftProvider, MappingsProviderImpl mappingsProvider) { super.initFiles(minecraftProvider, mappingsProvider); projectMappedJar = new File(getJarDirectory(getExtension().getRootProjectPersistentCache(), projectMappedClassifier), "minecraft-" + getJarVersionString(projectMappedClassifier) + ".jar"); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java index e7f961df..980cecf0 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java @@ -65,7 +65,7 @@ public class LaunchProvider extends DependencyProvider { .property("client", "org.lwjgl.librarypath", getExtension().getNativesDirectory().getAbsolutePath()) .argument("client", "--assetIndex") - .argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().getMinecraftVersion())) + .argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion())) .argument("client", "--assetsDir") .argument("client", new File(getExtension().getUserCache(), "assets").getAbsolutePath()); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java index aed9c725..fed7f5fb 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java @@ -24,224 +24,10 @@ package net.fabricmc.loom.configuration.providers; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Optional; -import java.util.function.Consumer; - -import com.google.common.io.Files; -import org.gradle.api.GradleException; -import org.gradle.api.Project; -import org.gradle.api.logging.Logger; - -import net.fabricmc.loom.LoomGradlePlugin; -import net.fabricmc.loom.configuration.DependencyProvider; -import net.fabricmc.loom.configuration.providers.minecraft.ManifestVersion; -import net.fabricmc.loom.configuration.providers.minecraft.MinecraftLibraryProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.DownloadUtil; -import net.fabricmc.loom.util.HashedDownloadUtil; -import net.fabricmc.stitch.merge.JarMerger; -public class MinecraftProvider extends DependencyProvider { - private String minecraftVersion; +public interface MinecraftProvider { + String minecraftVersion(); - private MinecraftVersionMeta versionInfo; - private MinecraftLibraryProvider libraryProvider; - - private File minecraftJson; - private File minecraftClientJar; - private File minecraftServerJar; - private File minecraftMergedJar; - private File versionManifestJson; - - public MinecraftProvider(Project project) { - super(project); - } - - @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { - minecraftVersion = dependency.getDependency().getVersion(); - - boolean offline = getProject().getGradle().getStartParameter().isOffline(); - - initFiles(); - - downloadMcJson(offline); - - try (FileReader reader = new FileReader(minecraftJson)) { - versionInfo = LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, MinecraftVersionMeta.class); - } - - // Add Loom as an annotation processor - addDependency(getProject().files(this.getClass().getProtectionDomain().getCodeSource().getLocation()), "compileOnly"); - - if (offline) { - if (minecraftClientJar.exists() && minecraftServerJar.exists()) { - getProject().getLogger().debug("Found client and server jars, presuming up-to-date"); - } else if (minecraftMergedJar.exists()) { - //Strictly we don't need the split jars if the merged one exists, let's try go on - getProject().getLogger().warn("Missing game jar but merged jar present, things might end badly"); - } else { - throw new GradleException("Missing jar(s); Client: " + minecraftClientJar.exists() + ", Server: " + minecraftServerJar.exists()); - } - } else { - downloadJars(getProject().getLogger()); - } - - libraryProvider = new MinecraftLibraryProvider(); - libraryProvider.provide(this, getProject()); - - if (!minecraftMergedJar.exists() || isRefreshDeps()) { - try { - mergeJars(getProject().getLogger()); - } catch (Throwable e) { - HashedDownloadUtil.delete(minecraftClientJar); - HashedDownloadUtil.delete(minecraftServerJar); - minecraftMergedJar.delete(); - - getProject().getLogger().error("Could not merge JARs! Deleting source JARs - please re-run the command and move on.", e); - throw e; - } - } - } - - private void initFiles() { - minecraftJson = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-info.json"); - minecraftClientJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-client.jar"); - minecraftServerJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-server.jar"); - minecraftMergedJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-merged.jar"); - versionManifestJson = new File(getExtension().getUserCache(), "version_manifest.json"); - } - - private void downloadMcJson(boolean offline) throws IOException { - if (getExtension().isShareCaches() && !getExtension().isRootProject() && versionManifestJson.exists() && !isRefreshDeps()) { - return; - } - - if (!offline && !isRefreshDeps() && hasRecentValidManifest()) { - // We have a recent valid manifest file, so do nothing - } else if (offline) { - if (versionManifestJson.exists()) { - // If there is the manifests already we'll presume that's good enough - getProject().getLogger().debug("Found version manifests, presuming up-to-date"); - } else { - // If we don't have the manifests then there's nothing more we can do - throw new GradleException("Version manifests not found at " + versionManifestJson.getAbsolutePath()); - } - } else { - getProject().getLogger().debug("Downloading version manifests"); - DownloadUtil.downloadIfChanged(new URL(Constants.VERSION_MANIFESTS), versionManifestJson, getProject().getLogger()); - } - - String versionManifest = Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read(); - ManifestVersion mcManifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(versionManifest, ManifestVersion.class); - - Optional optionalVersion = Optional.empty(); - - if (getExtension().customManifest != null) { - ManifestVersion.Versions customVersion = new ManifestVersion.Versions(); - customVersion.id = minecraftVersion; - customVersion.url = getExtension().customManifest; - optionalVersion = Optional.of(customVersion); - getProject().getLogger().lifecycle("Using custom minecraft manifest"); - } - - if (!optionalVersion.isPresent()) { - optionalVersion = mcManifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst(); - } - - if (optionalVersion.isPresent()) { - if (offline) { - if (minecraftJson.exists()) { - //If there is the manifest already we'll presume that's good enough - getProject().getLogger().debug("Found Minecraft {} manifest, presuming up-to-date", minecraftVersion); - } else { - //If we don't have the manifests then there's nothing more we can do - throw new GradleException("Minecraft " + minecraftVersion + " manifest not found at " + minecraftJson.getAbsolutePath()); - } - } else { - getProject().getLogger().debug("Downloading Minecraft {} manifest", minecraftVersion); - - ManifestVersion.Versions version = optionalVersion.get(); - String url = version.url; - - if (version.sha1 != null) { - HashedDownloadUtil.downloadIfInvalid(new URL(url), minecraftJson, version.sha1, getProject().getLogger(), true); - } else { - // Use the etag if no hash found from url - DownloadUtil.downloadIfChanged(new URL(url), minecraftJson, getProject().getLogger()); - } - } - } else { - throw new RuntimeException("Failed to find minecraft version: " + minecraftVersion); - } - } - - private boolean hasRecentValidManifest() throws IOException { - if (getExtension().customManifest != null) { - return false; - } - - if (!versionManifestJson.exists() || !minecraftJson.exists()) { - return false; - } - - if (versionManifestJson.lastModified() > System.currentTimeMillis() - 24 * 3_600_000) { - // Version manifest hasn't been modified in 24 hours, time to get a new one. - return false; - } - - ManifestVersion manifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read(), ManifestVersion.class); - Optional version = manifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst(); - - // fail if the expected mc version was not found, will download the file again. - return version.isPresent(); - } - - private void downloadJars(Logger logger) throws IOException { - if (getExtension().isShareCaches() && !getExtension().isRootProject() && minecraftClientJar.exists() && minecraftServerJar.exists() && !isRefreshDeps()) { - return; - } - - MinecraftVersionMeta.Download client = versionInfo.download("client"); - MinecraftVersionMeta.Download server = versionInfo.download("server"); - - HashedDownloadUtil.downloadIfInvalid(new URL(client.url()), minecraftClientJar, client.sha1(), logger, false); - HashedDownloadUtil.downloadIfInvalid(new URL(server.url()), minecraftServerJar, server.sha1(), logger, false); - } - - private void mergeJars(Logger logger) throws IOException { - logger.info(":merging jars"); - - try (JarMerger jarMerger = new JarMerger(minecraftClientJar, minecraftServerJar, minecraftMergedJar)) { - jarMerger.enableSyntheticParamsOffset(); - jarMerger.merge(); - } - } - - public File getMergedJar() { - return minecraftMergedJar; - } - - public String getMinecraftVersion() { - return minecraftVersion; - } - - public MinecraftVersionMeta getVersionInfo() { - return versionInfo; - } - - public MinecraftLibraryProvider getLibraryProvider() { - return libraryProvider; - } - - @Override - public String getTargetConfig() { - return Constants.Configurations.MINECRAFT; - } + MinecraftVersionMeta getVersionInfo(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java new file mode 100644 index 00000000..2767755e --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java @@ -0,0 +1,249 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.function.Consumer; + +import com.google.common.io.Files; +import org.gradle.api.GradleException; +import org.gradle.api.Project; +import org.gradle.api.logging.Logger; + +import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.configuration.DependencyProvider; +import net.fabricmc.loom.configuration.providers.minecraft.ManifestVersion; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftLibraryProvider; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.DownloadUtil; +import net.fabricmc.loom.util.HashedDownloadUtil; +import net.fabricmc.stitch.merge.JarMerger; + +public class MinecraftProviderImpl extends DependencyProvider implements MinecraftProvider { + private String minecraftVersion; + + private MinecraftVersionMeta versionInfo; + private MinecraftLibraryProvider libraryProvider; + + private File minecraftJson; + private File minecraftClientJar; + private File minecraftServerJar; + private File minecraftMergedJar; + private File versionManifestJson; + + public MinecraftProviderImpl(Project project) { + super(project); + } + + @Override + public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + minecraftVersion = dependency.getDependency().getVersion(); + + boolean offline = getProject().getGradle().getStartParameter().isOffline(); + + initFiles(); + + downloadMcJson(offline); + + try (FileReader reader = new FileReader(minecraftJson)) { + versionInfo = LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, MinecraftVersionMeta.class); + } + + // Add Loom as an annotation processor + addDependency(getProject().files(this.getClass().getProtectionDomain().getCodeSource().getLocation()), "compileOnly"); + + if (offline) { + if (minecraftClientJar.exists() && minecraftServerJar.exists()) { + getProject().getLogger().debug("Found client and server jars, presuming up-to-date"); + } else if (minecraftMergedJar.exists()) { + //Strictly we don't need the split jars if the merged one exists, let's try go on + getProject().getLogger().warn("Missing game jar but merged jar present, things might end badly"); + } else { + throw new GradleException("Missing jar(s); Client: " + minecraftClientJar.exists() + ", Server: " + minecraftServerJar.exists()); + } + } else { + downloadJars(getProject().getLogger()); + } + + libraryProvider = new MinecraftLibraryProvider(); + libraryProvider.provide(this, getProject()); + + if (!minecraftMergedJar.exists() || isRefreshDeps()) { + try { + mergeJars(getProject().getLogger()); + } catch (Throwable e) { + HashedDownloadUtil.delete(minecraftClientJar); + HashedDownloadUtil.delete(minecraftServerJar); + minecraftMergedJar.delete(); + + getProject().getLogger().error("Could not merge JARs! Deleting source JARs - please re-run the command and move on.", e); + throw e; + } + } + } + + private void initFiles() { + minecraftJson = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-info.json"); + minecraftClientJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-client.jar"); + minecraftServerJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-server.jar"); + minecraftMergedJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-merged.jar"); + versionManifestJson = new File(getExtension().getUserCache(), "version_manifest.json"); + } + + private void downloadMcJson(boolean offline) throws IOException { + if (getExtension().isShareCaches() && !getExtension().isRootProject() && versionManifestJson.exists() && !isRefreshDeps()) { + return; + } + + if (!offline && !isRefreshDeps() && hasRecentValidManifest()) { + // We have a recent valid manifest file, so do nothing + } else if (offline) { + if (versionManifestJson.exists()) { + // If there is the manifests already we'll presume that's good enough + getProject().getLogger().debug("Found version manifests, presuming up-to-date"); + } else { + // If we don't have the manifests then there's nothing more we can do + throw new GradleException("Version manifests not found at " + versionManifestJson.getAbsolutePath()); + } + } else { + getProject().getLogger().debug("Downloading version manifests"); + DownloadUtil.downloadIfChanged(new URL(Constants.VERSION_MANIFESTS), versionManifestJson, getProject().getLogger()); + } + + String versionManifest = Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read(); + ManifestVersion mcManifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(versionManifest, ManifestVersion.class); + + Optional optionalVersion = Optional.empty(); + + if (getExtension().customManifest != null) { + ManifestVersion.Versions customVersion = new ManifestVersion.Versions(); + customVersion.id = minecraftVersion; + customVersion.url = getExtension().customManifest; + optionalVersion = Optional.of(customVersion); + getProject().getLogger().lifecycle("Using custom minecraft manifest"); + } + + if (!optionalVersion.isPresent()) { + optionalVersion = mcManifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst(); + } + + if (optionalVersion.isPresent()) { + if (offline) { + if (minecraftJson.exists()) { + //If there is the manifest already we'll presume that's good enough + getProject().getLogger().debug("Found Minecraft {} manifest, presuming up-to-date", minecraftVersion); + } else { + //If we don't have the manifests then there's nothing more we can do + throw new GradleException("Minecraft " + minecraftVersion + " manifest not found at " + minecraftJson.getAbsolutePath()); + } + } else { + getProject().getLogger().debug("Downloading Minecraft {} manifest", minecraftVersion); + + ManifestVersion.Versions version = optionalVersion.get(); + String url = version.url; + + if (version.sha1 != null) { + HashedDownloadUtil.downloadIfInvalid(new URL(url), minecraftJson, version.sha1, getProject().getLogger(), true); + } else { + // Use the etag if no hash found from url + DownloadUtil.downloadIfChanged(new URL(url), minecraftJson, getProject().getLogger()); + } + } + } else { + throw new RuntimeException("Failed to find minecraft version: " + minecraftVersion); + } + } + + private boolean hasRecentValidManifest() throws IOException { + if (getExtension().customManifest != null) { + return false; + } + + if (!versionManifestJson.exists() || !minecraftJson.exists()) { + return false; + } + + if (versionManifestJson.lastModified() > System.currentTimeMillis() - 24 * 3_600_000) { + // Version manifest hasn't been modified in 24 hours, time to get a new one. + return false; + } + + ManifestVersion manifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read(), ManifestVersion.class); + Optional version = manifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst(); + + // fail if the expected mc version was not found, will download the file again. + return version.isPresent(); + } + + private void downloadJars(Logger logger) throws IOException { + if (getExtension().isShareCaches() && !getExtension().isRootProject() && minecraftClientJar.exists() && minecraftServerJar.exists() && !isRefreshDeps()) { + return; + } + + MinecraftVersionMeta.Download client = versionInfo.download("client"); + MinecraftVersionMeta.Download server = versionInfo.download("server"); + + HashedDownloadUtil.downloadIfInvalid(new URL(client.url()), minecraftClientJar, client.sha1(), logger, false); + HashedDownloadUtil.downloadIfInvalid(new URL(server.url()), minecraftServerJar, server.sha1(), logger, false); + } + + private void mergeJars(Logger logger) throws IOException { + logger.info(":merging jars"); + + try (JarMerger jarMerger = new JarMerger(minecraftClientJar, minecraftServerJar, minecraftMergedJar)) { + jarMerger.enableSyntheticParamsOffset(); + jarMerger.merge(); + } + } + + public File getMergedJar() { + return minecraftMergedJar; + } + + @Override + public String minecraftVersion() { + return minecraftVersion; + } + + @Override + public MinecraftVersionMeta getVersionInfo() { + return versionInfo; + } + + public MinecraftLibraryProvider getLibraryProvider() { + return libraryProvider; + } + + @Override + public String getTargetConfig() { + return Constants.Configurations.MINECRAFT; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java new file mode 100644 index 00000000..d9357014 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java @@ -0,0 +1,74 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.File; + +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.logging.Logger; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.configuration.providers.MinecraftProvider; + +public class GradleMappingContext implements MappingContext { + private final Project project; + private final LoomGradleExtension extension; + private final String workingDirName; + + public GradleMappingContext(Project project, String workingDirName) { + this.project = project; + this.extension = project.getExtensions().getByType(LoomGradleExtension.class); + this.workingDirName = workingDirName; + } + + @Override + public File mavenFile(String mavenNotation) { + Configuration configuration = project.getConfigurations().detachedConfiguration(project.getDependencies().create(mavenNotation)); + return configuration.getSingleFile(); + } + + @Override + public MappingsProvider mappingsProvider() { + return extension.getMappingsProvider(); + } + + @Override + public MinecraftProvider minecraftProvider() { + return extension.getMinecraftProvider(); + } + + @Override + public File workingDirectory(String name) { + File tempDir = new File(mappingsProvider().getMappingsDir().toFile(), workingDirName); + tempDir.mkdirs(); + return new File(tempDir, name); + } + + @Override + public Logger getLogger() { + return project.getLogger(); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java new file mode 100644 index 00000000..9f86fb5d --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpec.java @@ -0,0 +1,34 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.util.List; + +public record LayeredMappingSpec(List> layers) { + public String getVersion() { + // TODO something better? + return "layered+hash.%d".formatted(Math.abs(hashCode())); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java new file mode 100644 index 00000000..389df643 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java @@ -0,0 +1,65 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.gradle.api.Action; + +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec; +import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec; +import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpecBuilder; + +public class LayeredMappingSpecBuilder { + private final List> layers = new LinkedList<>(); + + public LayeredMappingSpecBuilder officalMojangMappings() { + layers.add(new MojangMappingsSpec()); + return this; + } + + public LayeredMappingSpecBuilder parchment(String mavenNotation) { + parchment(mavenNotation, parchmentMappingsSpecBuilder -> parchmentMappingsSpecBuilder.setRemovePrefix(true)); + return this; + } + + public LayeredMappingSpecBuilder parchment(String mavenNotation, Action action) { + var builder = ParchmentMappingsSpecBuilder.builder(mavenNotation); + action.execute(builder); + layers.add(builder.build()); + return this; + } + + public LayeredMappingSpec build() { + List> builtLayers = new LinkedList<>(); + // Intermediary is always the base layer + builtLayers.add(new IntermediaryMappingsSpec()); + builtLayers.addAll(layers); + + return new LayeredMappingSpec(Collections.unmodifiableList(builtLayers)); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java new file mode 100644 index 00000000..ddc1664d --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java @@ -0,0 +1,143 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.gradle.api.artifacts.Dependency; +import org.gradle.api.artifacts.SelfResolvingDependency; +import org.gradle.api.tasks.TaskDependency; +import org.zeroturnaround.zip.ByteSource; +import org.zeroturnaround.zip.ZipEntrySource; +import org.zeroturnaround.zip.ZipUtil; + +import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.mappingio.adapter.MappingDstNsReorder; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.format.Tiny2Writer; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +public class LayeredMappingsDependency implements SelfResolvingDependency { + private static final String GROUP = "loom"; + private static final String MODULE = "mappings"; + + private final MappingContext mappingContext; + private final LayeredMappingSpec layeredMappingSpec; + private final String version; + + public LayeredMappingsDependency(MappingContext mappingContext, LayeredMappingSpec layeredMappingSpec, String version) { + this.mappingContext = mappingContext; + this.layeredMappingSpec = layeredMappingSpec; + this.version = version; + } + + @Override + public Set resolve() { + Path mappingsDir = mappingContext.mappingsProvider().getMappingsDir(); + Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion())); + + if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) { + try { + var processor = new LayeredMappingsProcessor(layeredMappingSpec); + MemoryMappingTree mappings = processor.getMappings(mappingContext); + + try (Writer writer = new StringWriter()) { + Tiny2Writer tiny2Writer = new Tiny2Writer(writer, false); + + MappingDstNsReorder nsReorder = new MappingDstNsReorder(tiny2Writer, Collections.singletonList(MappingNamespace.NAMED.stringValue())); + MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingNamespace.INTERMEDIARY.stringValue()); + mappings.accept(nsSwitch); + + Files.deleteIfExists(mappingsFile); + + ZipUtil.pack(new ZipEntrySource[] { + new ByteSource("mappings/mappings.tiny", writer.toString().getBytes(StandardCharsets.UTF_8)) + }, mappingsFile.toFile()); + } + } catch (IOException e) { + throw new RuntimeException("Failed to resolve Mojang mappings", e); + } + } + + return Collections.singleton(mappingsFile.toFile()); + } + + @Override + public Set resolve(boolean transitive) { + return resolve(); + } + + @Override + public TaskDependency getBuildDependencies() { + return task -> Collections.emptySet(); + } + + @Override + public String getGroup() { + return GROUP; + } + + @Override + public String getName() { + return MODULE; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public boolean contentEquals(Dependency dependency) { + if (dependency instanceof LayeredMappingsDependency layeredMappingsDependency) { + return Objects.equals(layeredMappingsDependency.getVersion(), this.getVersion()); + } + + return false; + } + + @Override + public Dependency copy() { + return new LayeredMappingsDependency(mappingContext, layeredMappingSpec, version); + } + + @Override + public String getReason() { + return null; + } + + @Override + public void because(String s) { + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java new file mode 100644 index 00000000..cc45ea6f --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java @@ -0,0 +1,89 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +public class LayeredMappingsProcessor { + private final LayeredMappingSpec layeredMappingSpec; + + public LayeredMappingsProcessor(LayeredMappingSpec spec) { + this.layeredMappingSpec = spec; + } + + public MemoryMappingTree getMappings(MappingContext context) throws IOException { + MemoryMappingTree mappingTree = new MemoryMappingTree(); + + List> visitedLayers = new ArrayList<>(); + + for (MappingsSpec spec : layeredMappingSpec.layers()) { + MappingLayer layer = spec.createLayer(context); + + for (Class dependentLayer : layer.dependsOn()) { + if (!visitedLayers.contains(dependentLayer)) { + throw new RuntimeException("Layer %s depends on %s".formatted(layer.getClass().getName(), dependentLayer.getName())); + } + } + + visitedLayers.add(layer.getClass()); + + // We have to rebuild a new tree to work on when a layer doesnt merge into layered + boolean rebuild = layer.getSourceNamespace() != MappingNamespace.NAMED; + MemoryMappingTree workingTree; + + if (rebuild) { + var tempTree = new MemoryMappingTree(); + + // This can be null on the first layer + if (mappingTree.getSrcNamespace() != null) { + var sourceNsSwitch = new MappingSourceNsSwitch(tempTree, layer.getSourceNamespace().stringValue()); + mappingTree.accept(sourceNsSwitch); + } + + workingTree = tempTree; + } else { + workingTree = mappingTree; + } + + try { + layer.visit(workingTree); + } catch (IOException e) { + throw new IOException("Failed to visit: " + layer.getClass(), e); + } + + if (rebuild) { + mappingTree = new MemoryMappingTree(); + workingTree.accept(new MappingSourceNsSwitch(mappingTree, MappingNamespace.NAMED.stringValue())); + } + } + + return mappingTree; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java new file mode 100644 index 00000000..5ae5ea6f --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingContext.java @@ -0,0 +1,50 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.File; + +import org.gradle.api.logging.Logger; + +import net.fabricmc.loom.configuration.providers.MinecraftProvider; + +public interface MappingContext { + File mavenFile(String mavenNotation); + + MappingsProvider mappingsProvider(); + + MinecraftProvider minecraftProvider(); + + default String minecraftVersion() { + return minecraftProvider().minecraftVersion(); + } + + /** + * Creates a temporary working dir to be used to store working files. + */ + File workingDirectory(String name); + + Logger getLogger(); +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java new file mode 100644 index 00000000..2fdd451f --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingLayer.java @@ -0,0 +1,43 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import net.fabricmc.mappingio.MappingVisitor; + +public interface MappingLayer { + void visit(MappingVisitor mappingVisitor) throws IOException; + + default MappingNamespace getSourceNamespace() { + return MappingNamespace.NAMED; + } + + default List> dependsOn() { + return Collections.emptyList(); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java new file mode 100644 index 00000000..8ac400ad --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingNamespace.java @@ -0,0 +1,37 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.util.Locale; + +public enum MappingNamespace { + OFFICIAL, + INTERMEDIARY, + NAMED; + + public String stringValue() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java index c19b3796..c2c28280 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java @@ -24,390 +24,11 @@ package net.fabricmc.loom.configuration.providers.mappings; -import java.io.BufferedReader; import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.function.Consumer; -import com.google.common.base.Preconditions; -import com.google.common.net.UrlEscapers; -import com.google.gson.JsonObject; -import org.apache.commons.io.FileUtils; -import org.apache.tools.ant.util.StringUtils; -import org.gradle.api.Project; -import org.zeroturnaround.zip.FileSource; -import org.zeroturnaround.zip.ZipEntrySource; -import org.zeroturnaround.zip.ZipUtil; +public interface MappingsProvider { + Path getMappingsDir(); -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.LoomGradlePlugin; -import net.fabricmc.loom.configuration.DependencyProvider; -import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; -import net.fabricmc.loom.configuration.processors.JarProcessorManager; -import net.fabricmc.loom.configuration.processors.MinecraftProcessedProvider; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; -import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.DeletingFileVisitor; -import net.fabricmc.loom.util.DownloadUtil; -import net.fabricmc.mapping.reader.v2.TinyV2Factory; -import net.fabricmc.mapping.tree.TinyTree; -import net.fabricmc.stitch.Command; -import net.fabricmc.stitch.commands.CommandProposeFieldNames; -import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2; -import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2; - -public class MappingsProvider extends DependencyProvider { - public MinecraftMappedProvider mappedProvider; - - public String mappingsName; - public String minecraftVersion; - public String mappingsVersion; - - private final Path mappingsDir; - private final Path mappingsStepsDir; - private Path intermediaryTiny; - private boolean hasRefreshed = false; - // The mappings that gradle gives us - private Path baseTinyMappings; - // The mappings we use in practice - public File tinyMappings; - public File tinyMappingsJar; - private File unpickDefinitionsFile; - private boolean hasUnpickDefinitions; - private UnpickMetadata unpickMetadata; - - public MappingsProvider(Project project) { - super(project); - mappingsDir = getExtension().getUserCache().toPath().resolve("mappings"); - mappingsStepsDir = mappingsDir.resolve("steps"); - } - - public void clean() throws IOException { - FileUtils.deleteDirectory(mappingsDir.toFile()); - } - - public TinyTree getMappings() throws IOException { - return MappingsCache.INSTANCE.get(tinyMappings.toPath()); - } - - @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { - MinecraftProvider minecraftProvider = getDependencyManager().getProvider(MinecraftProvider.class); - - getProject().getLogger().info(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")"); - - String version = dependency.getResolvedVersion(); - File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find yarn mappings: " + dependency)); - - this.mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged"); - this.minecraftVersion = minecraftProvider.getMinecraftVersion(); - - boolean isV2; - - // Only do this for official yarn, there isn't really a way we can get the mc version for all mappings - if (dependency.getDependency().getGroup() != null && dependency.getDependency().getGroup().equals("net.fabricmc") && dependency.getDependency().getName().equals("yarn") && dependency.getDependency().getVersion() != null) { - String yarnVersion = dependency.getDependency().getVersion(); - char separator = yarnVersion.contains("+build.") ? '+' : yarnVersion.contains("-") ? '-' : '.'; - String yarnMinecraftVersion = yarnVersion.substring(0, yarnVersion.lastIndexOf(separator)); - - if (!yarnMinecraftVersion.equalsIgnoreCase(minecraftVersion)) { - throw new RuntimeException(String.format("Minecraft Version (%s) does not match yarn's minecraft version (%s)", minecraftVersion, yarnMinecraftVersion)); - } - - // We can save reading the zip file + header by checking the file name - isV2 = mappingsJar.getName().endsWith("-v2.jar"); - } else { - isV2 = doesJarContainV2Mappings(mappingsJar.toPath()); - } - - this.mappingsVersion = version + (isV2 ? "-v2" : ""); - - initFiles(); - - if (isRefreshDeps()) { - cleanFiles(); - } - - Files.createDirectories(mappingsDir); - Files.createDirectories(mappingsStepsDir); - - String[] depStringSplit = dependency.getDepString().split(":"); - String jarClassifier = "final"; - - if (depStringSplit.length >= 4) { - jarClassifier = jarClassifier + depStringSplit[3]; - } - - tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile(); - unpickDefinitionsFile = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".unpick").toFile(); - tinyMappingsJar = new File(getExtension().getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar")); - - if (!tinyMappings.exists() || isRefreshDeps()) { - storeMappings(getProject(), minecraftProvider, mappingsJar.toPath()); - } else { - try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), (ClassLoader) null)) { - extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); - } - } - - if (!tinyMappingsJar.exists() || isRefreshDeps()) { - ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar); - } - - if (hasUnpickDefinitions()) { - String notation = String.format("%s:%s:%s:constants", - dependency.getDependency().getGroup(), - dependency.getDependency().getName(), - dependency.getDependency().getVersion() - ); - - getProject().getDependencies().add(Constants.Configurations.MAPPING_CONSTANTS, notation); - populateUnpickClasspath(); - } - - addDependency(tinyMappingsJar, Constants.Configurations.MAPPINGS_FINAL); - - LoomGradleExtension extension = getExtension(); - - if (extension.accessWidener != null) { - extension.addJarProcessor(new AccessWidenerJarProcessor(getProject())); - } - - JarProcessorManager processorManager = new JarProcessorManager(extension.getJarProcessors()); - extension.setJarProcessorManager(processorManager); - processorManager.setupProcessors(); - - if (processorManager.active()) { - mappedProvider = new MinecraftProcessedProvider(getProject(), processorManager); - getProject().getLogger().lifecycle("Using project based jar storage"); - } else { - mappedProvider = new MinecraftMappedProvider(getProject()); - } - - mappedProvider.initFiles(minecraftProvider, this); - mappedProvider.provide(dependency, postPopulationScheduler); - } - - private void storeMappings(Project project, MinecraftProvider minecraftProvider, Path yarnJar) throws IOException { - project.getLogger().info(":extracting " + yarnJar.getFileName()); - - try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, (ClassLoader) null)) { - extractMappings(fileSystem, baseTinyMappings); - extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); - } - - if (baseMappingsAreV2()) { - // These are unmerged v2 mappings - mergeAndSaveMappings(project, yarnJar); - } else { - // These are merged v1 mappings - if (tinyMappings.exists()) { - tinyMappings.delete(); - } - - project.getLogger().lifecycle(":populating field names"); - suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings.toPath()); - } - } - - private boolean baseMappingsAreV2() throws IOException { - try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) { - TinyV2Factory.readMetadata(reader); - return true; - } catch (IllegalArgumentException e) { - // TODO: just check the mappings version when Parser supports V1 in readMetadata() - return false; - } - } - - private boolean doesJarContainV2Mappings(Path path) throws IOException { - try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { - try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) { - TinyV2Factory.readMetadata(reader); - return true; - } catch (IllegalArgumentException e) { - return false; - } - } - } - - public static void extractMappings(FileSystem jar, Path extractTo) throws IOException { - Files.copy(jar.getPath("mappings/mappings.tiny"), extractTo, StandardCopyOption.REPLACE_EXISTING); - } - - private void extractUnpickDefinitions(FileSystem jar, Path extractTo) throws IOException { - Path unpickPath = jar.getPath("extras/definitions.unpick"); - Path unpickMetadataPath = jar.getPath("extras/unpick.json"); - - if (!Files.exists(unpickPath) || !Files.exists(unpickMetadataPath)) { - return; - } - - Files.copy(unpickPath, extractTo, StandardCopyOption.REPLACE_EXISTING); - - unpickMetadata = parseUnpickMetadata(unpickMetadataPath); - hasUnpickDefinitions = true; - } - - private UnpickMetadata parseUnpickMetadata(Path input) throws IOException { - JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(Files.readString(input), JsonObject.class); - - if (!jsonObject.has("version") || jsonObject.get("version").getAsInt() != 1) { - throw new UnsupportedOperationException("Unsupported unpick version"); - } - - return new UnpickMetadata( - jsonObject.get("unpickGroup").getAsString(), - jsonObject.get("unpickVersion").getAsString() - ); - } - - private void populateUnpickClasspath() { - String unpickCliName = "unpick-cli"; - getProject().getDependencies().add(Constants.Configurations.UNPICK_CLASSPATH, - String.format("%s:%s:%s", unpickMetadata.unpickGroup, unpickCliName, unpickMetadata.unpickVersion) - ); - } - - private void extractIntermediary(Path intermediaryJar, Path intermediaryTiny) throws IOException { - getProject().getLogger().info(":extracting " + intermediaryJar.getFileName()); - - try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(intermediaryJar, (ClassLoader) null)) { - extractMappings(unmergedIntermediaryFs, intermediaryTiny); - } - } - - private void mergeAndSaveMappings(Project project, Path unmergedYarnJar) throws IOException { - Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny"); - project.getLogger().info(":extracting " + unmergedYarnJar.getFileName()); - - try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, (ClassLoader) null)) { - extractMappings(unmergedYarnJarFs, unmergedYarn); - } - - Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny"); - reorderMappings(getIntermediaryTiny(), invertedIntermediary, "intermediary", "official"); - Path unorderedMergedMappings = Paths.get(mappingsStepsDir.toString(), "unordered-merged.tiny"); - project.getLogger().info(":merging"); - mergeMappings(invertedIntermediary, unmergedYarn, unorderedMergedMappings); - reorderMappings(unorderedMergedMappings, tinyMappings.toPath(), "official", "intermediary", "named"); - } - - private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) { - Command command = new CommandReorderTinyV2(); - String[] args = new String[2 + newOrder.length]; - args[0] = oldMappings.toAbsolutePath().toString(); - args[1] = newMappings.toAbsolutePath().toString(); - System.arraycopy(newOrder, 0, args, 2, newOrder.length); - runCommand(command, args); - } - - private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) { - try { - Command command = new CommandMergeTinyV2(); - runCommand(command, intermediaryMappings.toAbsolutePath().toString(), - yarnMappings.toAbsolutePath().toString(), - newMergedMappings.toAbsolutePath().toString(), - "intermediary", "official"); - } catch (Exception e) { - throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString() - + " with mappings from " + yarnMappings, e); - } - } - - private void suggestFieldNames(MinecraftProvider minecraftProvider, Path oldMappings, Path newMappings) { - Command command = new CommandProposeFieldNames(); - runCommand(command, minecraftProvider.getMergedJar().getAbsolutePath(), - oldMappings.toAbsolutePath().toString(), - newMappings.toAbsolutePath().toString()); - } - - private void runCommand(Command command, String... args) { - try { - command.run(args); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private void initFiles() { - baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base"); - } - - public void cleanFiles() { - try { - if (Files.exists(mappingsStepsDir)) { - Files.walkFileTree(mappingsStepsDir, new DeletingFileVisitor()); - } - - if (Files.exists(baseTinyMappings)) { - Files.deleteIfExists(baseTinyMappings); - } - - if (tinyMappings != null) { - tinyMappings.delete(); - } - - if (tinyMappingsJar != null) { - tinyMappingsJar.delete(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public String getTargetConfig() { - return Constants.Configurations.MAPPINGS; - } - - public Path getMappingsDir() { - return mappingsDir; - } - - public Path getIntermediaryTiny() throws IOException { - if (intermediaryTiny == null) { - minecraftVersion = getExtension().getMinecraftProvider().getMinecraftVersion(); - Preconditions.checkNotNull(minecraftVersion, "Minecraft version cannot be null"); - - intermediaryTiny = mappingsDir.resolve(String.format("intermediary-%s-v2.tiny", minecraftVersion)); - - if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) { - hasRefreshed = true; - - // Download and extract intermediary - String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion); - String intermediaryArtifactUrl = getExtension().getIntermediaryUrl().apply(encodedMinecraftVersion); - Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar"); - DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger()); - - extractIntermediary(intermediaryJar, intermediaryTiny); - } - } - - return intermediaryTiny; - } - - public String getMappingsKey() { - return mappingsName + "." + minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsVersion; - } - - public File getUnpickDefinitionsFile() { - return unpickDefinitionsFile; - } - - public boolean hasUnpickDefinitions() { - return hasUnpickDefinitions; - } - - public record UnpickMetadata(String unpickGroup, String unpickVersion) { - } + File intermediaryTinyFile(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java new file mode 100644 index 00000000..bea337fc --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -0,0 +1,423 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.function.Consumer; + +import com.google.common.base.Preconditions; +import com.google.common.net.UrlEscapers; +import com.google.gson.JsonObject; +import org.apache.commons.io.FileUtils; +import org.apache.tools.ant.util.StringUtils; +import org.gradle.api.Project; +import org.zeroturnaround.zip.FileSource; +import org.zeroturnaround.zip.ZipEntrySource; +import org.zeroturnaround.zip.ZipUtil; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.configuration.DependencyProvider; +import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; +import net.fabricmc.loom.configuration.processors.JarProcessorManager; +import net.fabricmc.loom.configuration.processors.MinecraftProcessedProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.DeletingFileVisitor; +import net.fabricmc.loom.util.DownloadUtil; +import net.fabricmc.mapping.reader.v2.TinyV2Factory; +import net.fabricmc.mapping.tree.TinyTree; +import net.fabricmc.stitch.Command; +import net.fabricmc.stitch.commands.CommandProposeFieldNames; +import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2; +import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2; + +public class MappingsProviderImpl extends DependencyProvider implements MappingsProvider { + public MinecraftMappedProvider mappedProvider; + + public String mappingsName; + public String minecraftVersion; + public String mappingsVersion; + + private final Path mappingsDir; + private final Path mappingsStepsDir; + private Path intermediaryTiny; + private boolean hasRefreshed = false; + // The mappings that gradle gives us + private Path baseTinyMappings; + // The mappings we use in practice + public File tinyMappings; + public File tinyMappingsJar; + private File unpickDefinitionsFile; + private boolean hasUnpickDefinitions; + private UnpickMetadata unpickMetadata; + + public MappingsProviderImpl(Project project) { + super(project); + mappingsDir = getExtension().getUserCache().toPath().resolve("mappings"); + mappingsStepsDir = mappingsDir.resolve("steps"); + } + + public void clean() throws IOException { + FileUtils.deleteDirectory(mappingsDir.toFile()); + } + + public TinyTree getMappings() throws IOException { + return MappingsCache.INSTANCE.get(tinyMappings.toPath()); + } + + @Override + public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + MinecraftProviderImpl minecraftProvider = getDependencyManager().getProvider(MinecraftProviderImpl.class); + + getProject().getLogger().info(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")"); + + String version = dependency.getResolvedVersion(); + File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find yarn mappings: " + dependency)); + + this.mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged"); + this.minecraftVersion = minecraftProvider.minecraftVersion(); + + boolean isV2; + + // Only do this for official yarn, there isn't really a way we can get the mc version for all mappings + if (dependency.getDependency().getGroup() != null && dependency.getDependency().getGroup().equals("net.fabricmc") && dependency.getDependency().getName().equals("yarn") && dependency.getDependency().getVersion() != null) { + String yarnVersion = dependency.getDependency().getVersion(); + char separator = yarnVersion.contains("+build.") ? '+' : yarnVersion.contains("-") ? '-' : '.'; + String yarnMinecraftVersion = yarnVersion.substring(0, yarnVersion.lastIndexOf(separator)); + + if (!yarnMinecraftVersion.equalsIgnoreCase(minecraftVersion)) { + throw new RuntimeException(String.format("Minecraft Version (%s) does not match yarn's minecraft version (%s)", minecraftVersion, yarnMinecraftVersion)); + } + + // We can save reading the zip file + header by checking the file name + isV2 = mappingsJar.getName().endsWith("-v2.jar"); + } else { + isV2 = doesJarContainV2Mappings(mappingsJar.toPath()); + } + + this.mappingsVersion = version + (isV2 ? "-v2" : ""); + + initFiles(); + + if (isRefreshDeps()) { + cleanFiles(); + } + + Files.createDirectories(mappingsDir); + Files.createDirectories(mappingsStepsDir); + + String[] depStringSplit = dependency.getDepString().split(":"); + String jarClassifier = "final"; + + if (depStringSplit.length >= 4) { + jarClassifier = jarClassifier + depStringSplit[3]; + } + + tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile(); + unpickDefinitionsFile = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".unpick").toFile(); + tinyMappingsJar = new File(getExtension().getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar")); + + if (!tinyMappings.exists() || isRefreshDeps()) { + storeMappings(getProject(), minecraftProvider, mappingsJar.toPath()); + } else { + try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), (ClassLoader) null)) { + extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); + } + } + + if (!tinyMappingsJar.exists() || isRefreshDeps()) { + ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar); + } + + if (hasUnpickDefinitions()) { + String notation = String.format("%s:%s:%s:constants", + dependency.getDependency().getGroup(), + dependency.getDependency().getName(), + dependency.getDependency().getVersion() + ); + + getProject().getDependencies().add(Constants.Configurations.MAPPING_CONSTANTS, notation); + populateUnpickClasspath(); + } + + addDependency(tinyMappingsJar, Constants.Configurations.MAPPINGS_FINAL); + + LoomGradleExtension extension = getExtension(); + + if (extension.accessWidener != null) { + extension.addJarProcessor(new AccessWidenerJarProcessor(getProject())); + } + + JarProcessorManager processorManager = new JarProcessorManager(extension.getJarProcessors()); + extension.setJarProcessorManager(processorManager); + processorManager.setupProcessors(); + + if (processorManager.active()) { + mappedProvider = new MinecraftProcessedProvider(getProject(), processorManager); + getProject().getLogger().lifecycle("Using project based jar storage"); + } else { + mappedProvider = new MinecraftMappedProvider(getProject()); + } + + mappedProvider.initFiles(minecraftProvider, this); + mappedProvider.provide(dependency, postPopulationScheduler); + } + + private void storeMappings(Project project, MinecraftProviderImpl minecraftProvider, Path yarnJar) throws IOException { + project.getLogger().info(":extracting " + yarnJar.getFileName()); + + try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, (ClassLoader) null)) { + extractMappings(fileSystem, baseTinyMappings); + extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); + } + + if (baseMappingsAreV2()) { + // These are unmerged v2 mappings + mergeAndSaveMappings(project, yarnJar); + } else { + // These are merged v1 mappings + if (tinyMappings.exists()) { + tinyMappings.delete(); + } + + project.getLogger().lifecycle(":populating field names"); + suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings.toPath()); + } + } + + private boolean baseMappingsAreV2() throws IOException { + try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) { + TinyV2Factory.readMetadata(reader); + return true; + } catch (IllegalArgumentException e) { + // TODO: just check the mappings version when Parser supports V1 in readMetadata() + return false; + } + } + + private boolean doesJarContainV2Mappings(Path path) throws IOException { + try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { + try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) { + TinyV2Factory.readMetadata(reader); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + } + + public static void extractMappings(FileSystem jar, Path extractTo) throws IOException { + Files.copy(jar.getPath("mappings/mappings.tiny"), extractTo, StandardCopyOption.REPLACE_EXISTING); + } + + private void extractUnpickDefinitions(FileSystem jar, Path extractTo) throws IOException { + Path unpickPath = jar.getPath("extras/definitions.unpick"); + Path unpickMetadataPath = jar.getPath("extras/unpick.json"); + + if (!Files.exists(unpickPath) || !Files.exists(unpickMetadataPath)) { + return; + } + + Files.copy(unpickPath, extractTo, StandardCopyOption.REPLACE_EXISTING); + + unpickMetadata = parseUnpickMetadata(unpickMetadataPath); + hasUnpickDefinitions = true; + } + + private UnpickMetadata parseUnpickMetadata(Path input) throws IOException { + JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(Files.readString(input), JsonObject.class); + + if (!jsonObject.has("version") || jsonObject.get("version").getAsInt() != 1) { + throw new UnsupportedOperationException("Unsupported unpick version"); + } + + return new UnpickMetadata( + jsonObject.get("unpickGroup").getAsString(), + jsonObject.get("unpickVersion").getAsString() + ); + } + + private void populateUnpickClasspath() { + String unpickCliName = "unpick-cli"; + getProject().getDependencies().add(Constants.Configurations.UNPICK_CLASSPATH, + String.format("%s:%s:%s", unpickMetadata.unpickGroup, unpickCliName, unpickMetadata.unpickVersion) + ); + } + + private void extractIntermediary(Path intermediaryJar, Path intermediaryTiny) throws IOException { + getProject().getLogger().info(":extracting " + intermediaryJar.getFileName()); + + try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(intermediaryJar, (ClassLoader) null)) { + extractMappings(unmergedIntermediaryFs, intermediaryTiny); + } + } + + private void mergeAndSaveMappings(Project project, Path unmergedYarnJar) throws IOException { + Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny"); + project.getLogger().info(":extracting " + unmergedYarnJar.getFileName()); + + try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, (ClassLoader) null)) { + extractMappings(unmergedYarnJarFs, unmergedYarn); + } + + Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny"); + reorderMappings(getIntermediaryTiny(), invertedIntermediary, "intermediary", "official"); + Path unorderedMergedMappings = Paths.get(mappingsStepsDir.toString(), "unordered-merged.tiny"); + project.getLogger().info(":merging"); + mergeMappings(invertedIntermediary, unmergedYarn, unorderedMergedMappings); + reorderMappings(unorderedMergedMappings, tinyMappings.toPath(), "official", "intermediary", "named"); + } + + private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) { + Command command = new CommandReorderTinyV2(); + String[] args = new String[2 + newOrder.length]; + args[0] = oldMappings.toAbsolutePath().toString(); + args[1] = newMappings.toAbsolutePath().toString(); + System.arraycopy(newOrder, 0, args, 2, newOrder.length); + runCommand(command, args); + } + + private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) { + try { + Command command = new CommandMergeTinyV2(); + runCommand(command, intermediaryMappings.toAbsolutePath().toString(), + yarnMappings.toAbsolutePath().toString(), + newMergedMappings.toAbsolutePath().toString(), + "intermediary", "official"); + } catch (Exception e) { + throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString() + + " with mappings from " + yarnMappings, e); + } + } + + private void suggestFieldNames(MinecraftProviderImpl minecraftProvider, Path oldMappings, Path newMappings) { + Command command = new CommandProposeFieldNames(); + runCommand(command, minecraftProvider.getMergedJar().getAbsolutePath(), + oldMappings.toAbsolutePath().toString(), + newMappings.toAbsolutePath().toString()); + } + + private void runCommand(Command command, String... args) { + try { + command.run(args); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void initFiles() { + baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base"); + } + + public void cleanFiles() { + try { + if (Files.exists(mappingsStepsDir)) { + Files.walkFileTree(mappingsStepsDir, new DeletingFileVisitor()); + } + + if (Files.exists(baseTinyMappings)) { + Files.deleteIfExists(baseTinyMappings); + } + + if (tinyMappings != null) { + tinyMappings.delete(); + } + + if (tinyMappingsJar != null) { + tinyMappingsJar.delete(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public String getTargetConfig() { + return Constants.Configurations.MAPPINGS; + } + + @Override + public Path getMappingsDir() { + return mappingsDir; + } + + public Path getIntermediaryTiny() throws IOException { + if (intermediaryTiny == null) { + minecraftVersion = getExtension().getMinecraftProvider().minecraftVersion(); + Preconditions.checkNotNull(minecraftVersion, "Minecraft version cannot be null"); + + intermediaryTiny = mappingsDir.resolve(String.format("intermediary-%s-v2.tiny", minecraftVersion)); + + if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) { + hasRefreshed = true; + + // Download and extract intermediary + String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion); + String intermediaryArtifactUrl = getExtension().getIntermediaryUrl().apply(encodedMinecraftVersion); + Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar"); + DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger()); + + extractIntermediary(intermediaryJar, intermediaryTiny); + } + } + + return intermediaryTiny; + } + + public String getMappingsKey() { + return mappingsName + "." + minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsVersion; + } + + public File getUnpickDefinitionsFile() { + return unpickDefinitionsFile; + } + + public boolean hasUnpickDefinitions() { + return hasUnpickDefinitions; + } + + @Override + public File intermediaryTinyFile() { + try { + return getIntermediaryTiny().toFile(); + } catch (IOException e) { + throw new RuntimeException("Failed to get intermediary", e); + } + } + + public record UnpickMetadata(String unpickGroup, String unpickVersion) { + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java new file mode 100644 index 00000000..1666d95c --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsSpec.java @@ -0,0 +1,29 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings; + +public interface MappingsSpec { + L createLayer(MappingContext context); +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java deleted file mode 100644 index 1cd80a45..00000000 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MojangMappingsDependency.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2016, 2017, 2018 FabricMC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package net.fabricmc.loom.configuration.providers.mappings; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.Set; -import java.util.function.Consumer; - -import org.cadixdev.lorenz.MappingSet; -import org.cadixdev.lorenz.io.TextMappingsWriter; -import org.cadixdev.lorenz.io.proguard.ProGuardReader; -import org.cadixdev.lorenz.model.ClassMapping; -import org.cadixdev.lorenz.model.FieldMapping; -import org.cadixdev.lorenz.model.InnerClassMapping; -import org.cadixdev.lorenz.model.MethodMapping; -import org.cadixdev.lorenz.model.TopLevelClassMapping; -import org.gradle.api.Project; -import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.SelfResolvingDependency; -import org.gradle.api.tasks.TaskDependency; -import org.zeroturnaround.zip.ByteSource; -import org.zeroturnaround.zip.ZipEntrySource; -import org.zeroturnaround.zip.ZipUtil; - -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.LoomGradlePlugin; -import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; -import net.fabricmc.loom.util.HashedDownloadUtil; -import net.fabricmc.lorenztiny.TinyMappingsReader; -import net.fabricmc.mapping.tree.TinyMappingFactory; - -public class MojangMappingsDependency implements SelfResolvingDependency { - public static final String GROUP = "net.minecraft"; - public static final String MODULE = "mappings"; - // Keys in dependency manifest - private static final String MANIFEST_CLIENT_MAPPINGS = "client_mappings"; - private static final String MANIFEST_SERVER_MAPPINGS = "server_mappings"; - - private final Project project; - private final LoomGradleExtension extension; - - public MojangMappingsDependency(Project project, LoomGradleExtension extension) { - this.project = project; - this.extension = extension; - } - - @Override - public Set resolve() { - Path mappingsDir = extension.getMappingsProvider().getMappingsDir(); - Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion())); - Path clientMappings = mappingsDir.resolve(String.format("%s.%s-%s-client.map", GROUP, MODULE, getVersion())); - Path serverMappings = mappingsDir.resolve(String.format("%s.%s-%s-server.map", GROUP, MODULE, getVersion())); - - if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) { - MappingSet mappingSet; - - try { - mappingSet = getMappingsSet(clientMappings, serverMappings); - - try (Writer writer = new StringWriter()) { - new TinyWriter(writer, "intermediary", "named").write(mappingSet); - Files.deleteIfExists(mappingsFile); - - ZipUtil.pack(new ZipEntrySource[] { - new ByteSource("mappings/mappings.tiny", writer.toString().getBytes(StandardCharsets.UTF_8)) - }, mappingsFile.toFile()); - } - } catch (IOException e) { - throw new RuntimeException("Failed to resolve Mojang mappings", e); - } - } - - try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8)) { - project.getLogger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); - project.getLogger().warn("Using of the official minecraft mappings is at your own risk!"); - project.getLogger().warn("Please make sure to read and understand the following license:"); - project.getLogger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); - String line; - - while ((line = clientBufferedReader.readLine()).startsWith("#")) { - project.getLogger().warn(line); - } - - project.getLogger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); - } catch (IOException e) { - throw new RuntimeException("Failed to read client mappings", e); - } - - return Collections.singleton(mappingsFile.toFile()); - } - - private MappingSet getMappingsSet(Path clientMappings, Path serverMappings) throws IOException { - MinecraftVersionMeta versionInfo = extension.getMinecraftProvider().getVersionInfo(); - - if (versionInfo.download(MANIFEST_CLIENT_MAPPINGS) == null) { - throw new RuntimeException("Failed to find official mojang mappings for " + getVersion()); - } - - MinecraftVersionMeta.Download clientMappingsDownload = versionInfo.download(MANIFEST_CLIENT_MAPPINGS); - MinecraftVersionMeta.Download serverMappingsDownload = versionInfo.download(MANIFEST_CLIENT_MAPPINGS); - - HashedDownloadUtil.downloadIfInvalid(new URL(clientMappingsDownload.url()), clientMappings.toFile(), clientMappingsDownload.sha1(), project.getLogger(), false); - HashedDownloadUtil.downloadIfInvalid(new URL(serverMappingsDownload.url()), serverMappings.toFile(), clientMappingsDownload.sha1(), project.getLogger(), false); - - MappingSet mappings = MappingSet.create(); - - try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8); - BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings, StandardCharsets.UTF_8)) { - try (ProGuardReader proGuardReaderClient = new ProGuardReader(clientBufferedReader); - ProGuardReader proGuardReaderServer = new ProGuardReader(serverBufferedReader)) { - proGuardReaderClient.read(mappings); - proGuardReaderServer.read(mappings); - } - } - - MappingSet officialToNamed = mappings.reverse(); - MappingSet intermediaryToOfficial; - - try (BufferedReader reader = Files.newBufferedReader(extension.getMappingsProvider().getIntermediaryTiny(), StandardCharsets.UTF_8)) { - intermediaryToOfficial = new TinyMappingsReader(TinyMappingFactory.loadWithDetection(reader), "intermediary", "official").read(); - } - - MappingSet intermediaryToMojang = MappingSet.create(); - - // Merging. Don't use MappingSet#merge - iterateClasses(intermediaryToOfficial, inputMappings -> { - officialToNamed.getClassMapping(inputMappings.getFullDeobfuscatedName()) - .ifPresent(namedClass -> { - ClassMapping mojangClassMapping = intermediaryToMojang.getOrCreateClassMapping(inputMappings.getFullObfuscatedName()) - .setDeobfuscatedName(namedClass.getFullDeobfuscatedName()); - - for (FieldMapping fieldMapping : inputMappings .getFieldMappings()) { - namedClass.getFieldMapping(fieldMapping.getDeobfuscatedName()) - .ifPresent(namedField -> { - mojangClassMapping.getOrCreateFieldMapping(fieldMapping.getSignature()) - .setDeobfuscatedName(namedField.getDeobfuscatedName()); - }); - } - - for (MethodMapping methodMapping : inputMappings .getMethodMappings()) { - namedClass.getMethodMapping(methodMapping.getDeobfuscatedSignature()) - .ifPresent(namedMethod -> { - mojangClassMapping.getOrCreateMethodMapping(methodMapping.getSignature()) - .setDeobfuscatedName(namedMethod.getDeobfuscatedName()); - }); - } - }); - }); - - return intermediaryToMojang; - } - - @Override - public Set resolve(boolean transitive) { - return resolve(); - } - - @Override - public TaskDependency getBuildDependencies() { - return task -> Collections.emptySet(); - } - - @Override - public String getGroup() { - return GROUP; - } - - @Override - public String getName() { - return MODULE; - } - - @Override - public String getVersion() { - return extension.getMinecraftProvider().getMinecraftVersion(); - } - - @Override - public boolean contentEquals(Dependency dependency) { - if (dependency instanceof MojangMappingsDependency mojangMappingsDependency) { - return mojangMappingsDependency.extension.getMinecraftProvider().getMinecraftVersion().equals(getVersion()); - } - - return false; - } - - @Override - public Dependency copy() { - return new MojangMappingsDependency(project, extension); - } - - @Override - public String getReason() { - return null; - } - - @Override - public void because(String s) { - } - - private static void iterateClasses(MappingSet mappings, Consumer> consumer) { - for (TopLevelClassMapping classMapping : mappings.getTopLevelClassMappings()) { - iterateClass(classMapping, consumer); - } - } - - private static void iterateClass(ClassMapping classMapping, Consumer> consumer) { - consumer.accept(classMapping); - - for (InnerClassMapping innerClassMapping : classMapping.getInnerClassMappings()) { - iterateClass(innerClassMapping, consumer); - } - } - - private static class TinyWriter extends TextMappingsWriter { - private final String namespaceFrom; - private final String namespaceTo; - - protected TinyWriter(Writer writer, String namespaceFrom, String namespaceTo) { - super(writer); - this.namespaceFrom = namespaceFrom; - this.namespaceTo = namespaceTo; - } - - @Override - public void write(MappingSet mappings) { - writer.println("tiny\t2\t0\t" + namespaceFrom + "\t" + namespaceTo); - - iterateClasses(mappings, classMapping -> { - writer.println("c\t" + classMapping.getFullObfuscatedName() + "\t" + classMapping.getFullDeobfuscatedName()); - - for (FieldMapping fieldMapping : classMapping.getFieldMappings()) { - fieldMapping.getType().ifPresent(fieldType -> { - writer.println("\tf\t" + fieldType + "\t" + fieldMapping.getObfuscatedName() + "\t" + fieldMapping.getDeobfuscatedName()); - }); - } - - for (MethodMapping methodMapping : classMapping.getMethodMappings()) { - writer.println("\tm\t" + methodMapping.getSignature().getDescriptor() + "\t" + methodMapping.getObfuscatedName() + "\t" + methodMapping.getDeobfuscatedName()); - } - }); - } - } -} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java new file mode 100644 index 00000000..e7fe3938 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingLayer.java @@ -0,0 +1,55 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.intermediary; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Collections; + +import net.fabricmc.loom.configuration.providers.mappings.MappingLayer; +import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace; +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.adapter.MappingNsCompleter; +import net.fabricmc.mappingio.format.Tiny2Reader; + +public record IntermediaryMappingLayer(File tinyFile) implements MappingLayer { + @Override + public MappingNamespace getSourceNamespace() { + return MappingNamespace.OFFICIAL; + } + + @Override + public void visit(MappingVisitor mappingVisitor) throws IOException { + // Populate named with intermediary and add Add a "named" namespace + MappingNsCompleter nsCompleter = new MappingNsCompleter(mappingVisitor, Collections.singletonMap(MappingNamespace.NAMED.stringValue(), MappingNamespace.INTERMEDIARY.stringValue()), true); + + try (BufferedReader reader = Files.newBufferedReader(tinyFile().toPath(), StandardCharsets.UTF_8)) { + Tiny2Reader.read(reader, nsCompleter); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java new file mode 100644 index 00000000..e4c71fda --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/intermediary/IntermediaryMappingsSpec.java @@ -0,0 +1,35 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.intermediary; + +import net.fabricmc.loom.configuration.providers.mappings.MappingContext; +import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec; + +public record IntermediaryMappingsSpec() implements MappingsSpec { + @Override + public IntermediaryMappingLayer createLayer(MappingContext context) { + return new IntermediaryMappingLayer(context.mappingsProvider().intermediaryTinyFile()); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java new file mode 100644 index 00000000..31b5b880 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java @@ -0,0 +1,102 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.mojmap; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import org.gradle.api.logging.Logger; + +import net.fabricmc.loom.configuration.providers.mappings.MappingLayer; +import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingLayer; +import net.fabricmc.loom.util.HashedDownloadUtil; +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.format.ProGuardReader; + +public record MojangMappingLayer(MinecraftVersionMeta.Download clientDownload, + MinecraftVersionMeta.Download serverDownload, + File workingDir, + Logger logger) implements MappingLayer { + @Override + public void visit(MappingVisitor mappingVisitor) throws IOException { + var clientMappings = new File(workingDir(), "client.txt"); + var serverMappings = new File(workingDir(), "server.txt"); + + download(clientMappings, serverMappings); + + printMappingsLicense(clientMappings.toPath()); + + // Make official the source namespace + MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingVisitor, MappingNamespace.OFFICIAL.stringValue()); + + try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings.toPath(), StandardCharsets.UTF_8); + BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings.toPath(), StandardCharsets.UTF_8)) { + ProGuardReader.read(clientBufferedReader, MappingNamespace.NAMED.stringValue(), MappingNamespace.OFFICIAL.stringValue(), nsSwitch); + ProGuardReader.read(serverBufferedReader, MappingNamespace.NAMED.stringValue(), MappingNamespace.OFFICIAL.stringValue(), nsSwitch); + } + } + + private void download(File clientMappings, File serverMappings) throws IOException { + HashedDownloadUtil.downloadIfInvalid(new URL(clientDownload().url()), clientMappings, clientDownload().sha1(), logger(), false); + HashedDownloadUtil.downloadIfInvalid(new URL(serverDownload().url()), serverMappings, serverDownload().sha1(), logger(), false); + } + + private void printMappingsLicense(Path clientMappings) { + try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8)) { + logger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + logger().warn("Using of the official minecraft mappings is at your own risk!"); + logger().warn("Please make sure to read and understand the following license:"); + logger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + String line; + + while ((line = clientBufferedReader.readLine()).startsWith("#")) { + logger().warn(line); + } + + logger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + } catch (IOException e) { + throw new RuntimeException("Failed to read client mappings", e); + } + } + + @Override + public MappingNamespace getSourceNamespace() { + return MappingNamespace.OFFICIAL; + } + + @Override + public List> dependsOn() { + return List.of(IntermediaryMappingLayer.class); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java new file mode 100644 index 00000000..78cfc026 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java @@ -0,0 +1,51 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.mojmap; + +import net.fabricmc.loom.configuration.providers.mappings.MappingContext; +import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; + +public record MojangMappingsSpec() implements MappingsSpec { + // Keys in dependency manifest + private static final String MANIFEST_CLIENT_MAPPINGS = "client_mappings"; + private static final String MANIFEST_SERVER_MAPPINGS = "server_mappings"; + + @Override + public MojangMappingLayer createLayer(MappingContext context) { + MinecraftVersionMeta versionInfo = context.minecraftProvider().getVersionInfo(); + + if (versionInfo.download(MANIFEST_CLIENT_MAPPINGS) == null) { + throw new RuntimeException("Failed to find official mojang mappings for " + context.minecraftVersion()); + } + + return new MojangMappingLayer( + versionInfo.download(MANIFEST_CLIENT_MAPPINGS), + versionInfo.download(MANIFEST_SERVER_MAPPINGS), + context.workingDirectory("mojang"), + context.getLogger() + ); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java new file mode 100644 index 00000000..70764234 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingLayer.java @@ -0,0 +1,63 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.parchment; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Objects; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.configuration.providers.mappings.MappingLayer; +import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace; +import net.fabricmc.mappingio.MappingVisitor; + +public record ParchmentMappingLayer(File parchmentFile, boolean removePrefix) implements MappingLayer { + private static final String PARCHMENT_DATA_FILE_NAME = "parchment.json"; + + @Override + public void visit(MappingVisitor mappingVisitor) throws IOException { + ParchmentTreeV1 parchmentData = getParchmentData(); + + if (removePrefix()) { + mappingVisitor = new ParchmentPrefixStripingMappingVisitor(mappingVisitor); + } + + parchmentData.visit(mappingVisitor, MappingNamespace.NAMED.stringValue()); + } + + private ParchmentTreeV1 getParchmentData() throws IOException { + try (var zipFile = new ZipFile(parchmentFile())) { + ZipEntry zipFileEntry = zipFile.getEntry(PARCHMENT_DATA_FILE_NAME); + Objects.requireNonNull(zipFileEntry, "Could not find %s in parchment data file".formatted(PARCHMENT_DATA_FILE_NAME)); + + try (var reader = new InputStreamReader(zipFile.getInputStream(zipFileEntry))) { + return LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, ParchmentTreeV1.class); + } + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java new file mode 100644 index 00000000..efec61c2 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpec.java @@ -0,0 +1,35 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.parchment; + +import net.fabricmc.loom.configuration.providers.mappings.MappingContext; +import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec; + +public record ParchmentMappingsSpec(String mavenNotation, boolean removePrefix) implements MappingsSpec { + @Override + public ParchmentMappingLayer createLayer(MappingContext context) { + return new ParchmentMappingLayer(context.mavenFile(mavenNotation()), removePrefix()); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java new file mode 100644 index 00000000..808e077c --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentMappingsSpecBuilder.java @@ -0,0 +1,48 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.parchment; + +public class ParchmentMappingsSpecBuilder { + private final String mavenNotation; + + private boolean removePrefix; + + private ParchmentMappingsSpecBuilder(String mavenNotation) { + this.mavenNotation = mavenNotation; + } + + public static ParchmentMappingsSpecBuilder builder(String depNotation) { + return new ParchmentMappingsSpecBuilder(depNotation); + } + + public ParchmentMappingsSpecBuilder setRemovePrefix(boolean removePrefix) { + this.removePrefix = removePrefix; + return this; + } + + public ParchmentMappingsSpec build() { + return new ParchmentMappingsSpec(mavenNotation, removePrefix); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentPrefixStripingMappingVisitor.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentPrefixStripingMappingVisitor.java new file mode 100644 index 00000000..6280a5f0 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentPrefixStripingMappingVisitor.java @@ -0,0 +1,50 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.parchment; + +import java.util.Locale; + +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.adapter.ForwardingMappingVisitor; + +public final class ParchmentPrefixStripingMappingVisitor extends ForwardingMappingVisitor { + protected ParchmentPrefixStripingMappingVisitor(MappingVisitor next) { + super(next); + } + + @Override + public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) { + return super.visitMethodArg(argPosition, lvIndex, stripMethodArg(srcName)); + } + + public static String stripMethodArg(String arg) { + if (arg.length() > 1 && arg.startsWith("p") && Character.isUpperCase(arg.charAt(1))) { + String a2 = arg.substring(1); // Remove p + return a2.substring(0, 1).toLowerCase(Locale.ROOT) + a2.substring(1); // Make first char lowercase + } + + return arg; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentTreeV1.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentTreeV1.java new file mode 100644 index 00000000..6d9c1a6c --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/parchment/ParchmentTreeV1.java @@ -0,0 +1,165 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.parchment; + +import java.util.Collections; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.MappingVisitor; + +public record ParchmentTreeV1( + String version, + @Nullable + List classes, + @Nullable + List packages +) { + public void visit(MappingVisitor visitor, String srcNamespace) { + while (true) { + if (visitor.visitHeader()) { + visitor.visitNamespaces(srcNamespace, Collections.emptyList()); + } + + if (visitor.visitContent()) { + if (classes() != null) { + for (Class c : classes()) { + c.visit(visitor); + } + } + } + + if (visitor.visitEnd()) { + break; + } + } + } + + public record Class( + String name, + @Nullable + List fields, + @Nullable + List methods, + @Nullable + List javadoc + ) { + public void visit(MappingVisitor visitor) { + if (visitor.visitClass(name())) { + if (!visitor.visitElementContent(MappedElementKind.CLASS)) { + return; + } + + if (fields() != null) { + for (Field field : fields()) { + field.visit(visitor); + } + } + + if (methods() != null) { + for (Method method : methods()) { + method.visit(visitor); + } + } + + if (javadoc() != null) { + visitor.visitComment(MappedElementKind.CLASS, String.join("\n", javadoc())); + } + } + } + } + + public record Field( + String name, + String descriptor, + @Nullable + List javadoc + ) { + public void visit(MappingVisitor visitor) { + if (visitor.visitField(name, descriptor)) { + if (!visitor.visitElementContent(MappedElementKind.FIELD)) { + return; + } + + if (javadoc() != null) { + visitor.visitComment(MappedElementKind.FIELD, String.join("\n", javadoc())); + } + } + } + } + + public record Method( + String name, + String descriptor, + @Nullable + List parameters, + @Nullable + List javadoc + ) { + public void visit(MappingVisitor visitor) { + if (visitor.visitMethod(name, descriptor)) { + if (!visitor.visitElementContent(MappedElementKind.METHOD)) { + return; + } + + if (parameters() != null) { + for (Parameter parameter : parameters()) { + parameter.visit(visitor); + } + } + + if (javadoc() != null) { + visitor.visitComment(MappedElementKind.METHOD, String.join("\n", javadoc())); + } + } + } + } + + public record Parameter( + int index, + String name, + @Nullable + String javadoc + ) { + public void visit(MappingVisitor visitor) { + if (visitor.visitMethodArg(index, index, name)) { + if (!visitor.visitElementContent(MappedElementKind.METHOD_ARG)) { + return; + } + + if (javadoc() != null) { + visitor.visitComment(MappedElementKind.METHOD_ARG, javadoc); + } + } + } + } + + public record Package( + String name, + List javadoc + ) { } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java index 130df4d8..bfb42d74 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java @@ -29,13 +29,13 @@ import java.io.File; import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; import net.fabricmc.loom.util.Constants; public class MinecraftLibraryProvider { public File MINECRAFT_LIBS; - public void provide(MinecraftProvider minecraftProvider, Project project) { + public void provide(MinecraftProviderImpl minecraftProvider, Project project) { MinecraftVersionMeta versionInfo = minecraftProvider.getVersionInfo(); initFiles(project, minecraftProvider); @@ -47,7 +47,7 @@ public class MinecraftLibraryProvider { } } - private void initFiles(Project project, MinecraftProvider minecraftProvider) { + private void initFiles(Project project, MinecraftProviderImpl minecraftProvider) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MINECRAFT_LIBS = new File(extension.getUserCache(), "libraries"); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java index a2718090..1ca7179d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java @@ -36,8 +36,8 @@ import com.google.common.collect.ImmutableMap; import org.gradle.api.Project; import net.fabricmc.loom.configuration.DependencyProvider; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.TinyRemapperMappingsHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; @@ -53,7 +53,7 @@ public class MinecraftMappedProvider extends DependencyProvider { private File minecraftMappedJar; private File minecraftIntermediaryJar; - private MinecraftProvider minecraftProvider; + private MinecraftProviderImpl minecraftProvider; public MinecraftMappedProvider(Project project) { super(project); @@ -101,7 +101,7 @@ public class MinecraftMappedProvider extends DependencyProvider { private void mapMinecraftJar() throws IOException { String fromM = "official"; - MappingsProvider mappingsProvider = getExtension().getMappingsProvider(); + MappingsProviderImpl mappingsProvider = getExtension().getMappingsProvider(); Path input = minecraftProvider.getMergedJar().toPath(); Path outputMapped = minecraftMappedJar.toPath(); @@ -148,7 +148,7 @@ public class MinecraftMappedProvider extends DependencyProvider { getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString("mapped"))); } - public void initFiles(MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) { + public void initFiles(MinecraftProviderImpl minecraftProvider, MappingsProviderImpl mappingsProvider) { this.minecraftProvider = minecraftProvider; minecraftIntermediaryJar = new File(getExtension().getUserCache(), "minecraft-" + getJarVersionString("intermediary") + ".jar"); minecraftMappedJar = new File(getJarDirectory(getExtension().getUserCache(), "mapped"), "minecraft-" + getJarVersionString("mapped") + ".jar"); @@ -159,7 +159,7 @@ public class MinecraftMappedProvider extends DependencyProvider { } protected String getJarVersionString(String type) { - return String.format("%s-%s-%s-%s", minecraftProvider.getMinecraftVersion(), type, getExtension().getMappingsProvider().mappingsName, getExtension().getMappingsProvider().mappingsVersion); + return String.format("%s-%s-%s-%s", minecraftProvider.minecraftVersion(), type, getExtension().getMappingsProvider().mappingsName, getExtension().getMappingsProvider().mappingsVersion); } public File getIntermediaryJar() { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/assets/MinecraftAssetsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/assets/MinecraftAssetsProvider.java index fd1ad733..566e924b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/assets/MinecraftAssetsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/assets/MinecraftAssetsProvider.java @@ -41,14 +41,14 @@ import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.HashedDownloadUtil; import net.fabricmc.loom.util.gradle.ProgressLogger; public class MinecraftAssetsProvider { - public static void provide(MinecraftProvider minecraftProvider, Project project) throws IOException { + public static void provide(MinecraftProviderImpl minecraftProvider, Project project) throws IOException { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); boolean offline = project.getGradle().getStartParameter().isOffline(); @@ -62,7 +62,7 @@ public class MinecraftAssetsProvider { assets.mkdirs(); } - File assetsInfo = new File(assets, "indexes" + File.separator + assetIndex.fabricId(minecraftProvider.getMinecraftVersion()) + ".json"); + File assetsInfo = new File(assets, "indexes" + File.separator + assetIndex.fabricId(minecraftProvider.minecraftVersion()) + ".json"); project.getLogger().info(":downloading asset index"); diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index 25d6fe47..2c2b3ce8 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -41,7 +41,7 @@ import org.gradle.api.tasks.TaskAction; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.decompilers.DecompilationMetadata; import net.fabricmc.loom.api.decompilers.LoomDecompiler; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.decompilers.LineNumberRemapper; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.gradle.ProgressLogger; @@ -102,7 +102,7 @@ public class GenerateSourcesTask extends AbstractLoomTask { private File getMappedJarFileWithSuffix(String suffix) { LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class); - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); File mappedJar = mappingsProvider.mappedProvider.getMappedJar(); String path = mappedJar.getAbsolutePath(); diff --git a/src/main/java/net/fabricmc/loom/task/LoomTasks.java b/src/main/java/net/fabricmc/loom/task/LoomTasks.java index 1b1de6a7..b9221f8b 100644 --- a/src/main/java/net/fabricmc/loom/task/LoomTasks.java +++ b/src/main/java/net/fabricmc/loom/task/LoomTasks.java @@ -33,7 +33,7 @@ import org.gradle.api.tasks.TaskContainer; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.decompilers.LoomDecompiler; import net.fabricmc.loom.configuration.ide.RunConfigSettings; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.decompilers.fernflower.FabricFernFlowerDecompiler; public final class LoomTasks { @@ -113,7 +113,7 @@ public final class LoomTasks { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); project.afterEvaluate(p -> { - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); File inputJar = mappingsProvider.mappedProvider.getMappedJar(); if (mappingsProvider.hasUnpickDefinitions()) { diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index 97217fcb..6151f932 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -49,9 +49,10 @@ import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.options.Option; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; -import net.fabricmc.loom.configuration.providers.mappings.MojangMappingsDependency; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder; +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency; import net.fabricmc.loom.util.SourceRemapper; import net.fabricmc.lorenztiny.TinyMappingsJoiner; import net.fabricmc.mapping.tree.TinyMappingFactory; @@ -96,7 +97,7 @@ public class MigrateMappingsTask extends AbstractLoomTask { Files.createDirectories(outputDir); File mappings = loadMappings(); - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); try { TinyTree currentMappings = mappingsProvider.getMappings(); @@ -118,12 +119,13 @@ public class MigrateMappingsTask extends AbstractLoomTask { Set files; try { - if (mappings.startsWith(MojangMappingsDependency.GROUP + ':' + MojangMappingsDependency.MODULE + ':') || mappings.startsWith("net.mojang.minecraft:mappings:")) { - if (!mappings.endsWith(":" + project.getExtensions().getByType(LoomGradleExtension.class).getMinecraftProvider().getMinecraftVersion())) { + if (mappings.startsWith("net.minecraft:mappings:") || mappings.startsWith("net.mojang.minecraft:mappings:")) { + if (!mappings.endsWith(":" + project.getExtensions().getByType(LoomGradleExtension.class).getMinecraftProvider().minecraftVersion())) { throw new UnsupportedOperationException("Migrating Mojang mappings is currently only supported for the specified minecraft version"); } - files = new MojangMappingsDependency(project, getExtension()).resolve(); + LayeredMappingsDependency dep = (LayeredMappingsDependency) getExtension().layered(LayeredMappingSpecBuilder::officalMojangMappings); + files = dep.resolve(); } else { Dependency dependency = project.getDependencies().create(mappings); files = project.getConfigurations().detachedConfiguration(dependency).resolve(); diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index 79e2f231..cc0ff755 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -58,7 +58,7 @@ import net.fabricmc.loom.build.nesting.MergedNestedJarProvider; import net.fabricmc.loom.build.nesting.NestedDependencyProvider; import net.fabricmc.loom.build.nesting.NestedJarProvider; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.TinyRemapperMappingsHelper; import net.fabricmc.loom.util.ZipReprocessorUtil; @@ -113,7 +113,7 @@ public class RemapJarTask extends Jar { throw new FileNotFoundException(input.toString()); } - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); String fromM = "named"; String toM = "intermediary"; diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index ed4957a5..1e3eb801 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -44,7 +44,7 @@ import org.zeroturnaround.zip.ZipUtil; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.configuration.RemappedConfigurationEntry; import net.fabricmc.loom.configuration.providers.LaunchProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.gradle.ProgressLogger; import net.fabricmc.lorenztiny.TinyMappingsReader; import net.fabricmc.mapping.tree.TinyTree; @@ -163,7 +163,7 @@ public class SourceRemapper { } LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> { try { diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/DependencyResolutionManagementTest.groovy similarity index 100% rename from src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy rename to src/test/groovy/net/fabricmc/loom/test/integration/DependencyResolutionManagementTest.groovy diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/ParchmentTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/ParchmentTest.groovy new file mode 100644 index 00000000..836ba58a --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/ParchmentTest.groovy @@ -0,0 +1,52 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.integration + +import net.fabricmc.loom.test.util.ProjectTestTrait +import spock.lang.Specification +import spock.lang.Unroll + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class ParchmentTest extends Specification implements ProjectTestTrait { + @Override + String name() { + "parchment" + } + + @Unroll + def "parchment #gradle"() { + when: + def result = create("build", gradle) + + then: + result.task(":build").outcome == SUCCESS + + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy new file mode 100644 index 00000000..3184ceb9 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy @@ -0,0 +1,43 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec + +class IntermediaryMappingLayerTest extends LayeredMappingsSpecification { + def "Read intermediary mappings" () { + setup: + mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_17_URL, "intermediary.jar"), "mappings/mappings.tiny") + when: + def mappings = getSingleMapping(new IntermediaryMappingsSpec()) + def tiny = getTiny(mappings) + then: + mappings.srcNamespace == "official" + mappings.dstNamespaces == ["intermediary", "named"] + mappings.classes.size() == 6107 + mappings.getClass("abc").getDstName(0) == "net/minecraft/class_3191" + mappings.getClass("abc").getDstName(1) == "net/minecraft/class_3191" + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy new file mode 100644 index 00000000..035ac11e --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy @@ -0,0 +1,118 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec +import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec +import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec +import org.gradle.api.Action +import org.gradle.util.ConfigureUtil +import spock.lang.Specification + +class LayeredMappingSpecBuilderTest extends Specification { + def "simple mojmap" () { + when: + def spec = layered() { + officalMojangMappings() + } + def layers = spec.layers() + then: + spec.version == "layered+hash.961" + layers.size() == 2 + layers[0].class == IntermediaryMappingsSpec + layers[1].class == MojangMappingsSpec + } + + def "simple mojmap with parchment" () { + when: + def spec = layered() { + officalMojangMappings() + parchment("I like cake") + } + def layers = spec.layers() + def parchment = layers[2] as ParchmentMappingsSpec + then: + spec.version == "layered+hash.863714404" + layers.size() == 3 + layers[0].class == IntermediaryMappingsSpec + layers[1].class == MojangMappingsSpec + layers[2].class == ParchmentMappingsSpec + parchment.mavenNotation() == "I like cake" + parchment.removePrefix() == true + } + + def "simple mojmap with parchment keep prefix" () { + when: + def spec = layered() { + officalMojangMappings() + parchment("I like cake") { + it.removePrefix = false + } + } + def layers = spec.layers() + def parchment = layers[2] as ParchmentMappingsSpec + then: + spec.version == "layered+hash.863714410" + layers.size() == 3 + layers[0].class == IntermediaryMappingsSpec + layers[1].class == MojangMappingsSpec + layers[2].class == ParchmentMappingsSpec + parchment.mavenNotation() == "I like cake" + parchment.removePrefix() == false + } + + def "simple mojmap with parchment keep prefix alternate hash" () { + when: + def spec = layered() { + officalMojangMappings() + parchment("I really like cake") { + it.removePrefix = false + } + } + def layers = spec.layers() + def parchment = layers[2] as ParchmentMappingsSpec + then: + spec.version == "layered+hash.1144465487" + layers.size() == 3 + layers[0].class == IntermediaryMappingsSpec + layers[1].class == MojangMappingsSpec + layers[2].class == ParchmentMappingsSpec + parchment.mavenNotation() == "I really like cake" + parchment.removePrefix() == false + } + + // Gradle does this big of magic behind the scenes + LayeredMappingSpec layered(@DelegatesTo(LayeredMappingSpecBuilder) Closure cl) { + return layeredAction(ConfigureUtil.configureUsing(cl)) + } + + LayeredMappingSpec layeredAction(Action action) { + LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder() + action.execute(builder) + return builder.build() + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy new file mode 100644 index 00000000..8fa26b34 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy @@ -0,0 +1,121 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import groovy.transform.CompileStatic +import net.fabricmc.loom.configuration.providers.MinecraftProvider +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor +import net.fabricmc.loom.configuration.providers.mappings.MappingContext +import net.fabricmc.loom.configuration.providers.mappings.MappingLayer +import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider +import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec +import net.fabricmc.mappingio.format.Tiny2Writer +import net.fabricmc.mappingio.tree.MappingTree +import net.fabricmc.mappingio.tree.MemoryMappingTree +import org.gradle.api.logging.Logger +import spock.lang.Specification + +import java.util.zip.ZipFile + +abstract class LayeredMappingsSpecification extends Specification implements LayeredMappingsTestConstants { + Logger mockLogger = Mock(Logger) + MappingsProvider mockMappingsProvider = Mock(MappingsProvider) + MinecraftProvider mockMinecraftProvider = Mock(MinecraftProvider) + + MappingContext mappingContext = new TestMappingContext() + + File tempDir = File.createTempDir() + + Map mavenFiles = [:] + + def withMavenFile(String mavenNotation, File file) { + mavenFiles.put(mavenNotation, file) + } + + File downloadFile(String url, String name) { + File dst = new File(tempDir, name) + dst.parentFile.mkdirs() + dst << new URL(url).newInputStream() + return dst + } + + File extractFileFromZip(File zipFile, String name) { + File dst = new File(tempDir, name) + dst.parentFile.mkdirs() + + new ZipFile(zipFile).withCloseable { + dst << it.getInputStream(it.getEntry(name)) + } + return dst + } + + MemoryMappingTree getSingleMapping(MappingsSpec spec) { + MemoryMappingTree mappingTree = new MemoryMappingTree() + spec.createLayer(mappingContext).visit(mappingTree) + return mappingTree + } + + MemoryMappingTree getLayeredMappings(MappingsSpec... specs) { + LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList()) + LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec) + return processor.getMappings(mappingContext) + } + + String getTiny(MemoryMappingTree mappingTree) { + def sw = new StringWriter() + mappingTree.accept(new Tiny2Writer(sw, false)) + return sw.toString() + } + + @CompileStatic + class TestMappingContext implements MappingContext { + @Override + File mavenFile(String mavenNotation) { + assert mavenFiles.containsKey(mavenNotation) + return mavenFiles.get(mavenNotation) + } + + @Override + MappingsProvider mappingsProvider() { + return mockMappingsProvider + } + + @Override + MinecraftProvider minecraftProvider() { + return mockMinecraftProvider + } + + @Override + File workingDirectory(String name) { + return new File(tempDir, name) + } + + @Override + Logger getLogger() { + return mockLogger + } + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsTestConstants.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsTestConstants.groovy new file mode 100644 index 00000000..1827ccd6 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsTestConstants.groovy @@ -0,0 +1,47 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta + +interface LayeredMappingsTestConstants { + public static final String INTERMEDIARY_1_17_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.17/intermediary-1.17-v2.jar" + public static final String INTERMEDIARY_1_16_5_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.16.5/intermediary-1.16.5-v2.jar" + + public static final Map DOWNLOADS_1_17 = [ + client_mappings:new MinecraftVersionMeta.Download(null, "227d16f520848747a59bef6f490ae19dc290a804", 6431705, "https://launcher.mojang.com/v1/objects/227d16f520848747a59bef6f490ae19dc290a804/client.txt"), + server_mappings:new MinecraftVersionMeta.Download(null, "84d80036e14bc5c7894a4fad9dd9f367d3000334", 4948536, "https://launcher.mojang.com/v1/objects/84d80036e14bc5c7894a4fad9dd9f367d3000334/server.txt") + ] + public static final MinecraftVersionMeta VERSION_META_1_17 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_17, null, null, null, null, 0, null, null, null) + + public static final Map DOWNLOADS_1_16_5 = [ + client_mappings:new MinecraftVersionMeta.Download(null, "e3dfb0001e1079a1af72ee21517330edf52e6192", 5746047, "https://launcher.mojang.com/v1/objects/e3dfb0001e1079a1af72ee21517330edf52e6192/client.txt"), + server_mappings:new MinecraftVersionMeta.Download(null, "81d5c793695d8cde63afddb40dde88e3a88132ac", 4400926, "https://launcher.mojang.com/v1/objects/81d5c793695d8cde63afddb40dde88e3a88132ac/server.txt") + ] + public static final MinecraftVersionMeta VERSION_META_1_16_5 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_16_5, null, null, null, null, 0, null, null, null) + + public static final String PARCHMENT_NOTATION = "org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip" + public static final String PARCHMENT_URL = "https://ldtteam.jfrog.io/artifactory/parchmentmc-snapshots/org/parchmentmc/data/parchment-1.16.5/20210608-SNAPSHOT/parchment-1.16.5-20210608-SNAPSHOT.zip" +} \ No newline at end of file diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy new file mode 100644 index 00000000..28e058dd --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy @@ -0,0 +1,49 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec +import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec + +class MojangMappingLayerTest extends LayeredMappingsSpecification { + def "Read mojang mappings" () { + setup: + mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_17_URL, "intermediary.jar"), "mappings/mappings.tiny") + mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17 + when: + def mappings = getLayeredMappings( + new IntermediaryMappingsSpec(), + new MojangMappingsSpec() + ) + def tiny = getTiny(mappings) + then: + mappings.srcNamespace == "named" + mappings.dstNamespaces == ["intermediary", "official"] + mappings.classes.size() == 6113 + mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash + mappings.classes[0].getDstName(0) == "net/minecraft/class_2354" + mappings.classes[0].methods[0].args.size() == 0 // No Args + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy new file mode 100644 index 00000000..597e17f6 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy @@ -0,0 +1,74 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec +import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec +import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta + +class ParchmentMappingLayerTest extends LayeredMappingsSpecification { + def "Read parchment mappings" () { + setup: + mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_16_5_URL, "intermediary.jar"), "mappings/mappings.tiny") + mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5 + when: + withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip")) + def mappings = getLayeredMappings( + new IntermediaryMappingsSpec(), + new MojangMappingsSpec(), + new ParchmentMappingsSpec(PARCHMENT_NOTATION, false) + ) + def tiny = getTiny(mappings) + then: + mappings.srcNamespace == "named" + mappings.dstNamespaces == ["intermediary", "official"] + mappings.classes.size() == 5747 + mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash + mappings.classes[0].getDstName(0) == "net/minecraft/class_2573" + mappings.classes[0].methods[0].args[0].srcName == "pStack" + } + + def "Read parchment mappings remove prefix" () { + setup: + mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_16_5_URL, "intermediary.jar"), "mappings/mappings.tiny") + mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5 + when: + withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip")) + def mappings = getLayeredMappings( + new IntermediaryMappingsSpec(), + new MojangMappingsSpec(), + new ParchmentMappingsSpec(PARCHMENT_NOTATION, true) + ) + def tiny = getTiny(mappings) + then: + mappings.srcNamespace == "named" + mappings.dstNamespaces == ["intermediary", "official"] + mappings.classes.size() == 5747 + mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash + mappings.classes[0].getDstName(0) == "net/minecraft/class_2573" + mappings.classes[0].methods[0].args[0].srcName == "stack" + } +} diff --git a/src/test/resources/projects/parchment/build.gradle b/src/test/resources/projects/parchment/build.gradle new file mode 100644 index 00000000..255e98e0 --- /dev/null +++ b/src/test/resources/projects/parchment/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'fabric-loom' +} + +repositories { + maven { + name = "ldtteam" + url = "https://ldtteam.jfrog.io/artifactory/parchmentmc-snapshots/" + } +} + +dependencies { + minecraft "com.mojang:minecraft:1.16.5" + mappings loom.layered() { + officalMojangMappings() + parchment("org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip") + } + + modImplementation "net.fabricmc:fabric-loader:0.11.3" +} From b4cd38a287196fda82b7323ba1d601a517a93c8f Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 16 Jun 2021 19:16:47 +0100 Subject: [PATCH 29/56] Ensure deps are reproducible. This prevents them from being updated without us knowing. --- build.gradle | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3e4cb362..f64dbc30 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,12 @@ configurations { testRuntimeClasspath.extendsFrom bootstrap } +configurations.all { + resolutionStrategy { + failOnNonReproducibleResolution() + } +} + dependencies { implementation gradleApi() @@ -87,7 +93,27 @@ dependencies { implementation ('org.benf:cfr:0.151') // source code remapping - implementation ('org.cadixdev:mercury:0.1.0-rc1') + implementation ('org.cadixdev:mercury:[0.1.0-rc1]') + + // Mercury pulls all of these deps in, however eclipse does not specify the exact version to use so they can get updated without us knowing. + // Depend specifically on these versions to prevent them from being updated under our feet. + implementation ('org.eclipse.jdt:org.eclipse.jdt.core:[3.21.0]') + implementation ('org.eclipse.platform:org.eclipse.compare.core:[3.6.1000]') + implementation ('org.eclipse.platform:org.eclipse.core.commands:[3.9.800]') + implementation ('org.eclipse.platform:org.eclipse.core.contenttype:[3.7.900]') + implementation ('org.eclipse.platform:org.eclipse.core.expressions:[3.7.100]') + implementation ('org.eclipse.platform:org.eclipse.core.filesystem:[1.7.700]') + implementation ('org.eclipse.platform:org.eclipse.core.jobs:[3.10.1100]') + implementation ('org.eclipse.platform:org.eclipse.core.resources:[3.14.0]') + implementation ('org.eclipse.platform:org.eclipse.core.runtime:[3.20.100]') + implementation ('org.eclipse.platform:org.eclipse.equinox.app:[1.5.100]') + implementation ('org.eclipse.platform:org.eclipse.equinox.common:[3.14.100]') + implementation ('org.eclipse.platform:org.eclipse.equinox.preferences:[3.8.200]') + implementation ('org.eclipse.platform:org.eclipse.equinox.registry:[3.10.100]') + implementation ('org.eclipse.platform:org.eclipse.osgi:[3.16.200]') + implementation ('org.eclipse.platform:org.eclipse.team.core:[3.8.1100]') + implementation ('org.eclipse.platform:org.eclipse.text:[3.11.0]') + // Kapt integration compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0') From 147af48879c725f422b99ea15a9e6f3ce1a496f3 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 16 Jun 2021 23:16:44 +0100 Subject: [PATCH 30/56] Patch all eclipse deps to use a strict version --- build.gradle | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/build.gradle b/build.gradle index f64dbc30..a7e766fc 100644 --- a/build.gradle +++ b/build.gradle @@ -97,6 +97,7 @@ dependencies { // Mercury pulls all of these deps in, however eclipse does not specify the exact version to use so they can get updated without us knowing. // Depend specifically on these versions to prevent them from being updated under our feet. + // The POM is also patched later on to as this strict versioning does not make it through. implementation ('org.eclipse.jdt:org.eclipse.jdt.core:[3.21.0]') implementation ('org.eclipse.platform:org.eclipse.compare.core:[3.6.1000]') implementation ('org.eclipse.platform:org.eclipse.core.commands:[3.9.800]') @@ -196,6 +197,18 @@ import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node +def patchPom(groovy.util.Node node) { + node.dependencies.first().each { + def groupId = it.get("groupId").first().value().first() + + // Patch all eclipse deps to use a strict version + if (groupId.startsWith("org.eclipse.")) { + def version = it.get("version").first().value().first() + it.get("version").first().value = new groovy.util.NodeList(["[$version]"]) + } + } +} + publishing { publications { plugin(MavenPublication) { publication -> @@ -207,6 +220,10 @@ publishing { artifact sourcesJar artifact javadocJar + + pom.withXml { + patchPom(asNode()) + } } // Also publish a snapshot so people can use the latest version if they wish @@ -219,6 +236,10 @@ publishing { artifact sourcesJar artifact javadocJar + + pom.withXml { + patchPom(asNode()) + } } // Manually crate the plugin marker for snapshot versions From 74088b2ad4865bd0d06516414091f5e098b6313f Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 16 Jun 2021 19:16:47 +0100 Subject: [PATCH 31/56] Ensure deps are reproducible. This prevents them from being updated without us knowing. --- build.gradle | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ff50ae2b..9b66773f 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,12 @@ configurations { runtimeClasspath.extendsFrom bootstrap } +configurations.all { + resolutionStrategy { + failOnNonReproducibleResolution() + } +} + dependencies { implementation gradleApi() @@ -85,7 +91,27 @@ dependencies { implementation ('org.benf:cfr:0.151') // source code remapping - implementation ('org.cadixdev:mercury:0.1.0-rc1') + implementation ('org.cadixdev:mercury:[0.1.0-rc1]') + + // Mercury pulls all of these deps in, however eclipse does not specify the exact version to use so they can get updated without us knowing. + // Depend specifically on these versions to prevent them from being updated under our feet. + implementation ('org.eclipse.jdt:org.eclipse.jdt.core:[3.21.0]') + implementation ('org.eclipse.platform:org.eclipse.compare.core:[3.6.1000]') + implementation ('org.eclipse.platform:org.eclipse.core.commands:[3.9.800]') + implementation ('org.eclipse.platform:org.eclipse.core.contenttype:[3.7.900]') + implementation ('org.eclipse.platform:org.eclipse.core.expressions:[3.7.100]') + implementation ('org.eclipse.platform:org.eclipse.core.filesystem:[1.7.700]') + implementation ('org.eclipse.platform:org.eclipse.core.jobs:[3.10.1100]') + implementation ('org.eclipse.platform:org.eclipse.core.resources:[3.14.0]') + implementation ('org.eclipse.platform:org.eclipse.core.runtime:[3.20.100]') + implementation ('org.eclipse.platform:org.eclipse.equinox.app:[1.5.100]') + implementation ('org.eclipse.platform:org.eclipse.equinox.common:[3.14.100]') + implementation ('org.eclipse.platform:org.eclipse.equinox.preferences:[3.8.200]') + implementation ('org.eclipse.platform:org.eclipse.equinox.registry:[3.10.100]') + implementation ('org.eclipse.platform:org.eclipse.osgi:[3.16.200]') + implementation ('org.eclipse.platform:org.eclipse.team.core:[3.8.1100]') + implementation ('org.eclipse.platform:org.eclipse.text:[3.11.0]') + // Kapt integration compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0') From 3c42e9288100b119ac993df9af20beb47b0bf926 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 16 Jun 2021 23:16:44 +0100 Subject: [PATCH 32/56] Patch all eclipse deps to use a strict version --- build.gradle | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/build.gradle b/build.gradle index 9b66773f..d3ebb50e 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,7 @@ dependencies { // Mercury pulls all of these deps in, however eclipse does not specify the exact version to use so they can get updated without us knowing. // Depend specifically on these versions to prevent them from being updated under our feet. + // The POM is also patched later on to as this strict versioning does not make it through. implementation ('org.eclipse.jdt:org.eclipse.jdt.core:[3.21.0]') implementation ('org.eclipse.platform:org.eclipse.compare.core:[3.6.1000]') implementation ('org.eclipse.platform:org.eclipse.core.commands:[3.9.800]') @@ -194,6 +195,18 @@ import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node +def patchPom(groovy.util.Node node) { + node.dependencies.first().each { + def groupId = it.get("groupId").first().value().first() + + // Patch all eclipse deps to use a strict version + if (groupId.startsWith("org.eclipse.")) { + def version = it.get("version").first().value().first() + it.get("version").first().value = new groovy.util.NodeList(["[$version]"]) + } + } +} + publishing { publications { plugin(MavenPublication) { publication -> @@ -205,6 +218,10 @@ publishing { artifact sourcesJar artifact javadocJar + + pom.withXml { + patchPom(asNode()) + } } // Also publish a snapshot so people can use the latest version if they wish @@ -217,6 +234,10 @@ publishing { artifact sourcesJar artifact javadocJar + + pom.withXml { + patchPom(asNode()) + } } // Manually crate the plugin marker for snapshot versions From 99775c20690694e1b7ac80e049681fd60187bfd6 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Thu, 17 Jun 2021 23:41:46 +0800 Subject: [PATCH 33/56] Make compileForgeInjectJava build for Java 8 Signed-off-by: shedaniel --- build.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fac2e5b5..461ea788 100644 --- a/build.gradle +++ b/build.gradle @@ -23,7 +23,6 @@ tasks.withType(JavaCompile).configureEach { it.options.release = 16 } - group = "dev.architectury" archivesBaseName = project.name def baseVersion = '0.8.0' @@ -51,6 +50,10 @@ sourceSets { forgeInject } +tasks.compileForgeInjectJava { + options.release = 8 +} + repositories { mavenCentral() maven { url "https://maven.fabricmc.net/" } From 1f93aab9d84b9fbf486c9829551607b68a3ab0b5 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 18 Jun 2021 00:04:58 +0800 Subject: [PATCH 34/56] Reapply some patches Signed-off-by: shedaniel --- .../fabricmc/loom/LoomGradleExtension.java | 3 - .../providers/LaunchProvider.java | 2 +- .../providers/MinecraftProviderImpl.java | 27 ++- .../forge/FieldMigratedMappingsProvider.java | 9 +- .../forge/MinecraftPatchedProvider.java | 9 +- .../mappings/MappingsProviderImpl.java | 205 ++++++++++++++++-- 6 files changed, 217 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index bfe36d54..d1ae16cb 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -61,7 +61,6 @@ import net.fabricmc.loom.configuration.launch.LaunchProviderSettings; import net.fabricmc.loom.configuration.processors.JarProcessor; import net.fabricmc.loom.configuration.processors.JarProcessorManager; import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; import net.fabricmc.loom.configuration.providers.forge.FieldMigratedMappingsProvider; import net.fabricmc.loom.configuration.providers.forge.ForgeProvider; import net.fabricmc.loom.configuration.providers.forge.ForgeUniversalProvider; @@ -69,8 +68,6 @@ import net.fabricmc.loom.configuration.providers.forge.ForgeUserdevProvider; import net.fabricmc.loom.configuration.providers.forge.McpConfigProvider; import net.fabricmc.loom.configuration.providers.forge.PatchProvider; import net.fabricmc.loom.configuration.providers.forge.SrgProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; -import net.fabricmc.loom.configuration.providers.mappings.MojangMappingsDependency; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec; diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java index 522314bf..9aeb74d1 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java @@ -75,7 +75,7 @@ public class LaunchProvider extends DependencyProvider { .property("fabric.yarnWithSrg.path", getExtension().getMappingsProvider().tinyMappingsWithSrg.toAbsolutePath().toString()) .argument("--fml.mcVersion") - .argument(getExtension().getMinecraftProvider().getMinecraftVersion()) + .argument(getExtension().getMinecraftProvider().minecraftVersion()) .argument("--fml.forgeVersion") .argument(getExtension().getForgeProvider().getVersion().getForgeVersion()) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java index 2767755e..b6399e91 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java @@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.function.Consumer; +import com.google.common.base.Stopwatch; import com.google.common.io.Files; import org.gradle.api.GradleException; import org.gradle.api.Project; @@ -54,10 +55,11 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra private MinecraftLibraryProvider libraryProvider; private File minecraftJson; - private File minecraftClientJar; - private File minecraftServerJar; + public File minecraftClientJar; + public File minecraftServerJar; private File minecraftMergedJar; private File versionManifestJson; + private String jarSuffix = ""; public MinecraftProviderImpl(Project project) { super(project); @@ -67,6 +69,10 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { minecraftVersion = dependency.getDependency().getVersion(); + if (getExtension().shouldGenerateSrgTiny() && !getExtension().isForge()) { + addDependency("de.oceanlabs.mcp:mcp_config:" + minecraftVersion, Constants.Configurations.SRG); + } + boolean offline = getProject().getGradle().getStartParameter().isOffline(); initFiles(); @@ -118,6 +124,12 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra versionManifestJson = new File(getExtension().getUserCache(), "version_manifest.json"); } + public void deleteFiles() { + DownloadUtil.delete(minecraftClientJar); + DownloadUtil.delete(minecraftServerJar); + DownloadUtil.delete(minecraftMergedJar); + } + private void downloadMcJson(boolean offline) throws IOException { if (getExtension().isShareCaches() && !getExtension().isRootProject() && versionManifestJson.exists() && !isRefreshDeps()) { return; @@ -217,11 +229,14 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra private void mergeJars(Logger logger) throws IOException { logger.info(":merging jars"); + Stopwatch stopwatch = Stopwatch.createStarted(); try (JarMerger jarMerger = new JarMerger(minecraftClientJar, minecraftServerJar, minecraftMergedJar)) { jarMerger.enableSyntheticParamsOffset(); jarMerger.merge(); } + + logger.info(":merged jars in " + stopwatch); } public File getMergedJar() { @@ -242,6 +257,14 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra return libraryProvider; } + public String getJarSuffix() { + return jarSuffix; + } + + public void setJarSuffix(String jarSuffix) { + this.jarSuffix = jarSuffix; + } + @Override public String getTargetConfig() { return Constants.Configurations.MINECRAFT; diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java index 27f6fb6b..f5833007 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java @@ -28,7 +28,6 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; @@ -59,7 +58,7 @@ import org.objectweb.asm.Opcodes; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; +import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.ThreadingUtils; import net.fabricmc.loom.util.srg.SrgMerger; @@ -68,7 +67,7 @@ import net.fabricmc.mapping.tree.FieldDef; import net.fabricmc.mapping.tree.TinyMappingFactory; import net.fabricmc.mapping.tree.TinyTree; -public class FieldMigratedMappingsProvider extends MappingsProvider { +public class FieldMigratedMappingsProvider extends MappingsProviderImpl { private List> migratedFields = new ArrayList<>(); public Path migratedFieldsCache; public Path rawTinyMappings; @@ -143,7 +142,7 @@ public class FieldMigratedMappingsProvider extends MappingsProvider { migratedFields.forEach(entry -> { map.put(entry.getKey().owner + "#" + entry.getKey().field, entry.getValue()); }); - Files.write(migratedFieldsCache, new Gson().toJson(map).getBytes(StandardCharsets.UTF_8)); + Files.writeString(migratedFieldsCache, new Gson().toJson(map)); Files.deleteIfExists(tinyMappings.toPath()); } @@ -174,7 +173,7 @@ public class FieldMigratedMappingsProvider extends MappingsProvider { } } - Files.write(tinyMappings.toPath(), MappingsUtils.serializeToString(mappings).getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE); + Files.writeString(tinyMappings.toPath(), MappingsUtils.serializeToString(mappings), StandardOpenOption.CREATE); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index cd95c283..108450a6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -77,6 +77,7 @@ import org.zeroturnaround.zip.ZipUtil; import net.fabricmc.loom.configuration.DependencyProvider; import net.fabricmc.loom.configuration.providers.MinecraftProvider; +import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.util.Checksum; import net.fabricmc.loom.util.Constants; @@ -143,9 +144,9 @@ public class MinecraftPatchedProvider extends DependencyProvider { atDirty = mismatched; } - MinecraftProvider minecraftProvider = getExtension().getMinecraftProvider(); + MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); PatchProvider patchProvider = getExtension().getPatchProvider(); - String minecraftVersion = minecraftProvider.getMinecraftVersion(); + String minecraftVersion = minecraftProvider.minecraftVersion(); String patchId = "forge-" + patchProvider.forgeVersion; if (getExtension().useFabricMixin) { @@ -266,7 +267,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { private void createSrgJars(Logger logger) throws Exception { McpConfigProvider mcpProvider = getExtension().getMcpConfigProvider(); - MinecraftProvider minecraftProvider = getExtension().getMinecraftProvider(); + MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); String[] mappingsPath = {null}; @@ -510,7 +511,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { logger.lifecycle(":copying resources"); // Copy resources - MinecraftProvider minecraftProvider = getExtension().getMinecraftProvider(); + MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); copyNonClassFiles(minecraftProvider.minecraftClientJar, minecraftMergedPatchedJar); copyNonClassFiles(minecraftProvider.minecraftServerJar, minecraftMergedPatchedJar); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index bea337fc..fa1085f2 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -31,17 +31,25 @@ import java.net.URL; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.function.Consumer; import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; import com.google.common.net.UrlEscapers; import com.google.gson.JsonObject; +import dev.architectury.mappingslayers.api.utils.MappingsModificationUtils; +import dev.architectury.mappingslayers.api.utils.MappingsUtils; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.util.StringUtils; import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; import org.zeroturnaround.zip.FileSource; import org.zeroturnaround.zip.ZipEntrySource; import org.zeroturnaround.zip.ZipUtil; @@ -53,25 +61,35 @@ import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; import net.fabricmc.loom.configuration.processors.JarProcessorManager; import net.fabricmc.loom.configuration.processors.MinecraftProcessedProvider; import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; +import net.fabricmc.loom.configuration.providers.forge.MinecraftPatchedProvider; +import net.fabricmc.loom.configuration.providers.forge.SrgProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.DeletingFileVisitor; import net.fabricmc.loom.util.DownloadUtil; +import net.fabricmc.loom.util.srg.MCPReader; +import net.fabricmc.loom.util.srg.SrgMerger; +import net.fabricmc.loom.util.srg.SrgNamedWriter; +import net.fabricmc.mapping.reader.v2.TinyMetadata; import net.fabricmc.mapping.reader.v2.TinyV2Factory; import net.fabricmc.mapping.tree.TinyTree; import net.fabricmc.stitch.Command; import net.fabricmc.stitch.commands.CommandProposeFieldNames; import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2; -import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2; +import net.fabricmc.stitch.commands.tinyv2.TinyFile; +import net.fabricmc.stitch.commands.tinyv2.TinyV2Writer; public class MappingsProviderImpl extends DependencyProvider implements MappingsProvider { public MinecraftMappedProvider mappedProvider; + public MinecraftPatchedProvider patchedProvider; public String mappingsName; public String minecraftVersion; public String mappingsVersion; + public String removeSuffix; - private final Path mappingsDir; + protected final Path mappingsDir; + protected Path mappingsVersionedDir; private final Path mappingsStepsDir; private Path intermediaryTiny; private boolean hasRefreshed = false; @@ -79,7 +97,12 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings private Path baseTinyMappings; // The mappings we use in practice public File tinyMappings; + // tinyMappings wrapped in a jar public File tinyMappingsJar; + public Path tinyMappingsWithSrg; + public File mixinTinyMappingsWithSrg; // FORGE: The mixin mappings have srg names in intermediary. + public File srgToNamedSrg; // FORGE: srg to named in srg file format + private File unpickDefinitionsFile; private boolean hasUnpickDefinitions; private UnpickMetadata unpickMetadata; @@ -90,6 +113,28 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings mappingsStepsDir = mappingsDir.resolve("steps"); } + public Path getMappingsVersionedDir() throws IOException { + if (mappingsVersionedDir == null) { + mappingsVersionedDir = mappingsDir.resolve(getExtension().getMinecraftProvider().minecraftVersion()); + + if (!Files.exists(mappingsVersionedDir)) { + Files.createDirectories(mappingsVersionedDir); + } + } + + return mappingsVersionedDir; + } + + public Path getMappedVersionedDir(String name) throws IOException { + Path dir = getMappingsVersionedDir().resolve(name); + + if (!Files.exists(dir)) { + Files.createDirectories(dir); + } + + return dir; + } + public void clean() throws IOException { FileUtils.deleteDirectory(mappingsDir.toFile()); } @@ -98,6 +143,14 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings return MappingsCache.INSTANCE.get(tinyMappings.toPath()); } + public TinyTree getMappingsWithSrg() throws IOException { + if (getExtension().shouldGenerateSrgTiny()) { + return MappingsCache.INSTANCE.get(tinyMappingsWithSrg); + } + + throw new UnsupportedOperationException("Not running with Forge support / Tiny srg support."); + } + @Override public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { MinecraftProviderImpl minecraftProvider = getDependencyManager().getProvider(MinecraftProviderImpl.class); @@ -112,6 +165,13 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings boolean isV2; + if (isMCP(mappingsJar.toPath())) { + File old = mappingsJar; + mappingsJar = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".zip") + "-" + minecraftVersion + ".jar").toFile(); + FileUtils.copyFile(old, mappingsJar); + mappingsName += "-" + minecraftVersion; + } + // Only do this for official yarn, there isn't really a way we can get the mc version for all mappings if (dependency.getDependency().getGroup() != null && dependency.getDependency().getGroup().equals("net.fabricmc") && dependency.getDependency().getName().equals("yarn") && dependency.getDependency().getVersion() != null) { String yarnVersion = dependency.getDependency().getVersion(); @@ -123,11 +183,12 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings } // We can save reading the zip file + header by checking the file name - isV2 = mappingsJar.getName().endsWith("-v2.jar"); + isV2 = mappingsJar.getName().endsWith("-v2.jar") || mappingsJar.getName().endsWith("-mergedv2.jar"); } else { isV2 = doesJarContainV2Mappings(mappingsJar.toPath()); } + this.removeSuffix = StringUtils.removeSuffix(mappingsJar.getName(), ".jar"); this.mappingsVersion = version + (isV2 ? "-v2" : ""); initFiles(); @@ -146,18 +207,36 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings jarClassifier = jarClassifier + depStringSplit[3]; } - tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile(); - unpickDefinitionsFile = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".unpick").toFile(); - tinyMappingsJar = new File(getExtension().getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar")); + Path mappedVersionedDir = getMappedVersionedDir(removeSuffix); + tinyMappings = mappedVersionedDir.resolve("mappings.tiny").toFile(); + unpickDefinitionsFile = mappedVersionedDir.resolve("definitions.unpick").toFile(); + tinyMappingsJar = new File(getExtension().getUserCache(), removeSuffix + "-" + jarClassifier + ".jar"); + tinyMappingsWithSrg = mappedVersionedDir.resolve("mappings-srg.tiny"); + mixinTinyMappingsWithSrg = mappedVersionedDir.resolve("mappings-mixin-srg.tiny").toFile(); + srgToNamedSrg = mappedVersionedDir.resolve("mappings-srg-named.srg").toFile(); if (!tinyMappings.exists() || isRefreshDeps()) { - storeMappings(getProject(), minecraftProvider, mappingsJar.toPath()); + storeMappings(getProject(), minecraftProvider, mappingsJar.toPath(), postPopulationScheduler); } else { try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), (ClassLoader) null)) { extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); } } + if (getExtension().isForge()) { + patchedProvider = new MinecraftPatchedProvider(getProject()); + patchedProvider.provide(dependency, postPopulationScheduler); + } + + manipulateMappings(mappingsJar.toPath()); + + if (getExtension().shouldGenerateSrgTiny()) { + if (Files.notExists(tinyMappingsWithSrg) || isRefreshDeps()) { + // Merge tiny mappings with srg + SrgMerger.mergeSrg(getExtension().getSrgProvider().getSrg().toPath(), tinyMappings.toPath(), tinyMappingsWithSrg, true); + } + } + if (!tinyMappingsJar.exists() || isRefreshDeps()) { ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar); } @@ -173,6 +252,23 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings populateUnpickClasspath(); } + if (getExtension().isForge()) { + if (!getExtension().shouldGenerateSrgTiny()) { + throw new IllegalStateException("We have to generate srg tiny in a forge environment!"); + } + + if (!mixinTinyMappingsWithSrg.exists() || isRefreshDeps()) { + List lines = new ArrayList<>(Files.readAllLines(tinyMappingsWithSrg)); + lines.set(0, lines.get(0).replace("intermediary", "yraidemretni").replace("srg", "intermediary")); + Files.deleteIfExists(mixinTinyMappingsWithSrg.toPath()); + Files.write(mixinTinyMappingsWithSrg.toPath(), lines); + } + + if (!srgToNamedSrg.exists() || isRefreshDeps()) { + SrgNamedWriter.writeTo(getProject().getLogger(), srgToNamedSrg.toPath(), getMappingsWithSrg(), "srg", "named"); + } + } + addDependency(tinyMappingsJar, Constants.Configurations.MAPPINGS_FINAL); LoomGradleExtension extension = getExtension(); @@ -185,7 +281,11 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings extension.setJarProcessorManager(processorManager); processorManager.setupProcessors(); - if (processorManager.active()) { + if (extension.isForge()) { + patchedProvider.finishProvide(); + } + + if (processorManager.active() || (extension.isForge() && patchedProvider.usesProjectCache())) { mappedProvider = new MinecraftProcessedProvider(getProject(), processorManager); getProject().getLogger().lifecycle("Using project based jar storage"); } else { @@ -196,15 +296,28 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings mappedProvider.provide(dependency, postPopulationScheduler); } - private void storeMappings(Project project, MinecraftProviderImpl minecraftProvider, Path yarnJar) throws IOException { + public void manipulateMappings(Path mappingsJar) throws IOException { } + + private void storeMappings(Project project, MinecraftProviderImpl minecraftProvider, Path yarnJar, Consumer postPopulationScheduler) + throws Exception { project.getLogger().info(":extracting " + yarnJar.getFileName()); + if (isMCP(yarnJar)) { + readAndMergeMCP(yarnJar, postPopulationScheduler); + return; + } + try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, (ClassLoader) null)) { extractMappings(fileSystem, baseTinyMappings); extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); } - if (baseMappingsAreV2()) { + if (baseMappingsAreMergedV2()) { + // Architectury Loom Patch + // If a merged tiny v2 mappings file is provided + // Skip merging, should save a lot of time + Files.copy(baseTinyMappings, tinyMappings.toPath(), StandardCopyOption.REPLACE_EXISTING); + } else if (baseMappingsAreV2()) { // These are unmerged v2 mappings mergeAndSaveMappings(project, yarnJar); } else { @@ -218,16 +331,53 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings } } + private void readAndMergeMCP(Path mcpJar, Consumer postPopulationScheduler) throws Exception { + Path intermediaryTinyPath = getIntermediaryTiny(); + SrgProvider provider = getExtension().getSrgProvider(); + + if (provider == null) { + if (!getExtension().shouldGenerateSrgTiny()) { + Configuration srg = getProject().getConfigurations().maybeCreate(Constants.Configurations.SRG); + srg.setTransitive(false); + } + + provider = new SrgProvider(getProject()); + getProject().getDependencies().add(provider.getTargetConfig(), "de.oceanlabs.mcp:mcp_config:" + minecraftVersion); + Configuration configuration = getProject().getConfigurations().getByName(provider.getTargetConfig()); + provider.provide(DependencyInfo.create(getProject(), configuration.getDependencies().iterator().next(), configuration), postPopulationScheduler); + } + + Path srgPath = provider.getSrg().toPath(); + + TinyFile file = new MCPReader(intermediaryTinyPath, srgPath).read(mcpJar); + TinyV2Writer.write(file, tinyMappings.toPath()); + } + + private boolean isMCP(Path path) throws IOException { + try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { + return Files.exists(fs.getPath("fields.csv")) && Files.exists(fs.getPath("methods.csv")); + } + } + private boolean baseMappingsAreV2() throws IOException { try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) { TinyV2Factory.readMetadata(reader); return true; - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | NoSuchFileException e) { // TODO: just check the mappings version when Parser supports V1 in readMetadata() return false; } } + private boolean baseMappingsAreMergedV2() throws IOException { + try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) { + TinyMetadata metadata = TinyV2Factory.readMetadata(reader); + return metadata.getNamespaces().containsAll(Arrays.asList("named", "intermediary", "official")); + } catch (IllegalArgumentException | NoSuchFileException e) { + return false; + } + } + private boolean doesJarContainV2Mappings(Path path) throws IOException { try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) { @@ -293,21 +443,21 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings extractMappings(unmergedYarnJarFs, unmergedYarn); } + Stopwatch stopwatch = Stopwatch.createStarted(); + project.getLogger().info(":merging mappings"); Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny"); reorderMappings(getIntermediaryTiny(), invertedIntermediary, "intermediary", "official"); Path unorderedMergedMappings = Paths.get(mappingsStepsDir.toString(), "unordered-merged.tiny"); - project.getLogger().info(":merging"); mergeMappings(invertedIntermediary, unmergedYarn, unorderedMergedMappings); reorderMappings(unorderedMergedMappings, tinyMappings.toPath(), "official", "intermediary", "named"); + Files.deleteIfExists(invertedIntermediary); + Files.deleteIfExists(unorderedMergedMappings); + project.getLogger().info(":merged mappings in " + stopwatch.stop()); } - private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) { - Command command = new CommandReorderTinyV2(); - String[] args = new String[2 + newOrder.length]; - args[0] = oldMappings.toAbsolutePath().toString(); - args[1] = newMappings.toAbsolutePath().toString(); - System.arraycopy(newOrder, 0, args, 2, newOrder.length); - runCommand(command, args); + private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) throws IOException { + MappingsModificationUtils.modify(oldMappings, newMappings, tree -> + MappingsUtils.reorderNamespaces(tree, Arrays.asList(newOrder))); } private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) { @@ -338,8 +488,12 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings } } - private void initFiles() { - baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base"); + private void initFiles() throws IOException { + baseTinyMappings = getMappedVersionedDir(removeSuffix).resolve("mappings-base.tiny"); + + if (Files.exists(mappingsStepsDir)) { + Files.walkFileTree(mappingsStepsDir, new DeletingFileVisitor()); + } } public void cleanFiles() { @@ -381,13 +535,18 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings intermediaryTiny = mappingsDir.resolve(String.format("intermediary-%s-v2.tiny", minecraftVersion)); - if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) { + if (isRefreshDeps() && !hasRefreshed) { + Files.deleteIfExists(intermediaryTiny); + } + + if (!Files.exists(intermediaryTiny)) { hasRefreshed = true; + intermediaryTiny = getMappingsVersionedDir().resolve("intermediary-v2.tiny"); // Download and extract intermediary String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion); String intermediaryArtifactUrl = getExtension().getIntermediaryUrl().apply(encodedMinecraftVersion); - Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar"); + Path intermediaryJar = getMappingsVersionedDir().resolve("intermediary-v2.jar"); DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger()); extractIntermediary(intermediaryJar, intermediaryTiny); From 581b04761dccf7d01cdf605bac0e83f6f0e0e26d Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 13 Jun 2021 13:28:47 +0100 Subject: [PATCH 35/56] Fix new gradle 8.0 deprecation added in 7.2 (#416) * Fix new gradle 8.0 deprecation added in 7.2 * Handle bootstrap tests a bit better * Fix 0.9 wrapper tests --- .github/workflows/test-push.yml | 3 +-- .../loom/configuration/RemapConfiguration.java | 10 +++++++++- .../fabricmc/loom/test/util/ProjectTestTrait.groovy | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-push.yml b/.github/workflows/test-push.yml index 9bed2ef7..ae5306a1 100644 --- a/.github/workflows/test-push.yml +++ b/.github/workflows/test-push.yml @@ -165,8 +165,7 @@ jobs: - run: ./gradlew --version working-directory: bootstrap/test-project - - run: ./gradlew build + - run: ./gradlew build || true working-directory: bootstrap/test-project - continue-on-error: true # TODO check the output of the previous step here \ No newline at end of file diff --git a/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java index 7534c27b..3a19e70a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/RemapConfiguration.java @@ -27,6 +27,7 @@ package net.fabricmc.loom.configuration; import java.io.IOException; import com.google.common.base.Preconditions; +import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.UnknownTaskException; @@ -144,7 +145,14 @@ public class RemapConfiguration { remapSourcesJarTask.dependsOn(project.getTasks().getByName(sourcesJarTaskName)); if (isDefaultRemap) { - remapSourcesJarTask.doLast(task -> project.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); + // Do not use lambda here, see: https://github.com/gradle/gradle/pull/17087 + //noinspection Convert2Lambda + remapSourcesJarTask.doLast(new Action<>() { + @Override + public void execute(Task task) { + project.getArtifacts().add("archives", remapSourcesJarTask.getOutput()); + } + }); } if (extension.isShareCaches()) { diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 2d0640a2..0f72662d 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.2-20210527220045+0000" + final static String PRE_RELEASE_GRADLE = "7.2-20210612220215+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() From ac413d0d97aa948cc5dc02882debaa8c51b47ca3 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 19 Jun 2021 22:01:03 +0800 Subject: [PATCH 36/56] Fix missing pom patch Signed-off-by: shedaniel --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 85da8682..01f5ea69 100644 --- a/build.gradle +++ b/build.gradle @@ -290,6 +290,10 @@ publishing { from components.java artifact mainJar artifact sourcesJar + + pom.withXml { + patchPom(asNode()) + } } maven(MavenPublication) { publication -> From 10d810fad176d26ce5e5f9e1f656fc8d3c037a01 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 02:26:17 +0800 Subject: [PATCH 37/56] Readd silenceLicense Signed-off-by: shedaniel --- build.gradle | 3 ++- .../java/net/fabricmc/loom/LoomGradleExtension.java | 2 +- src/main/java/net/fabricmc/loom/LoomGradlePlugin.java | 1 + .../providers/mappings/LayeredMappingSpecBuilder.java | 10 +++++++++- .../providers/mappings/mojmap/MojangMappingLayer.java | 8 ++++++-- .../providers/mappings/mojmap/MojangMappingsSpec.java | 11 +++++++++-- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index bae8e322..0726b8a6 100644 --- a/build.gradle +++ b/build.gradle @@ -77,7 +77,8 @@ configurations { configurations.all { resolutionStrategy { - failOnNonReproducibleResolution() + // I am sorry modmuss +// failOnNonReproducibleResolution() } } diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index d1ae16cb..e70946e8 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -227,7 +227,7 @@ public class LoomGradleExtension { } public Dependency layered(Action action) { - LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder(); + LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder(this); action.execute(builder); LayeredMappingSpec builtSpec = builder.build(); return new LayeredMappingsDependency(new GradleMappingContext(project, "layers_" + builtSpec.getVersion().replace("+", "_").replace(".", "_")), builtSpec, builtSpec.getVersion()); diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 4b171024..96c49433 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -67,6 +67,7 @@ public class LoomGradlePlugin implements BootstrappedPlugin { loggedVersions.add(loomVersion); System.setProperty("loom.printed.logged", String.join(",", loggedVersions)); project.getLogger().lifecycle("Architectury Loom: " + loomVersion); + project.getLogger().lifecycle("You are using an unstable version of Architectury Loom! Please report any issues found!"); } refreshDeps = project.getGradle().getStartParameter().isRefreshDependencies() || "true".equals(System.getProperty("loom.refresh")); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java index 389df643..98582f2c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java @@ -29,16 +29,24 @@ import java.util.LinkedList; import java.util.List; import org.gradle.api.Action; +import org.jetbrains.annotations.Nullable; +import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec; import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec; import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpecBuilder; public class LayeredMappingSpecBuilder { private final List> layers = new LinkedList<>(); + @Nullable + private final LoomGradleExtension extension; + + public LayeredMappingSpecBuilder(LoomGradleExtension extension) { + this.extension = extension; + } public LayeredMappingSpecBuilder officalMojangMappings() { - layers.add(new MojangMappingsSpec()); + layers.add(new MojangMappingsSpec(() -> extension != null && extension.isSilentMojangMappingsLicenseEnabled())); return this; } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java index 31b5b880..194e2f31 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java @@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.function.BooleanSupplier; import org.gradle.api.logging.Logger; @@ -47,7 +48,8 @@ import net.fabricmc.mappingio.format.ProGuardReader; public record MojangMappingLayer(MinecraftVersionMeta.Download clientDownload, MinecraftVersionMeta.Download serverDownload, File workingDir, - Logger logger) implements MappingLayer { + Logger logger, + BooleanSupplier silenceLicense) implements MappingLayer { @Override public void visit(MappingVisitor mappingVisitor) throws IOException { var clientMappings = new File(workingDir(), "client.txt"); @@ -55,7 +57,9 @@ public record MojangMappingLayer(MinecraftVersionMeta.Download clientDownload, download(clientMappings, serverMappings); - printMappingsLicense(clientMappings.toPath()); + if (!silenceLicense.getAsBoolean()) { + printMappingsLicense(clientMappings.toPath()); + } // Make official the source namespace MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingVisitor, MappingNamespace.OFFICIAL.stringValue()); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java index 78cfc026..83f53a74 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java @@ -24,15 +24,21 @@ package net.fabricmc.loom.configuration.providers.mappings.mojmap; +import java.util.function.BooleanSupplier; + import net.fabricmc.loom.configuration.providers.mappings.MappingContext; import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; -public record MojangMappingsSpec() implements MappingsSpec { +public record MojangMappingsSpec(BooleanSupplier silenceLicense) implements MappingsSpec { // Keys in dependency manifest private static final String MANIFEST_CLIENT_MAPPINGS = "client_mappings"; private static final String MANIFEST_SERVER_MAPPINGS = "server_mappings"; + public MojangMappingsSpec() { + this(() -> false); + } + @Override public MojangMappingLayer createLayer(MappingContext context) { MinecraftVersionMeta versionInfo = context.minecraftProvider().getVersionInfo(); @@ -45,7 +51,8 @@ public record MojangMappingsSpec() implements MappingsSpec { versionInfo.download(MANIFEST_CLIENT_MAPPINGS), versionInfo.download(MANIFEST_SERVER_MAPPINGS), context.workingDirectory("mojang"), - context.getLogger() + context.getLogger(), + silenceLicense() ); } } From a0057b87318112e8eee46d1f64e4ad62626fb43a Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 02:26:42 +0800 Subject: [PATCH 38/56] Disable failOnNonReproducibleResolution Signed-off-by: shedaniel --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 01f5ea69..afa80763 100644 --- a/build.gradle +++ b/build.gradle @@ -76,7 +76,8 @@ configurations { configurations.all { resolutionStrategy { - failOnNonReproducibleResolution() + // I am sorry, for now + // failOnNonReproducibleResolution() } } From 076cda371cf36484c9c4851e5fe319465b0993b3 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 18:47:13 +0800 Subject: [PATCH 39/56] Make mojang mappings stable by implementing a custom license supplier Signed-off-by: shedaniel --- build.gradle | 6 ---- .../mappings/mojmap/MojangMappingLayer.java | 4 +-- .../mappings/mojmap/MojangMappingsSpec.java | 36 +++++++++++++++++-- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index e73b91a6..0726b8a6 100644 --- a/build.gradle +++ b/build.gradle @@ -82,12 +82,6 @@ configurations.all { } } -configurations.all { - resolutionStrategy { - failOnNonReproducibleResolution() - } -} - dependencies { implementation gradleApi() diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java index 194e2f31..4e83e412 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java @@ -49,7 +49,7 @@ public record MojangMappingLayer(MinecraftVersionMeta.Download clientDownload, MinecraftVersionMeta.Download serverDownload, File workingDir, Logger logger, - BooleanSupplier silenceLicense) implements MappingLayer { + MojangMappingsSpec.SilenceLicenseOption silenceLicense) implements MappingLayer { @Override public void visit(MappingVisitor mappingVisitor) throws IOException { var clientMappings = new File(workingDir(), "client.txt"); @@ -57,7 +57,7 @@ public record MojangMappingLayer(MinecraftVersionMeta.Download clientDownload, download(clientMappings, serverMappings); - if (!silenceLicense.getAsBoolean()) { + if (!silenceLicense.isSilent()) { printMappingsLicense(clientMappings.toPath()); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java index 83f53a74..4fa87d7c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingsSpec.java @@ -24,21 +24,51 @@ package net.fabricmc.loom.configuration.providers.mappings.mojmap; -import java.util.function.BooleanSupplier; - import net.fabricmc.loom.configuration.providers.mappings.MappingContext; import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; -public record MojangMappingsSpec(BooleanSupplier silenceLicense) implements MappingsSpec { +public record MojangMappingsSpec(SilenceLicenseOption silenceLicense) implements MappingsSpec { // Keys in dependency manifest private static final String MANIFEST_CLIENT_MAPPINGS = "client_mappings"; private static final String MANIFEST_SERVER_MAPPINGS = "server_mappings"; + public MojangMappingsSpec(SilenceLicenseSupplier supplier) { + this(new SilenceLicenseOption(supplier)); + } + public MojangMappingsSpec() { this(() -> false); } + @FunctionalInterface + public interface SilenceLicenseSupplier { + boolean isSilent(); + } + + public record SilenceLicenseOption(SilenceLicenseSupplier supplier) { + public boolean isSilent() { + return supplier.isSilent(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SilenceLicenseOption that)) return false; + return isSilent() == that.isSilent(); + } + + @Override + public int hashCode() { + return Boolean.hashCode(isSilent()); + } + + @Override + public String toString() { + return isSilent() + ""; + } + } + @Override public MojangMappingLayer createLayer(MappingContext context) { MinecraftVersionMeta versionInfo = context.minecraftProvider().getVersionInfo(); From 4dba17310dc5107fd28ca99cba277a4459985110 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 20:08:13 +0800 Subject: [PATCH 40/56] Add crane support Signed-off-by: shedaniel --- build.gradle | 2 +- .../mappings/LayeredMappingSpecBuilder.java | 6 ++ .../mappings/crane/CraneMappingLayer.java | 92 +++++++++++++++++++ .../mappings/crane/CraneMappingsSpec.java | 35 +++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingLayer.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingsSpec.java diff --git a/build.gradle b/build.gradle index 0726b8a6..c10f4b6b 100644 --- a/build.gradle +++ b/build.gradle @@ -108,7 +108,7 @@ dependencies { // tinyfile management implementation ('dev.architectury:tiny-remapper:1.1.0') - implementation ('dev.architectury:mappings-layers-core:1.2.7') + implementation ('dev.architectury:mappings-layers-core:1.3.8') implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') implementation 'net.fabricmc:access-widener:1.0.0' diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java index 98582f2c..035dcd06 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java @@ -32,6 +32,7 @@ import org.gradle.api.Action; import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.configuration.providers.mappings.crane.CraneMappingsSpec; import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec; import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec; import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpecBuilder; @@ -62,6 +63,11 @@ public class LayeredMappingSpecBuilder { return this; } + public LayeredMappingSpecBuilder crane(String mavenNotation) { + layers.add(new CraneMappingsSpec(mavenNotation)); + return this; + } + public LayeredMappingSpec build() { List> builtLayers = new LinkedList<>(); // Intermediary is always the base layer diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingLayer.java new file mode 100644 index 00000000..65fa8bd4 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingLayer.java @@ -0,0 +1,92 @@ +package net.fabricmc.loom.configuration.providers.mappings.crane; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Collections; + +import dev.architectury.mappingslayers.api.mutable.MutableClassDef; +import dev.architectury.mappingslayers.api.mutable.MutableFieldDef; +import dev.architectury.mappingslayers.api.mutable.MutableMethodDef; +import dev.architectury.mappingslayers.api.mutable.MutableParameterDef; +import dev.architectury.mappingslayers.api.mutable.MutableTinyTree; +import dev.architectury.mappingslayers.api.utils.MappingsUtils; +import org.apache.commons.io.IOUtils; + +import net.fabricmc.loom.configuration.providers.mappings.MappingLayer; +import net.fabricmc.loom.util.FileSystemUtil; +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.MappingVisitor; + +public record CraneMappingLayer(File craneJar) implements MappingLayer { + private static final String TINY_FILE_NAME = "crane.tiny"; + + @Override + public void visit(MappingVisitor visitor) throws IOException { + try (FileSystemUtil.FileSystemDelegate fs = FileSystemUtil.getJarFileSystem(craneJar().toPath(), false)) { + try (BufferedReader reader = Files.newBufferedReader(fs.get().getPath(TINY_FILE_NAME), StandardCharsets.UTF_8)) { + // can't use this, it requires 2 namespaces + // Tiny2Reader.read(reader, mappingVisitor); + MutableTinyTree tree = MappingsUtils.deserializeFromString(IOUtils.toString(reader)); + + do { + if (visitor.visitHeader()) { + visitor.visitNamespaces(tree.getMetadata().getNamespaces().get(0), Collections.emptyList()); + } + + if (visitor.visitContent()) { + for (MutableClassDef classDef : tree.getClassesMutable()) { + if (visitor.visitClass(classDef.getName(0))) { + if (!visitor.visitElementContent(MappedElementKind.CLASS)) { + return; + } + + for (MutableFieldDef fieldDef : classDef.getFieldsMutable()) { + if (visitor.visitField(fieldDef.getName(0), fieldDef.getDescriptor(0))) { + if (!visitor.visitElementContent(MappedElementKind.FIELD)) { + return; + } + + if (fieldDef.getComment() != null) { + visitor.visitComment(MappedElementKind.FIELD, fieldDef.getComment()); + } + } + } + + for (MutableMethodDef methodDef : classDef.getMethodsMutable()) { + if (visitor.visitMethod(methodDef.getName(0), methodDef.getDescriptor(0))) { + if (!visitor.visitElementContent(MappedElementKind.METHOD)) { + return; + } + + for (MutableParameterDef parameterDef : methodDef.getParametersMutable()) { + if (visitor.visitMethodArg(parameterDef.getLocalVariableIndex(), parameterDef.getLocalVariableIndex(), parameterDef.getName(0))) { + if (!visitor.visitElementContent(MappedElementKind.METHOD_ARG)) { + return; + } + + if (parameterDef.getComment() != null) { + visitor.visitComment(MappedElementKind.METHOD_ARG, parameterDef.getComment()); + } + } + } + + if (methodDef.getComment() != null) { + visitor.visitComment(MappedElementKind.METHOD, methodDef.getComment()); + } + } + } + + if (classDef.getComment() != null) { + visitor.visitComment(MappedElementKind.FIELD, classDef.getComment()); + } + } + } + } + } while (!visitor.visitEnd()); + } + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingsSpec.java new file mode 100644 index 00000000..179bcc92 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/crane/CraneMappingsSpec.java @@ -0,0 +1,35 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.crane; + +import net.fabricmc.loom.configuration.providers.mappings.MappingContext; +import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec; + +public record CraneMappingsSpec(String mavenNotation) implements MappingsSpec { + @Override + public CraneMappingLayer createLayer(MappingContext context) { + return new CraneMappingLayer(context.mavenFile(mavenNotation())); + } +} From 3f9dc85fba8a3f1b7a1d9b6d00d424b263974aae Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 20:11:18 +0800 Subject: [PATCH 41/56] Publish Loom 0.9.0 Signed-off-by: shedaniel --- .github/workflows/publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a0fdd15a..e5d8228d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,6 +6,7 @@ on: - 'dev/0.6-forge' - 'dev/0.7-forge' - 'dev/0.8' + - 'dev/0.9' jobs: build: From 54d6ef7896f22f89d6594703d09e3195c814cf10 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 20:24:10 +0800 Subject: [PATCH 42/56] Fix typo "officalMojangMappings" (#420) Signed-off-by: shedaniel --- src/main/java/net/fabricmc/loom/LoomGradleExtension.java | 2 +- .../providers/mappings/LayeredMappingSpecBuilder.java | 2 +- .../java/net/fabricmc/loom/task/MigrateMappingsTask.java | 2 +- .../layeredmappings/LayeredMappingSpecBuilderTest.groovy | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 4f9f5e94..66902dc1 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -117,7 +117,7 @@ public class LoomGradleExtension { } public Dependency officialMojangMappings() { - return layered(LayeredMappingSpecBuilder::officalMojangMappings); + return layered(LayeredMappingSpecBuilder::officialMojangMappings); } public Dependency layered(Action action) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java index 389df643..208f34e8 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingSpecBuilder.java @@ -37,7 +37,7 @@ import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMap public class LayeredMappingSpecBuilder { private final List> layers = new LinkedList<>(); - public LayeredMappingSpecBuilder officalMojangMappings() { + public LayeredMappingSpecBuilder officialMojangMappings() { layers.add(new MojangMappingsSpec()); return this; } diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index 6151f932..7f7074de 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -124,7 +124,7 @@ public class MigrateMappingsTask extends AbstractLoomTask { throw new UnsupportedOperationException("Migrating Mojang mappings is currently only supported for the specified minecraft version"); } - LayeredMappingsDependency dep = (LayeredMappingsDependency) getExtension().layered(LayeredMappingSpecBuilder::officalMojangMappings); + LayeredMappingsDependency dep = (LayeredMappingsDependency) getExtension().layered(LayeredMappingSpecBuilder::officialMojangMappings); files = dep.resolve(); } else { Dependency dependency = project.getDependencies().create(mappings); diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy index 035ac11e..7fe03993 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy @@ -37,7 +37,7 @@ class LayeredMappingSpecBuilderTest extends Specification { def "simple mojmap" () { when: def spec = layered() { - officalMojangMappings() + officialMojangMappings() } def layers = spec.layers() then: @@ -50,7 +50,7 @@ class LayeredMappingSpecBuilderTest extends Specification { def "simple mojmap with parchment" () { when: def spec = layered() { - officalMojangMappings() + officialMojangMappings() parchment("I like cake") } def layers = spec.layers() @@ -68,7 +68,7 @@ class LayeredMappingSpecBuilderTest extends Specification { def "simple mojmap with parchment keep prefix" () { when: def spec = layered() { - officalMojangMappings() + officialMojangMappings() parchment("I like cake") { it.removePrefix = false } @@ -88,7 +88,7 @@ class LayeredMappingSpecBuilderTest extends Specification { def "simple mojmap with parchment keep prefix alternate hash" () { when: def spec = layered() { - officalMojangMappings() + officialMojangMappings() parchment("I really like cake") { it.removePrefix = false } From 8a8b2d88e3733f834b0482179b0fce325df91685 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 20 Jun 2021 20:47:18 +0800 Subject: [PATCH 43/56] Avoid double brackets Signed-off-by: shedaniel --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 270f6331..087850a4 100644 --- a/build.gradle +++ b/build.gradle @@ -279,7 +279,9 @@ def patchPom(groovy.util.Node node) { // Patch all eclipse deps to use a strict version if (groupId.startsWith("org.eclipse.")) { def version = it.get("version").first().value().first() - it.get("version").first().value = new groovy.util.NodeList(["[$version]"]) + if (!version.startsWith("[")) { + it.get("version").first().value = new groovy.util.NodeList(["[$version]"]) + } } } } From 9d31be3729223ff6080b78db5828693d43c555df Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 25 Jun 2021 02:59:18 +0800 Subject: [PATCH 44/56] Fix mergeAndSaveMappings logic Signed-off-by: shedaniel --- .../mappings/MappingsProviderImpl.java | 53 ++++++++++--------- .../mappings/mojmap/MojangMappingLayer.java | 1 - 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index fa1085f2..8f319f61 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -28,6 +28,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -37,6 +38,7 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -44,7 +46,6 @@ import com.google.common.base.Preconditions; import com.google.common.base.Stopwatch; import com.google.common.net.UrlEscapers; import com.google.gson.JsonObject; -import dev.architectury.mappingslayers.api.utils.MappingsModificationUtils; import dev.architectury.mappingslayers.api.utils.MappingsUtils; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.util.StringUtils; @@ -73,9 +74,13 @@ import net.fabricmc.loom.util.srg.SrgNamedWriter; import net.fabricmc.mapping.reader.v2.TinyMetadata; import net.fabricmc.mapping.reader.v2.TinyV2Factory; import net.fabricmc.mapping.tree.TinyTree; +import net.fabricmc.mappingio.adapter.MappingNsCompleter; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.format.Tiny2Reader; +import net.fabricmc.mappingio.format.Tiny2Writer; +import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.stitch.Command; import net.fabricmc.stitch.commands.CommandProposeFieldNames; -import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2; import net.fabricmc.stitch.commands.tinyv2.TinyFile; import net.fabricmc.stitch.commands.tinyv2.TinyV2Writer; @@ -445,32 +450,28 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings Stopwatch stopwatch = Stopwatch.createStarted(); project.getLogger().info(":merging mappings"); - Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny"); - reorderMappings(getIntermediaryTiny(), invertedIntermediary, "intermediary", "official"); - Path unorderedMergedMappings = Paths.get(mappingsStepsDir.toString(), "unordered-merged.tiny"); - mergeMappings(invertedIntermediary, unmergedYarn, unorderedMergedMappings); - reorderMappings(unorderedMergedMappings, tinyMappings.toPath(), "official", "intermediary", "named"); - Files.deleteIfExists(invertedIntermediary); - Files.deleteIfExists(unorderedMergedMappings); - project.getLogger().info(":merged mappings in " + stopwatch.stop()); - } + MemoryMappingTree tree = new MemoryMappingTree(); + MappingNsCompleter nsCompleter = new MappingNsCompleter(tree, Collections.singletonMap(MappingNamespace.NAMED.stringValue(), MappingNamespace.INTERMEDIARY.stringValue()), true); - private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) throws IOException { - MappingsModificationUtils.modify(oldMappings, newMappings, tree -> - MappingsUtils.reorderNamespaces(tree, Arrays.asList(newOrder))); - } - - private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) { - try { - Command command = new CommandMergeTinyV2(); - runCommand(command, intermediaryMappings.toAbsolutePath().toString(), - yarnMappings.toAbsolutePath().toString(), - newMergedMappings.toAbsolutePath().toString(), - "intermediary", "official"); - } catch (Exception e) { - throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString() - + " with mappings from " + yarnMappings, e); + try (BufferedReader reader = Files.newBufferedReader(getIntermediaryTiny(), StandardCharsets.UTF_8)) { + Tiny2Reader.read(reader, nsCompleter); } + + MemoryMappingTree tempTree = new MemoryMappingTree(); + + MappingSourceNsSwitch sourceNsSwitch = new MappingSourceNsSwitch(tempTree, MappingNamespace.OFFICIAL.stringValue()); + tree.accept(sourceNsSwitch); + tree = tempTree; + + try (BufferedReader reader = Files.newBufferedReader(unmergedYarn, StandardCharsets.UTF_8)) { + Tiny2Reader.read(reader, tree); + } + + try (Tiny2Writer writer = new Tiny2Writer(Files.newBufferedWriter(tinyMappings.toPath(), StandardCharsets.UTF_8), false)) { + tree.accept(writer); + } + + project.getLogger().info(":merged mappings in " + stopwatch.stop()); } private void suggestFieldNames(MinecraftProviderImpl minecraftProvider, Path oldMappings, Path newMappings) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java index 4e83e412..835dc910 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/mojmap/MojangMappingLayer.java @@ -32,7 +32,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; -import java.util.function.BooleanSupplier; import org.gradle.api.logging.Logger; From 7fba77d43a169f6f20c4cfe17af7bcac86833833 Mon Sep 17 00:00:00 2001 From: LogicFan <38597904+LogicFan@users.noreply.github.com> Date: Mon, 28 Jun 2021 11:33:18 -0400 Subject: [PATCH 45/56] fix broken test introduced in 54d6ef7896f22f89d6594703d09e3195c814cf10 (#424) --- src/test/resources/projects/parchment/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/projects/parchment/build.gradle b/src/test/resources/projects/parchment/build.gradle index 255e98e0..d36eaaeb 100644 --- a/src/test/resources/projects/parchment/build.gradle +++ b/src/test/resources/projects/parchment/build.gradle @@ -12,7 +12,7 @@ repositories { dependencies { minecraft "com.mojang:minecraft:1.16.5" mappings loom.layered() { - officalMojangMappings() + officialMojangMappings() parchment("org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip") } From ae5bc4df15748155adddb1b654a7cac02ef6a07f Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:44:02 +0300 Subject: [PATCH 46/56] Separate Forge runtime into its own subproject --- .gitignore | 3 +- build.gradle | 39 +-------- forge-runtime/.gitignore | 6 ++ forge-runtime/build.gradle | 82 +++++++++++++++++++ .../mcp/MethodsReturnNonnullByDefault.java | 3 +- .../java/net/fabricmc/loom/inject/Pair.java | 0 .../loom/inject/YarnNamingService.java | 0 ...ForgeLoomMixinRemapperInjectorService.java | 0 .../mixin/MixinIntermediaryDevRemapper.java | 0 ...w.mods.modlauncher.api.INameMappingService | 0 ...ods.modlauncher.api.ITransformationService | 0 settings.gradle | 3 +- .../providers/LaunchProvider.java | 3 +- .../forge/MinecraftPatchedProvider.java | 19 ----- .../net/fabricmc/loom/util/Constants.java | 2 + 15 files changed, 101 insertions(+), 59 deletions(-) create mode 100644 forge-runtime/.gitignore create mode 100644 forge-runtime/build.gradle rename {src/forgeInject => forge-runtime/src/main}/java/mcp/MethodsReturnNonnullByDefault.java (90%) rename {src/forgeInject => forge-runtime/src/main}/java/net/fabricmc/loom/inject/Pair.java (100%) rename {src/forgeInject => forge-runtime/src/main}/java/net/fabricmc/loom/inject/YarnNamingService.java (100%) rename {src/forgeInject => forge-runtime/src/main}/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java (100%) rename {src/forgeInject => forge-runtime/src/main}/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java (100%) rename {src/forgeInject => forge-runtime/src/main}/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService (100%) rename {src/forgeInject => forge-runtime/src/main}/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService (100%) diff --git a/.gitignore b/.gitignore index 4354f60f..6a36faa2 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ !/Jenkinsfile !/checkstyle.xml !/codenarc.groovy -!/bootstrap \ No newline at end of file +!/bootstrap +!/forge-runtime diff --git a/build.gradle b/build.gradle index 087850a4..42442548 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ plugins { id 'codenarc' id "org.cadixdev.licenser" version "0.5.0" id 'com.github.johnrengelman.shadow' version '7.0.0' + id 'net.kyori.blossom' version '1.3.0' } sourceCompatibility = 16 @@ -40,20 +41,6 @@ if (!isSnapshot) { logger.lifecycle(":building plugin v${version}") -configurations { - forgeInjectShadow - forgeInjectCompileClasspath.extendsFrom(forgeInjectShadow) - forgeInjectRuntimeClasspath.extendsFrom(forgeInjectShadow) -} - -sourceSets { - forgeInject -} - -tasks.compileForgeInjectJava { - options.release = 8 -} - repositories { mavenCentral() maven { url "https://maven.fabricmc.net/" } @@ -159,14 +146,6 @@ dependencies { implementation ('de.oceanlabs.mcp:mcinjector:3.8.0') implementation ('com.opencsv:opencsv:5.4') - // Forge injection - forgeInjectShadow ('net.fabricmc:tiny-mappings-parser:0.2.2.14') - forgeInjectImplementation ('cpw.mods:modlauncher:6.1.3') - forgeInjectImplementation ('org.spongepowered:mixin:0.8.2') - forgeInjectImplementation ('com.google.code.gson:gson:2.8.6') - forgeInjectImplementation ('com.google.guava:guava:21.0') - forgeInjectImplementation ('org.apache.logging.log4j:log4j-api:2.11.2') - // Testing testImplementation(gradleTestKit()) testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') { @@ -177,13 +156,8 @@ dependencies { compileOnly 'org.jetbrains:annotations:20.1.0' } -task forgeInjectJar(type: ShadowJar, dependsOn: [compileForgeInjectJava, processForgeInjectResources]) { - relocate 'net.fabricmc.mapping', 'net.fabricmc.loom.mapping' - relocate 'net.fabricmc.mappings', 'net.fabricmc.loom.mappings' - configurations = [project.configurations.forgeInjectShadow] - classifier = 'forgeinject' - from compileForgeInjectJava.outputs - from processForgeInjectResources.outputs +blossom { + replaceToken '$LOOM_VERSION', version } jar { @@ -191,13 +165,7 @@ jar { } task mainJar(type: Jar, dependsOn: jar) { - dependsOn forgeInjectJar - from zipTree(jar.archiveFile) - from(forgeInjectJar.outputs) { - into "inject" - rename { "injection.jar" } - } manifest { attributes 'Implementation-Version': project.version + ' Build(' + buildNum + ')' @@ -225,7 +193,6 @@ license { exclude '**/loom/util/DownloadUtil.java' exclude '**/projects' exclude '**/loom/util/FileSystemUtil.java' - exclude '**/loom/inject/mixin/MixinIntermediaryDevRemapper.java' } checkstyle { diff --git a/forge-runtime/.gitignore b/forge-runtime/.gitignore new file mode 100644 index 00000000..31ecb657 --- /dev/null +++ b/forge-runtime/.gitignore @@ -0,0 +1,6 @@ +# Ignore everything +/* + +!/src +!/build.gradle +!/.gitignore diff --git a/forge-runtime/build.gradle b/forge-runtime/build.gradle new file mode 100644 index 00000000..34303aea --- /dev/null +++ b/forge-runtime/build.gradle @@ -0,0 +1,82 @@ +plugins { + id 'java' + id 'maven-publish' + id 'com.github.johnrengelman.shadow' + id 'org.cadixdev.licenser' +} + +group = rootProject.group +archivesBaseName = 'architectury-loom-forge-runtime' +version = rootProject.version + +sourceCompatibility = 8 +targetCompatibility = 8 + +configurations { + include + compileOnly.extendsFrom include +} + +tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + it.options.release = 8 +} + +repositories { + mavenCentral() + maven { url "https://maven.fabricmc.net/" } + maven { + url "https://maven.minecraftforge.net/" + content { + excludeGroupByRegex "org\\.eclipse\\.?.*" + } + } +} + +dependencies { + include ('net.fabricmc:tiny-mappings-parser:0.2.2.14') + compileOnly ('cpw.mods:modlauncher:6.1.3') + compileOnly ('org.spongepowered:mixin:0.8.2') + compileOnly ('com.google.code.gson:gson:2.8.6') + compileOnly ('com.google.guava:guava:21.0') + compileOnly ('org.apache.logging.log4j:log4j-api:2.11.2') +} + +jar { + archiveClassifier = "slim" +} + +shadowJar { + archiveClassifier = "" + configurations = [project.configurations.include] + relocate "net.fabricmc.mapping", "dev.architectury.loom.forgeruntime.shadow.mapping" + relocate "net.fabricmc.mappings", "dev.architectury.loom.forgeruntime.shadow.mappings" +} + +assemble.dependsOn shadowJar + +license { + header rootProject.file("HEADER") + include "**/*.java" + exclude '**/loom/inject/mixin/MixinIntermediaryDevRemapper.java' +} + +publishing { + publications { + maven(MavenPublication) { + from components.java + } + } + + repositories { + if (System.getenv("MAVEN_PASS") != null) { + maven { + url = "https://deploy.shedaniel.me/" + credentials { + username = "shedaniel" + password = System.getenv("MAVEN_PASS") + } + } + } + } +} diff --git a/src/forgeInject/java/mcp/MethodsReturnNonnullByDefault.java b/forge-runtime/src/main/java/mcp/MethodsReturnNonnullByDefault.java similarity index 90% rename from src/forgeInject/java/mcp/MethodsReturnNonnullByDefault.java rename to forge-runtime/src/main/java/mcp/MethodsReturnNonnullByDefault.java index 8fbac050..8ec54e47 100644 --- a/src/forgeInject/java/mcp/MethodsReturnNonnullByDefault.java +++ b/forge-runtime/src/main/java/mcp/MethodsReturnNonnullByDefault.java @@ -25,7 +25,8 @@ package mcp; /** - * A dummy class, required for some Forge classes to load. + * A dummy class, required for some Forge classes to load + * because {@code MethodsReturnNonnullByDefault} in MCP has runtime retention. * * @deprecated Don't use this in your mods. JetBrains annotations are there for you. */ diff --git a/src/forgeInject/java/net/fabricmc/loom/inject/Pair.java b/forge-runtime/src/main/java/net/fabricmc/loom/inject/Pair.java similarity index 100% rename from src/forgeInject/java/net/fabricmc/loom/inject/Pair.java rename to forge-runtime/src/main/java/net/fabricmc/loom/inject/Pair.java diff --git a/src/forgeInject/java/net/fabricmc/loom/inject/YarnNamingService.java b/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java similarity index 100% rename from src/forgeInject/java/net/fabricmc/loom/inject/YarnNamingService.java rename to forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java diff --git a/src/forgeInject/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java b/forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java similarity index 100% rename from src/forgeInject/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java rename to forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java diff --git a/src/forgeInject/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java b/forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java similarity index 100% rename from src/forgeInject/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java rename to forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java diff --git a/src/forgeInject/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService b/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService similarity index 100% rename from src/forgeInject/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService rename to forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService diff --git a/src/forgeInject/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService b/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService similarity index 100% rename from src/forgeInject/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService rename to forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService diff --git a/settings.gradle b/settings.gradle index 26763f4c..0b542936 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = "architectury-loom" -include "bootstrap" \ No newline at end of file +include "bootstrap" +include "forge-runtime" diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java index 9aeb74d1..4cf96b94 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java @@ -136,7 +136,8 @@ public class LaunchProvider extends DependencyProvider { annotationDependency = addDependency(Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME); if (getExtension().isForge()) { - addDependency(Constants.Dependencies.JAVAX_ANNOTATIONS + Constants.Dependencies.Versions.JAVAX_ANNOTATIONS, "compileOnly"); + addDependency(Constants.Dependencies.FORGE_RUNTIME + Constants.Dependencies.Versions.FORGE_RUNTIME, JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME); + addDependency(Constants.Dependencies.JAVAX_ANNOTATIONS + Constants.Dependencies.Versions.JAVAX_ANNOTATIONS, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME); } postPopulationScheduler.accept(this::writeRemapClassPath); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index 108450a6..995cb208 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -339,25 +339,6 @@ public class MinecraftPatchedProvider extends DependencyProvider { copyAll(getExtension().getForgeUniversalProvider().getForge(), environment.patchedSrgJar.apply(this)); copyUserdevFiles(getExtension().getForgeUserdevProvider().getUserdevJar(), environment.patchedSrgJar.apply(this)); }); - - logger.lifecycle(":injecting loom classes into minecraft"); - File injection = File.createTempFile("loom-injection", ".jar"); - - try (InputStream in = MinecraftProvider.class.getResourceAsStream("/inject/injection.jar")) { - FileUtils.copyInputStreamToFile(in, injection); - } - - for (Environment environment : Environment.values()) { - String side = environment.side(); - File target = environment.patchedSrgJar.apply(this); - walkFileSystems(injection, target, it -> { - if (it.getFileName().toString().equals("MANIFEST.MF")) { - return false; - } - - return getExtension().useFabricMixin || !it.getFileName().toString().endsWith("cpw.mods.modlauncher.api.ITransformationService"); - }, this::copyReplacing); - } } private void accessTransformForge(Logger logger) throws Exception { diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index f4d12355..6f6f4f45 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -91,6 +91,7 @@ public class Constants { public static final String TERMINAL_CONSOLE_APPENDER = "net.minecrell:terminalconsoleappender:"; public static final String JETBRAINS_ANNOTATIONS = "org.jetbrains:annotations:"; public static final String JAVAX_ANNOTATIONS = "com.google.code.findbugs:jsr305:"; // I hate that I have to add these. + public static final String FORGE_RUNTIME = "dev.architectury:architectury-loom-forge-runtime:"; private Dependencies() { } @@ -104,6 +105,7 @@ public class Constants { public static final String TERMINAL_CONSOLE_APPENDER = "1.2.0"; public static final String JETBRAINS_ANNOTATIONS = "19.0.0"; public static final String JAVAX_ANNOTATIONS = "3.0.2"; + public static final String FORGE_RUNTIME = "$LOOM_VERSION"; // replaced with current version at build time private Versions() { } From 758333595efc7da6a8b3f81e13278d5aa04b00c5 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:47:47 +0300 Subject: [PATCH 47/56] Use AbstractMap.SimpleImmutableEntry instead of a custom Pair class --- .../java/net/fabricmc/loom/inject/Pair.java | 52 ------------------- .../loom/inject/YarnNamingService.java | 3 +- 2 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 forge-runtime/src/main/java/net/fabricmc/loom/inject/Pair.java diff --git a/forge-runtime/src/main/java/net/fabricmc/loom/inject/Pair.java b/forge-runtime/src/main/java/net/fabricmc/loom/inject/Pair.java deleted file mode 100644 index 0206cb5d..00000000 --- a/forge-runtime/src/main/java/net/fabricmc/loom/inject/Pair.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2016, 2017, 2018 FabricMC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package net.fabricmc.loom.inject; - -import java.util.Map; - -final class Pair implements Map.Entry { - private final A first; - private final B second; - - Pair(A first, B second) { - this.first = first; - this.second = second; - } - - @Override - public A getKey() { - return first; - } - - @Override - public B getValue() { - return second; - } - - @Override - public B setValue(B value) { - throw new UnsupportedOperationException("Pairs are immutable!"); - } -} diff --git a/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java b/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java index 2b62dc53..dea0428f 100644 --- a/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java +++ b/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java @@ -30,6 +30,7 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.AbstractMap; import java.util.Map; import java.util.Optional; import java.util.function.BiFunction; @@ -56,7 +57,7 @@ public class YarnNamingService implements INameMappingService { @Override public Map.Entry understanding() { - return new Pair<>("srg", "mcp"); + return new AbstractMap.SimpleImmutableEntry<>("srg", "mcp"); } @Override From 31495c1ca6e2253bfef1fbb12754250f941c88d2 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:50:04 +0300 Subject: [PATCH 48/56] Add checkstyle to forge-runtime --- forge-runtime/build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/forge-runtime/build.gradle b/forge-runtime/build.gradle index 34303aea..8c6e5fff 100644 --- a/forge-runtime/build.gradle +++ b/forge-runtime/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'maven-publish' + id 'checkstyle' id 'com.github.johnrengelman.shadow' id 'org.cadixdev.licenser' } @@ -61,6 +62,11 @@ license { exclude '**/loom/inject/mixin/MixinIntermediaryDevRemapper.java' } +checkstyle { + configFile = rootProject.checkstyle.configFile + toolVersion = rootProject.checkstyle.toolVersion +} + publishing { publications { maven(MavenPublication) { From 8146d775a1026283cfa73581bc829932173d34f1 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:52:43 +0300 Subject: [PATCH 49/56] net.fabricmc.loom.inject -> dev.architectury.loom.forgeruntime --- .../architectury/loom/forgeruntime}/YarnNamingService.java | 2 +- .../mixin/ForgeLoomMixinRemapperInjectorService.java | 2 +- .../loom/forgeruntime}/mixin/MixinIntermediaryDevRemapper.java | 2 +- .../services/cpw.mods.modlauncher.api.INameMappingService | 2 +- .../services/cpw.mods.modlauncher.api.ITransformationService | 2 +- .../fabricmc/loom/configuration/providers/LaunchProvider.java | 1 + 6 files changed, 6 insertions(+), 5 deletions(-) rename forge-runtime/src/main/java/{net/fabricmc/loom/inject => dev/architectury/loom/forgeruntime}/YarnNamingService.java (98%) rename forge-runtime/src/main/java/{net/fabricmc/loom/inject => dev/architectury/loom/forgeruntime}/mixin/ForgeLoomMixinRemapperInjectorService.java (98%) rename forge-runtime/src/main/java/{net/fabricmc/loom/inject => dev/architectury/loom/forgeruntime}/mixin/MixinIntermediaryDevRemapper.java (99%) diff --git a/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java b/forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/YarnNamingService.java similarity index 98% rename from forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java rename to forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/YarnNamingService.java index dea0428f..9d3c2aa9 100644 --- a/forge-runtime/src/main/java/net/fabricmc/loom/inject/YarnNamingService.java +++ b/forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/YarnNamingService.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package net.fabricmc.loom.inject; +package dev.architectury.loom.forgeruntime; import java.io.BufferedReader; import java.io.IOException; diff --git a/forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java b/forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/mixin/ForgeLoomMixinRemapperInjectorService.java similarity index 98% rename from forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java rename to forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/mixin/ForgeLoomMixinRemapperInjectorService.java index 1fe961c6..c32f6724 100644 --- a/forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/ForgeLoomMixinRemapperInjectorService.java +++ b/forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/mixin/ForgeLoomMixinRemapperInjectorService.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package net.fabricmc.loom.inject.mixin; +package dev.architectury.loom.forgeruntime.mixin; import java.io.BufferedReader; import java.nio.file.Files; diff --git a/forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java b/forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/mixin/MixinIntermediaryDevRemapper.java similarity index 99% rename from forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java rename to forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/mixin/MixinIntermediaryDevRemapper.java index ef5724dc..f331a9ca 100644 --- a/forge-runtime/src/main/java/net/fabricmc/loom/inject/mixin/MixinIntermediaryDevRemapper.java +++ b/forge-runtime/src/main/java/dev/architectury/loom/forgeruntime/mixin/MixinIntermediaryDevRemapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.loom.inject.mixin; +package dev.architectury.loom.forgeruntime.mixin; import java.util.ArrayDeque; import java.util.Collection; diff --git a/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService b/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService index 45290566..ec41d220 100644 --- a/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService +++ b/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.INameMappingService @@ -1 +1 @@ -net.fabricmc.loom.inject.YarnNamingService +dev.architectury.loom.forgeruntime.YarnNamingService diff --git a/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService b/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService index 0fb04144..679794d7 100644 --- a/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService +++ b/forge-runtime/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService @@ -1 +1 @@ -net.fabricmc.loom.inject.mixin.ForgeLoomMixinRemapperInjectorService \ No newline at end of file +dev.architectury.loom.forgeruntime.mixin.ForgeLoomMixinRemapperInjectorService \ No newline at end of file diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java index 4cf96b94..6325162c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java @@ -72,6 +72,7 @@ public class LaunchProvider extends DependencyProvider { if (getExtension().isForge()) { launchConfig + // Should match YarnNamingService.PATH_TO_MAPPINGS in forge-runtime .property("fabric.yarnWithSrg.path", getExtension().getMappingsProvider().tinyMappingsWithSrg.toAbsolutePath().toString()) .argument("--fml.mcVersion") From 479594deab21180651ee315ef15ce23bebf938c0 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:57:19 +0300 Subject: [PATCH 50/56] Update TMP and fix license check --- forge-runtime/build.gradle | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/forge-runtime/build.gradle b/forge-runtime/build.gradle index 8c6e5fff..8155b279 100644 --- a/forge-runtime/build.gradle +++ b/forge-runtime/build.gradle @@ -35,7 +35,10 @@ repositories { } dependencies { - include ('net.fabricmc:tiny-mappings-parser:0.2.2.14') + // shadowed + include ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') + + // guaranteed to be there at runtime compileOnly ('cpw.mods:modlauncher:6.1.3') compileOnly ('org.spongepowered:mixin:0.8.2') compileOnly ('com.google.code.gson:gson:2.8.6') @@ -59,7 +62,7 @@ assemble.dependsOn shadowJar license { header rootProject.file("HEADER") include "**/*.java" - exclude '**/loom/inject/mixin/MixinIntermediaryDevRemapper.java' + exclude '**/loom/forgeruntime/mixin/MixinIntermediaryDevRemapper.java' } checkstyle { From 8bba3fe765245c1ff29417533b6824dceb95d07d Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 23:01:47 +0300 Subject: [PATCH 51/56] Fix publication coordinates --- forge-runtime/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-runtime/build.gradle b/forge-runtime/build.gradle index 8155b279..ea477a1f 100644 --- a/forge-runtime/build.gradle +++ b/forge-runtime/build.gradle @@ -73,6 +73,7 @@ checkstyle { publishing { publications { maven(MavenPublication) { + artifactId = 'architectury-loom-forge-runtime' from components.java } } From 20f1e9460186a46b509a976d54ff0f3b74224989 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 23:10:40 +0300 Subject: [PATCH 52/56] Use typesafe constants instead of ints --- forge-runtime/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-runtime/build.gradle b/forge-runtime/build.gradle index ea477a1f..031bdb5d 100644 --- a/forge-runtime/build.gradle +++ b/forge-runtime/build.gradle @@ -10,8 +10,8 @@ group = rootProject.group archivesBaseName = 'architectury-loom-forge-runtime' version = rootProject.version -sourceCompatibility = 8 -targetCompatibility = 8 +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 configurations { include From 9bdd99282e9ff2b55f5f20b99cf6f3f8ede4bff9 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Mon, 28 Jun 2021 23:58:00 +0300 Subject: [PATCH 53/56] Fix publishing --- forge-runtime/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-runtime/build.gradle b/forge-runtime/build.gradle index 031bdb5d..f7bf4e4a 100644 --- a/forge-runtime/build.gradle +++ b/forge-runtime/build.gradle @@ -74,7 +74,7 @@ publishing { publications { maven(MavenPublication) { artifactId = 'architectury-loom-forge-runtime' - from components.java + shadow.component it } } From 2a47b28fde45db3d43dc12aa69f5d606912bff00 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Tue, 29 Jun 2021 00:15:16 +0300 Subject: [PATCH 54/56] Ignore Forge name mapping service provider --- .../providers/forge/MinecraftPatchedProvider.java | 12 +++++++++--- .../providers/mappings/MappingsProviderImpl.java | 1 - 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index 995cb208..786d5509 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -28,7 +28,6 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.UncheckedIOException; @@ -76,7 +75,6 @@ import org.objectweb.asm.tree.ClassNode; import org.zeroturnaround.zip.ZipUtil; import net.fabricmc.loom.configuration.DependencyProvider; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.util.Checksum; @@ -92,6 +90,8 @@ import net.fabricmc.loom.util.srg.SpecialSourceExecutor; import net.fabricmc.mapping.tree.TinyTree; public class MinecraftPatchedProvider extends DependencyProvider { + private static final String NAME_MAPPING_SERVICE_PATH = "/META-INF/services/cpw.mods.modlauncher.api.INameMappingService"; + // Step 1: Remap Minecraft to SRG private File minecraftClientSrgJar; private File minecraftServerSrgJar; @@ -557,7 +557,13 @@ public class MinecraftPatchedProvider extends DependencyProvider { } private void copyUserdevFiles(File source, File target) throws IOException { - walkFileSystems(source, target, file -> true, fs -> Collections.singleton(fs.getPath("inject")), (sourceFs, targetFs, sourcePath, targetPath) -> { + // Removes the Forge name mapping service definition so that our own is used. + // If there are multiple name mapping services with the same "understanding" pair + // (source -> target namespace pair), modlauncher throws a fit and will crash. + // To use our YarnNamingService instead of MCPNamingService, we have to remove this file. + Predicate filter = file -> !file.toString().equals(NAME_MAPPING_SERVICE_PATH); + + walkFileSystems(source, target, filter, fs -> Collections.singleton(fs.getPath("inject")), (sourceFs, targetFs, sourcePath, targetPath) -> { Path parent = targetPath.getParent(); if (parent != null) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index 8f319f61..373f6ab5 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -46,7 +46,6 @@ import com.google.common.base.Preconditions; import com.google.common.base.Stopwatch; import com.google.common.net.UrlEscapers; import com.google.gson.JsonObject; -import dev.architectury.mappingslayers.api.utils.MappingsUtils; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.util.StringUtils; import org.gradle.api.Project; From f240b0f39f7984f596a45ee0b4eaf7941e62ce9a Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Tue, 29 Jun 2021 01:12:52 +0300 Subject: [PATCH 55/56] Fix the previous --- .../configuration/providers/forge/MinecraftPatchedProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index 786d5509..eaf1c825 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -90,7 +90,7 @@ import net.fabricmc.loom.util.srg.SpecialSourceExecutor; import net.fabricmc.mapping.tree.TinyTree; public class MinecraftPatchedProvider extends DependencyProvider { - private static final String NAME_MAPPING_SERVICE_PATH = "/META-INF/services/cpw.mods.modlauncher.api.INameMappingService"; + private static final String NAME_MAPPING_SERVICE_PATH = "/inject/META-INF/services/cpw.mods.modlauncher.api.INameMappingService"; // Step 1: Remap Minecraft to SRG private File minecraftClientSrgJar; From ba9e99d9f1970d91df67eb11b20b2666323fafd0 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Tue, 29 Jun 2021 16:59:37 +0800 Subject: [PATCH 56/56] Implement "Loom-Patch-Version" Signed-off-by: shedaniel --- .../forge/MinecraftPatchedProvider.java | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index eaf1c825..579b31d0 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -28,7 +28,9 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.io.PrintStream; import java.io.UncheckedIOException; import java.lang.reflect.Field; @@ -44,11 +46,15 @@ import java.util.Arrays; import java.util.Collections; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.jar.Attributes; +import java.util.jar.Manifest; import java.util.stream.Stream; +import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableMap; @@ -90,6 +96,8 @@ import net.fabricmc.loom.util.srg.SpecialSourceExecutor; import net.fabricmc.mapping.tree.TinyTree; public class MinecraftPatchedProvider extends DependencyProvider { + private static final String LOOM_PATCH_VERSION_KEY = "Loom-Patch-Version"; + private static final String CURRENT_LOOM_PATCH_VERSION = "2"; private static final String NAME_MAPPING_SERVICE_PATH = "/inject/META-INF/services/cpw.mods.modlauncher.api.INameMappingService"; // Step 1: Remap Minecraft to SRG @@ -110,12 +118,14 @@ public class MinecraftPatchedProvider extends DependencyProvider { @Nullable private File projectAt = null; private boolean atDirty = false; + private boolean filesDirty = false; public MinecraftPatchedProvider(Project project) { super(project); } public void initFiles() throws IOException { + filesDirty = false; projectAtHash = new File(getExtension().getProjectPersistentCache(), "at.sha256"); SourceSet main = getProject().getConvention().findPlugin(JavaPluginConvention.class).getSourceSets().getByName("main"); @@ -172,7 +182,8 @@ public class MinecraftPatchedProvider extends DependencyProvider { minecraftServerPatchedOfficialJar = new File(projectDir, "server-patched.jar"); minecraftMergedPatchedJar = new File(projectDir, "merged-patched.jar"); - if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(Predicates.not(File::exists))) { + if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(Predicates.not(File::exists)) + || !isPatchedSrgJarUpdateToDate(minecraftClientPatchedSrgJar) || !isPatchedSrgJarUpdateToDate(minecraftServerPatchedSrgJar)) { cleanAllCache(); } else if (atDirty || Stream.of(getProjectCache()).anyMatch(Predicates.not(File::exists))) { cleanProjectCache(); @@ -251,6 +262,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { mergeJars(getProject().getLogger()); } + this.filesDirty = dirty; this.dirty = false; } @@ -272,7 +284,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { String[] mappingsPath = {null}; if (!ZipUtil.handle(mcpProvider.getMcp(), "config.json", (in, zipEntry) -> { - mappingsPath[0] = new JsonParser().parse(new InputStreamReader(in)).getAsJsonObject().get("data").getAsJsonObject().get("mappings").getAsString(); + mappingsPath[0] = JsonParser.parseReader(new InputStreamReader(in)).getAsJsonObject().get("data").getAsJsonObject().get("mappings").getAsString(); })) { throw new IllegalStateException("Failed to find 'config.json' in " + mcpProvider.getMcp().getAbsolutePath() + "!"); } @@ -341,6 +353,28 @@ public class MinecraftPatchedProvider extends DependencyProvider { }); } + private boolean isPatchedSrgJarUpdateToDate(File jar) { + if (!jar.exists()) return false; + + boolean[] upToDate = {false}; + + if (!ZipUtil.handle(jar, "META-INF/MANIFEST.MF", (in, zipEntry) -> { + Manifest manifest = new Manifest(in); + Attributes attributes = manifest.getMainAttributes(); + String value = attributes.getValue(LOOM_PATCH_VERSION_KEY); + + if (Objects.equals(value, CURRENT_LOOM_PATCH_VERSION)) { + upToDate[0] = true; + } else { + getProject().getLogger().lifecycle(":forge patched jars not up to date. current version: " + value); + } + })) { + return false; + } + + return upToDate[0]; + } + private void accessTransformForge(Logger logger) throws Exception { for (Environment environment : Environment.values()) { String side = environment.side(); @@ -572,6 +606,22 @@ public class MinecraftPatchedProvider extends DependencyProvider { Files.copy(sourcePath, targetPath); }); + + try (FileSystemUtil.FileSystemDelegate delegate = FileSystemUtil.getJarFileSystem(target, false)) { + Path manifestPath = delegate.get().getPath("META-INF/MANIFEST.MF"); + + Preconditions.checkArgument(Files.exists(manifestPath), "META-INF/MANIFEST.MF does not exist in patched srg jar!"); + Manifest manifest = new Manifest(); + + try (InputStream stream = Files.newInputStream(manifestPath)) { + manifest.read(stream); + manifest.getMainAttributes().putValue(LOOM_PATCH_VERSION_KEY, CURRENT_LOOM_PATCH_VERSION); + } + + try (OutputStream stream = Files.newOutputStream(manifestPath)) { + manifest.write(stream); + } + } } public File getMergedJar() { @@ -583,7 +633,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { } public boolean isAtDirty() { - return atDirty; + return atDirty || filesDirty; } @Override