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

Legacy Support #36

Merged
merged 29 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d440826
Legacy
shartte Jun 23, 2024
51eeafd
First steps of source remapping
shartte Jul 15, 2024
d5b878e
Remapping seems to work (?)
shartte Jul 15, 2024
27caaa9
WIP
shartte Jul 18, 2024
36970e3
Allow setting the JRE for tools.
shartte Jul 19, 2024
5150fbb
Allow setting the JRE for tools.
shartte Jul 19, 2024
415f103
legacy
shartte Jul 19, 2024
89fda21
Added more versions.
shartte Jul 29, 2024
b9048b0
Finish 1.19.2 vanilla
shartte Jul 29, 2024
8ec4d1e
Pass the renamed output for sources
Matyrobbrt Sep 5, 2024
ace05a7
Inject another step for Parchment post-remap in legacy mode
Matyrobbrt Sep 5, 2024
fec4f7d
Addressed Review Comments
shartte Sep 5, 2024
1ba707e
Refactor
shartte Sep 5, 2024
0ac2f33
Add a result to chain mappings
Matyrobbrt Sep 6, 2024
66521cd
More changes related to mapping output
Matyrobbrt Sep 6, 2024
b7ee31e
Change srgToOfficial to SRG format
Matyrobbrt Sep 7, 2024
c5350f4
Rename the mappings set
Matyrobbrt Sep 7, 2024
072c573
Output TSRGv1 instead of v2
Matyrobbrt Sep 7, 2024
eef55fb
Rework ProcessGeneration a bit.
shartte Sep 7, 2024
c98a40a
Merge branch 'main' into legacy
shartte Sep 7, 2024
e506b93
Add 1.17 test and add info about it.
shartte Sep 7, 2024
aa1f082
Merge branch 'main' into legacy
shartte Sep 7, 2024
f59ad5e
Add more excludes for merge
shartte Sep 7, 2024
d4b3277
Run tools added by NFRT always under the JRE that NFRT uses.
shartte Sep 8, 2024
5b10af8
minor rename +refactor
shartte Sep 8, 2024
29e41fa
minor rename +refactor
shartte Sep 8, 2024
37c1c49
Make useHostJavaExecutable internal.
shartte Sep 8, 2024
bf9b5d3
Rename results.
shartte Sep 8, 2024
b44e476
Fix run config
shartte Sep 8, 2024
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
16 changes: 16 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'org.eclipse.jdt:ecj:3.38.0'
implementation 'net.fabricmc:fabric-loom-native:0.2.1'
implementation 'net.neoforged:srgutils:1.0.9'
annotationProcessor 'info.picocli:picocli-codegen:4.7.6'

