Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new merge mappings command that works with partial parameter mappings. #13

Merged
merged 3 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
83 changes: 53 additions & 30 deletions src/main/java/net/neoforged/installertools/MergeMappings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<File> base = parser.accepts("base").withRequiredArg().ofType(File.class).required();
OptionSpec<Void> reverseBase = parser.accepts("reverse-base");
OptionSpec<File> merge = parser.accepts("merge").withRequiredArg().ofType(File.class).required();
OptionSpec<Void> reverseMerge = parser.accepts("reverse-merge");
OptionSpec<File> output = parser.accepts("output").withRequiredArg().ofType(File.class).required();
OptionSpec<Void> 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);
}
}
35 changes: 35 additions & 0 deletions src/test/java/net/neoforged/installertools/MergeMappingsTest.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
10 changes: 10 additions & 0 deletions src/test/resources/expected_merged_mappings.tsrg
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions src/test/resources/neoform_mappings.tsrg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
tsrg2 obf srg
a -
a (FF)V -
0 o p_254025_
1 o p_254401_
10 changes: 10 additions & 0 deletions src/test/resources/official.txt
Original file line number Diff line number Diff line change
@@ -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
Loading