From 3eb8c32ebd6792de4f8c6934d7e739d62722d2ee Mon Sep 17 00:00:00 2001 From: shartte Date: Wed, 11 Dec 2024 22:17:43 +0100 Subject: [PATCH] Add a new merge mappings command that works with partial parameter mappings. (#13) --- build.gradle | 6 ++ .../installertools/MergeMappings.java | 83 ++++++++++++------- .../installertools/MergeMappingsTest.java | 35 ++++++++ .../resources/expected_merged_mappings.tsrg | 10 +++ src/test/resources/neoform_mappings.tsrg | 5 ++ src/test/resources/official.txt | 10 +++ 6 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 src/test/java/net/neoforged/installertools/MergeMappingsTest.java create mode 100644 src/test/resources/expected_merged_mappings.tsrg create mode 100644 src/test/resources/neoform_mappings.tsrg create mode 100644 src/test/resources/official.txt diff --git a/build.gradle b/build.gradle index efcb160..340b86c 100644 --- a/build.gradle +++ b/build.gradle @@ -75,6 +75,12 @@ dependencies { implementation 'de.siegmar:fastcsv:2.0.0' implementation 'org.ow2.asm:asm-commons:9.3' implementation project(':cli-utils') + + testImplementation(libs.bundles.junit) +} + +test { + useJUnitPlatform() } publishing { diff --git a/src/main/java/net/neoforged/installertools/MergeMappings.java b/src/main/java/net/neoforged/installertools/MergeMappings.java index b131265..791a34d 100644 --- a/src/main/java/net/neoforged/installertools/MergeMappings.java +++ b/src/main/java/net/neoforged/installertools/MergeMappings.java @@ -18,42 +18,65 @@ */ package net.neoforged.installertools; +import joptsimple.OptionException; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; import net.neoforged.srgutils.IMappingFile; -import net.neoforged.srgutils.IRenamer; -import net.neoforged.srgutils.IMappingFile.IClass; -import net.neoforged.srgutils.IMappingFile.IField; -import net.neoforged.srgutils.IMappingFile.IMethod; -import net.neoforged.srgutils.IMappingFile.IPackage; -import net.neoforged.srgutils.IMappingFile.IParameter; -public class MergeMappings extends ChainMappings { +import java.io.File; +import java.io.IOException; + +public class MergeMappings extends Task { @Override - protected IRenamer makeRenamer(IMappingFile link, boolean classes, boolean fields, boolean methods, boolean params) { - return new IRenamer() { - public String rename(IPackage value) { - return link.remapPackage(value.getOriginal()); - } + public void process(String[] args) throws IOException { + OptionParser parser = new OptionParser(); + OptionSpec base = parser.accepts("base").withRequiredArg().ofType(File.class).required(); + OptionSpec reverseBase = parser.accepts("reverse-base"); + OptionSpec merge = parser.accepts("merge").withRequiredArg().ofType(File.class).required(); + OptionSpec reverseMerge = parser.accepts("reverse-merge"); + OptionSpec output = parser.accepts("output").withRequiredArg().ofType(File.class).required(); + OptionSpec reverseOutput = parser.accepts("reverse-output"); - public String rename(IClass value) { - return classes ? link.remapClass(value.getOriginal()) : value.getMapped(); - } + try { + OptionSet options = parser.parse(args); - public String rename(IField value) { - IClass cls = link.getClass(value.getParent().getOriginal()); - return cls == null || !fields ? value.getMapped() : cls.remapField(value.getOriginal()); - } + merge( + options.valueOf(base), + options.has(reverseBase), + options.valueOf(merge), + options.has(reverseMerge), + options.valueOf(output), + options.has(reverseOutput) + ); + } catch (OptionException e) { + parser.printHelpOn(System.out); + error("Please provide correct parameters"); + } + } - public String rename(IMethod value) { - IClass cls = link.getClass(value.getParent().getOriginal()); - return cls == null || !methods ? value.getMapped() : cls.remapMethod(value.getOriginal(), value.getDescriptor()); - } + private void merge(File baseFile, boolean reverseBase, + File mergeFile, boolean reverseMerge, + File outputFile, boolean reverseOutput) throws IOException { + log("Base Mappings: " + baseFile); + log("Reverse Base Mappings: " + reverseBase); + log("Merge Mappings: " + mergeFile); + log("Reverse Merge Mappings: " + reverseMerge); + log("Output: " + outputFile); + log("Reverse Output: " + reverseOutput); - public String rename(IParameter value) { - IMethod mtd = value.getParent(); - IClass cls = link.getClass(mtd.getParent().getOriginal()); - mtd = cls == null ? null : cls.getMethod(mtd.getOriginal(), mtd.getDescriptor()); - return mtd == null || !params ? value.getMapped() : mtd.remapParameter(value.getIndex(), value.getMapped()); - } - }; + IMappingFile baseMappings = IMappingFile.load(baseFile); + if (reverseBase) { + baseMappings = baseMappings.reverse(); + } + IMappingFile mergeMappings = IMappingFile.load(mergeFile); + if (reverseMerge) { + mergeMappings = mergeMappings.reverse(); + } + IMappingFile outputMappings = baseMappings.merge(mergeMappings); + if (reverseOutput) { + outputMappings = outputMappings.reverse(); + } + outputMappings.write(outputFile.toPath(), IMappingFile.Format.TSRG2, false); } } diff --git a/src/test/java/net/neoforged/installertools/MergeMappingsTest.java b/src/test/java/net/neoforged/installertools/MergeMappingsTest.java new file mode 100644 index 0000000..4ba0dc1 --- /dev/null +++ b/src/test/java/net/neoforged/installertools/MergeMappingsTest.java @@ -0,0 +1,35 @@ +package net.neoforged.installertools; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThat; + +class MergeMappingsTest { + @TempDir + Path tempDir; + + @Test + void testMergeMappings() throws Exception { + Path neoFormMappings = Paths.get(getClass().getResource("/neoform_mappings.tsrg").toURI()); + Path officialMappings = Paths.get(getClass().getResource("/official.txt").toURI()); + Path expectedMappings = Paths.get(getClass().getResource("/expected_merged_mappings.tsrg").toURI()); + Path outputPath = tempDir.resolve("output.txt"); + + // This is what NeoForm calls + new MergeMappings().process(new String[]{ + "--base", + officialMappings.toAbsolutePath().toString(), + "--reverse-base", + "--merge", + neoFormMappings.toAbsolutePath().toString(), + "--output", + outputPath.toString() + }); + + assertThat(outputPath).hasSameTextualContentAs(expectedMappings); + } +} diff --git a/src/test/resources/expected_merged_mappings.tsrg b/src/test/resources/expected_merged_mappings.tsrg new file mode 100644 index 0000000..9d90090 --- /dev/null +++ b/src/test/resources/expected_merged_mappings.tsrg @@ -0,0 +1,10 @@ +tsrg2 left right +a pkg/CoolName + a F NOT_MENTIONED_FIELD + a (FF)V coolMethod + 0 o p_254025_ + 1 o p_254401_ + b ()D noParams +b pkg/NotMentionedClass + a F NOT_MENTIONED_FIELD + b ()V notMentionedMethod diff --git a/src/test/resources/neoform_mappings.tsrg b/src/test/resources/neoform_mappings.tsrg new file mode 100644 index 0000000..35cd771 --- /dev/null +++ b/src/test/resources/neoform_mappings.tsrg @@ -0,0 +1,5 @@ +tsrg2 obf srg +a - + a (FF)V - + 0 o p_254025_ + 1 o p_254401_ diff --git a/src/test/resources/official.txt b/src/test/resources/official.txt new file mode 100644 index 0000000..56f8826 --- /dev/null +++ b/src/test/resources/official.txt @@ -0,0 +1,10 @@ +# This emulates the format used by mojang mappings +pkg.CoolName -> a: +# {"fileName":"CoolName.java","id":"sourceFile"} + float NOT_MENTIONED_FIELD -> a + 9:10:void coolMethod(float,float) -> a + 13:13:double noParams() -> b +pkg.NotMentionedClass -> b: +# {"fileName":"NotMentionedClass.java","id":"sourceFile"} + float NOT_MENTIONED_FIELD -> a + 6:8:void notMentionedMethod() -> b