testImplementation platform('org.junit:junit-bom:5.10.0')
Expand Down Expand Up @@ -190,6 +191,21 @@ idea {
programParameters = "run --dist joined --neoform net.neoforged:neoform:1.20.6-20240429.153634@zip --write-result=compiled:build/minecraft.jar --write-result=clientResources:build/client-extra.jar --write-result=sources:build/minecraft-sources.jar"
moduleRef(project, sourceSets.main)
}
"Run NeoForge 1.20.1 (joined)"(Application) {
mainClass = mainClassName
programParameters = "run --dist joined --neoforge net.neoforged:forge:1.20.1-47.1.54:userdev --parchment-data=org.parchmentmc.data:parchment-1.20.1:2023.09.03@zip --parchment-conflict-prefix=p_ --write-result=officialToSrgMapping:build/1.20.1.tsrg --write-result=compiledWithNeoForge:build/1.20.1-minecraft.jar --write-result=clientResources:build/1.20.1-client-extra.jar --write-result=sourcesWithNeoForge:build/1.20.1-minecraft-sources.jar"
moduleRef(project, sourceSets.main)
}
"Run Forge 1.12.2 (joined)"(Application) {
mainClass = mainClassName
programParameters = "run --dist joined --add-repository https://maven.minecraftforge.net --neoforge net.minecraftforge:forge:1.12.2-14.23.5.2860:userdev3 --write-result=compiledWithNeoForge:build/1.12.2-minecraft.jar --write-result=clientResources:build/1.12.2-client-extra.jar --write-result=sourcesWithNeoForge:build/1.12.2-minecraft-sources.jar"
moduleRef(project, sourceSets.main)
}
"Run Forge 1.17.1 (joined)"(Application) {
mainClass = mainClassName
programParameters = "run --dist joined --add-repository https://maven.minecraftforge.net --neoforge net.minecraftforge:forge:1.17.1-37.1.1:userdev --write-result=compiledWithNeoForge:build/1.17.1-minecraft.jar --write-result=clientResources:build/1.17.1-client-extra.jar --write-result=sourcesWithNeoForge:build/1.17.1-minecraft-sources.jar"
moduleRef(project, sourceSets.main)
}
"Run Neoform 1.19.2 (joined)"(Application) {
mainClass = mainClassName
programParameters = "run --dist joined --neoform de.oceanlabs.mcp:mcp_config:1.19.2@zip --write-result=compiled:build/minecraft.jar --write-result=clientResources:build/client-extra.jar --write-result=sources:build/minecraft-sources.jar"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package net.neoforged.neoform.runtime.actions;

import net.neoforged.neoform.runtime.engine.ProcessingEnvironment;
import net.neoforged.neoform.runtime.graph.ExecutionNodeAction;
import net.neoforged.srgutils.IMappingFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
* Creates different mapping files used by the legacy toolchain:
* <ul>
* <li>a {@code officialToSrg} TSRGv1 file that maps official names to SRG names</li>
* <li>a {@code srgToOfficial} SRG file (to please Mixin) that maps SRG names to official names</li>
* <li>a {@code csvMappings} zip file containing 2 csv files that map SRG names to official names</li>
* </ul>
*/
public class CreateLegacyMappingsAction implements ExecutionNodeAction {
@Override
public void run(ProcessingEnvironment environment) throws IOException, InterruptedException {
var first = environment.getRequiredInputPath("officialToObf");
var second = environment.getRequiredInputPath("obfToSrg");

var firstMappings = IMappingFile.load(first.toFile());
var secondMappings = IMappingFile.load(second.toFile());

var officialToSrg = firstMappings.chain(secondMappings);
officialToSrg.write(environment.getOutputPath("officialToSrg"), IMappingFile.Format.TSRG, false);

var srgToOfficial = officialToSrg.reverse();
srgToOfficial.write(environment.getOutputPath("srgToOfficial"), IMappingFile.Format.SRG, false);

try (var zipCsv = new ZipOutputStream(Files.newOutputStream(environment.getOutputPath("csvMappings")))) {
writeCsv(zipCsv, "methods.csv", srgToOfficial.getClasses().stream()
.flatMap(c -> c.getMethods().stream()).filter(c -> c.getOriginal().startsWith("m_")));
writeCsv(zipCsv, "fields.csv", srgToOfficial.getClasses().stream()
.flatMap(c -> c.getFields().stream()).filter(c -> c.getOriginal().startsWith("f_")));
}
}

private static void writeCsv(ZipOutputStream stream, String name, Stream<? extends IMappingFile.INode> nodes) throws IOException {
stream.putNextEntry(new ZipEntry(name));
stream.write(("searge,name,side,desc\n" + nodes.map(n -> n.getOriginal() + "," + n.getMapped() + ",0,").collect(Collectors.joining("\n"))).getBytes(StandardCharsets.UTF_8));
stream.closeEntry();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,28 @@ public class ExternalJavaToolAction implements ExecutionNodeAction {
private List<String> jvmArgs = new ArrayList<>();
private List<String> args = new ArrayList<>();

/**
* Tools that are referenced by the NeoForm/MCP process files usually are only guaranteed to run
* with the Java version that was current at the time.
* NFRT offers a --java-executable option to set an appropriate (older) Java version.
* Some tools, however, are referenced by NFRT itself and added to the graph, and those will usually
* only run with the Java that NFRT itself is running with.
* This option should be used for such tools.
*/
private final boolean useHostJavaExecutable;

public ExternalJavaToolAction(MavenCoordinate toolArtifactId) {
this.toolArtifactId = toolArtifactId;
// Tools referenced by maven coordinate come from the MCP/NeoForm config file and will usually only
// be tested against the Java version used by that Minecraft version.
this.useHostJavaExecutable = false;
}

public ExternalJavaToolAction(ToolCoordinate toolCoordinate) {
this.toolArtifactId = toolCoordinate.version();
// Tools referenced by tool coordinate are internal tools that are verified to run with the Java
// version that NFRT itself can run with.
this.useHostJavaExecutable = true;
}

@Override
Expand All @@ -57,10 +73,15 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt
toolArtifact = environment.getArtifactManager().get(toolArtifactId);
}

var javaExecutablePath = ProcessHandle.current()
.info()
.command()
.orElseThrow();
String javaExecutablePath;
if (useHostJavaExecutable) {
javaExecutablePath = environment.getJavaExecutable();
} else {
javaExecutablePath = ProcessHandle.current()
.info()
.command()
.orElseThrow();
}

var workingDir = environment.getWorkspace();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
Expand All @@ -26,10 +27,22 @@ public class InjectFromZipFileSource implements InjectSource {
* Folder within the ZIP we're copying from
*/
private final String sourcePath;
/**
* Optional regex for filtering which entries from this source will be injected.
* The relative path in the ZIP file will be matched against this regular expression.
* If the pattern is null, all entries are included.
*/
@Nullable
private final Pattern includeFilterPattern;

public InjectFromZipFileSource(ZipFile zf, String sourcePath) {
this(zf, sourcePath, null);
}

public InjectFromZipFileSource(ZipFile zf, String sourcePath, @Nullable Pattern includeFilterPattern) {
this.zf = zf;
this.sourcePath = sanitizeSourcePath(sourcePath);
this.includeFilterPattern = includeFilterPattern;
}

private static String sanitizeSourcePath(String sourcePath) {
Expand All @@ -55,7 +68,7 @@ public CacheKey.AnnotatedValue getCacheKey(FileHashService fileHashService) thro
var entries = zf.entries();
while (entries.hasMoreElements()) {
var entry = entries.nextElement();
if (sourcePath.isEmpty() || entry.getName().startsWith(sourcePath)) {
if ((sourcePath.isEmpty() || entry.getName().startsWith(sourcePath)) && matchesIncludeFilter(entry)) {
digestStream.write(entry.getName().getBytes());
try (var in = zf.getInputStream(entry)) {
in.transferTo(digestStream);
Expand All @@ -65,7 +78,7 @@ public CacheKey.AnnotatedValue getCacheKey(FileHashService fileHashService) thro

return new CacheKey.AnnotatedValue(
HexFormat.of().formatHex(digest.digest()),
sourcePath + " from " + zf.getName()
sourcePath + " from " + zf.getName() + (includeFilterPattern == null ? "" : " matching " + includeFilterPattern.pattern())
);
}

Expand All @@ -85,7 +98,7 @@ public void copyTo(ZipOutputStream out) throws IOException {
var entries = zf.entries();
while (entries.hasMoreElements()) {
var entry = entries.nextElement();
if (sourcePath.isEmpty() || entry.getName().startsWith(sourcePath)) {
if ((sourcePath.isEmpty() || entry.getName().startsWith(sourcePath)) && matchesIncludeFilter(entry)) {
try (var in = zf.getInputStream(entry)) {
// Relocate the entry
var copiedEntry = new ZipEntry(entry.getName().substring(sourcePath.length()));
Expand All @@ -108,4 +121,8 @@ public void copyTo(ZipOutputStream out) throws IOException {
}
}
}

private boolean matchesIncludeFilter(ZipEntry entry) {
return includeFilterPattern == null || includeFilterPattern.matcher(entry.getName()).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
* Injects additional content from {@linkplain InjectSource configurable sources} into a Zip (or Jar) file.
*/
public class InjectZipContentAction extends BuiltInAction {
private List<InjectSource> injectedSources;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public final class PatchActionFactory {
public static NodeOutput makeAction(ExecutionNodeBuilder builder,
Path patchesArchive,
String sourcePathInArchive,
NodeOutput sources) {
NodeOutput sources,
String basePathPrefix,
String modifiedPathPrefix) {
var patchesInZip = Objects.requireNonNull(sourcePathInArchive, "patches");
builder.input("input", sources.asInput());
var mainOutput = builder.output("output", NodeOutputType.ZIP, "ZIP file containing the patched sources");
Expand All @@ -30,7 +32,9 @@ public static NodeOutput makeAction(ExecutionNodeBuilder builder,
"--log-level", "WARN",
"--mode", "OFFSET",
"--archive-rejects", "ZIP",
"--reject", "{outputRejects}"
"--reject", "{outputRejects}",
"--base-path-prefix", basePathPrefix,
"--modified-path-prefix", modifiedPathPrefix
));

builder.action(action);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@
import java.util.List;

public abstract class RecompileSourcesAction extends BuiltInAction implements ExecutionNodeAction {

private final ExtensibleClasspath classpath = new ExtensibleClasspath();
private final ExtensibleClasspath sourcepath = new ExtensibleClasspath();
private int targetJavaVersion = 21;

@Override
public void computeCacheKey(CacheKeyBuilder ck) {
super.computeCacheKey(ck);
classpath.computeCacheKey("compile classpath", ck);
sourcepath.computeCacheKey("compile sourcepath", ck);
ck.add("target java version", String.valueOf(targetJavaVersion));
}

protected final List<Path> getEffectiveClasspath(ProcessingEnvironment environment) throws IOException {
Expand Down Expand Up @@ -53,4 +56,12 @@ public ExtensibleClasspath getClasspath() {
public ExtensibleClasspath getSourcepath() {
return sourcepath;
}

public int getTargetJavaVersion() {
return targetJavaVersion;
}

public void setTargetJavaVersion(int targetJavaVersion) {
this.targetJavaVersion = targetJavaVersion;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class RecompileSourcesActionWithECJ extends RecompileSourcesAction {
@Override
public void run(ProcessingEnvironment environment) throws IOException, InterruptedException {
var sources = environment.getRequiredInputPath("sources");
var javaRelease = String.valueOf(getTargetJavaVersion());

// Merge the original Minecraft classpath with the libs required by additional patches that we made
var classpathPaths = getEffectiveClasspath(environment);
Expand All @@ -69,7 +70,7 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt
true,
new AccessRuleSet(new AccessRule[0], AccessRestriction.COMMAND_LINE, library.getFileName().toString()),
"none",
"21"
javaRelease
));
}

Expand All @@ -81,9 +82,9 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt
var policy = DefaultErrorHandlingPolicies.exitOnFirstError();

var options = new CompilerOptions(Map.of(
CompilerOptions.OPTION_Source, "21",
CompilerOptions.OPTION_Compliance, "21",
CompilerOptions.OPTION_TargetPlatform, "21",
CompilerOptions.OPTION_Source, javaRelease,
CompilerOptions.OPTION_Compliance, javaRelease,
CompilerOptions.OPTION_TargetPlatform, javaRelease,
CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE,
CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED,
CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,6 @@
* Uses the current JDKs java compiler interface to recompile the sources.
*/
public class RecompileSourcesActionWithJDK extends RecompileSourcesAction {
private final List<String> compilerOptions = new ArrayList<>();

public RecompileSourcesActionWithJDK() {
compilerOptions.add("--release");
compilerOptions.add("21");
compilerOptions.add("-proc:none"); // No annotation processing on Minecraft sources
compilerOptions.add("-nowarn"); // We have no influence on Minecraft sources, so no warnings
compilerOptions.add("-g"); // Gradle compiles with debug by default, so we replicate this
compilerOptions.add("-XDuseUnsharedTable=true"); // Gradle also adds this unconditionally
compilerOptions.add("-implicit:none"); // Prevents source files from the source-path from being emitted
}

@Override
public void run(ProcessingEnvironment environment) throws IOException, InterruptedException {
var sources = environment.getRequiredInputPath("sources");
Expand Down Expand Up @@ -84,7 +72,7 @@ public void report(Diagnostic<? extends JavaFileObject> d) {
fileManager.setLocationFromPaths(StandardLocation.SOURCE_PATH, sourcepath);

var sourceJavaFiles = fileManager.getJavaFileObjectsFromPaths(sourcePaths);
var task = compiler.getTask(null, fileManager, diagnostics, compilerOptions, null, sourceJavaFiles);
var task = compiler.getTask(null, fileManager, diagnostics, getCompilerOptions(), null, sourceJavaFiles);
if (!task.call()) {
throw new IOException("Compilation failed");
}
Expand All @@ -106,6 +94,18 @@ public void report(Diagnostic<? extends JavaFileObject> d) {
public void computeCacheKey(CacheKeyBuilder ck) {
super.computeCacheKey(ck);
ck.add("compiler type", "javac");
ck.addStrings("compiler options", compilerOptions);
ck.addStrings("compiler options", getCompilerOptions());
}

private List<String> getCompilerOptions() {
return List.of(
"--release",
String.valueOf(getTargetJavaVersion()),
"-proc:none", // No annotation processing on Minecraft sources
"-nowarn", // We have no influence on Minecraft sources, so no warnings
"-g", // Gradle compiles with debug by default, so we replicate this
"-XDuseUnsharedTable=true", // Gradle also adds this unconditionally
"-implicit:none" // Prevents source files from the source-path from being emitted
);
}
}
Loading