mirror of https://github.com/FabricMC/yarn.git
Move jar remapping to Filament (#3300)
* Move jar remapping to Filament * Replace MapJarTask.libraryDir with a file collection * Use a more compact format for the task properties
This commit is contained in:
parent
9c83509bfc
commit
a7bf49e655
125
build.gradle
125
build.gradle
|
@ -12,7 +12,6 @@ buildscript {
|
|||
classpath "net.fabricmc:stitch:${project.stitch_version}"
|
||||
classpath "commons-io:commons-io:2.11.0"
|
||||
classpath "de.undercouch:gradle-download-task:4.1.1"
|
||||
classpath "net.fabricmc:tiny-remapper:${project.tiny_remapper_version}"
|
||||
classpath "net.fabricmc.unpick:unpick:${project.unpick_version}"
|
||||
classpath "net.fabricmc.unpick:unpick-format-utils:${project.unpick_version}"
|
||||
classpath "net.fabricmc:name-proposal:${project.name_proposal_version}"
|
||||
|
@ -119,22 +118,16 @@ import cuchaz.enigma.command.CheckMappingsCommand
|
|||
import cuchaz.enigma.command.ComposeMappingsCommand
|
||||
import cuchaz.enigma.command.ConvertMappingsCommand
|
||||
import cuchaz.enigma.command.MapSpecializedMethodsCommand
|
||||
import groovy.io.FileType
|
||||
import groovy.json.JsonSlurper
|
||||
import net.fabricmc.filament.task.MapJarTask
|
||||
import net.fabricmc.stitch.commands.CommandMergeTiny
|
||||
import net.fabricmc.stitch.commands.CommandReorderTiny
|
||||
import net.fabricmc.stitch.commands.CommandRewriteIntermediary
|
||||
import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2
|
||||
import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2
|
||||
import net.fabricmc.stitch.merge.JarMerger
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath
|
||||
import net.fabricmc.tinyremapper.TinyRemapper
|
||||
import net.fabricmc.tinyremapper.TinyUtils
|
||||
import net.fabricmc.nameproposal.MappingNameCompleter
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.objectweb.asm.ClassVisitor
|
||||
import org.objectweb.asm.FieldVisitor
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
@ -417,34 +410,24 @@ task patchIntermediary(dependsOn: [mergeJars, downloadIntermediary]) {
|
|||
}
|
||||
}
|
||||
|
||||
task mapIntermediaryJar(dependsOn: [downloadMcLibs, downloadIntermediary, mergeJars]) {
|
||||
task mapIntermediaryJar(type: MapJarTask, dependsOn: [downloadMcLibs, downloadIntermediary, mergeJars]) {
|
||||
group = mapJarGroup
|
||||
inputs.files downloadMcLibs.outputs.files.files
|
||||
outputs.file(intermediaryJar)
|
||||
|
||||
//Force the task to always run
|
||||
outputs.upToDateWhen { false }
|
||||
|
||||
doLast {
|
||||
logger.lifecycle(":mapping minecraft to intermediary")
|
||||
def tinyInput = downloadIntermediary.dest
|
||||
mapJar(intermediaryJar, mergedFile, tinyInput, libraries, "official", "intermediary")
|
||||
}
|
||||
output = intermediaryJar
|
||||
input = mergedFile
|
||||
mappings = downloadIntermediary.dest
|
||||
classpath.from fileTree(libraries)
|
||||
from = 'official'
|
||||
to = 'intermediary'
|
||||
}
|
||||
|
||||
task mapServerIntermediaryJar(dependsOn: [downloadMcLibs, downloadIntermediary, extractServerJar]) {
|
||||
task mapServerIntermediaryJar(type: MapJarTask, dependsOn: [downloadMcLibs, downloadIntermediary, extractServerJar]) {
|
||||
group = mapJarGroup
|
||||
inputs.files downloadMcLibs.outputs.files.files
|
||||
outputs.file(serverIntermediaryJar)
|
||||
|
||||
//Force the task to always run
|
||||
outputs.upToDateWhen { false }
|
||||
|
||||
doLast {
|
||||
logger.lifecycle(":mapping minecraft server to intermediary")
|
||||
def tinyInput = downloadIntermediary.dest
|
||||
mapJar(serverIntermediaryJar, serverJar, tinyInput, libraries, "official", "intermediary")
|
||||
}
|
||||
output = serverIntermediaryJar
|
||||
input = serverJar
|
||||
mappings = downloadIntermediary.dest
|
||||
classpath.from fileTree(libraries)
|
||||
from = 'official'
|
||||
to = 'intermediary'
|
||||
}
|
||||
|
||||
task yarnUnpicked(dependsOn: "unpickIntermediaryJar", type: EnigmaTask) {
|
||||
|
@ -636,33 +619,6 @@ task importMappingsOfficial(dependsOn: invertIntermediary) {
|
|||
}
|
||||
}
|
||||
|
||||
task mapNamedJar(dependsOn: ["mergeV2", "unpickIntermediaryJar"]) {
|
||||
group = mapJarGroup
|
||||
inputs.files downloadMcLibs.outputs.files.files
|
||||
outputs.file(namedJar)
|
||||
|
||||
//Force the task to always run
|
||||
outputs.upToDateWhen { false }
|
||||
|
||||
def jsrToJetbrains = [
|
||||
"javax/annotation/Nullable": "org/jetbrains/annotations/Nullable",
|
||||
"javax/annotation/Nonnull": "org/jetbrains/annotations/NotNull",
|
||||
"javax/annotation/concurrent/Immutable": "org/jetbrains/annotations/Unmodifiable"
|
||||
]
|
||||
|
||||
doLast {
|
||||
logger.lifecycle(":mapping minecraft to named")
|
||||
|
||||
mapJar(namedJar, unpickedJar, mergeV2.output, libraries, "intermediary", "named") {
|
||||
it.withMappings { out ->
|
||||
jsrToJetbrains.each { e ->
|
||||
out.acceptClass e.key, e.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
combineUnpickDefinitions {
|
||||
group = 'unpick'
|
||||
input = file('unpick-definitions')
|
||||
|
@ -821,6 +777,21 @@ task v2MergedYarnJar(dependsOn: ["mergeV2"], type: Jar) {
|
|||
}
|
||||
}
|
||||
|
||||
task mapNamedJar(type: MapJarTask, dependsOn: ["mergeV2", "unpickIntermediaryJar"]) {
|
||||
group = mapJarGroup
|
||||
output = namedJar
|
||||
input = unpickedJar
|
||||
mappings = mergeV2.output
|
||||
classpath.from fileTree(libraries)
|
||||
from = 'intermediary'
|
||||
to = 'named'
|
||||
classMappings = [
|
||||
"javax/annotation/Nullable": "org/jetbrains/annotations/Nullable",
|
||||
"javax/annotation/Nonnull": "org/jetbrains/annotations/NotNull",
|
||||
"javax/annotation/concurrent/Immutable": "org/jetbrains/annotations/Unmodifiable"
|
||||
]
|
||||
}
|
||||
|
||||
def fakeSourceDir = file(".gradle/temp/fakeSource")
|
||||
task genFakeSource(type: JavaExec, dependsOn: ["mergeV2", "mapNamedJar"]) {
|
||||
group = "javadoc generation"
|
||||
|
@ -1003,42 +974,6 @@ task checkVersion {
|
|||
|
||||
publish.mustRunAfter checkVersion
|
||||
|
||||
void mapJar(File output, File input, File mappings, File libraries, String from, String to,
|
||||
Action<TinyRemapper.Builder> action = { }) {
|
||||
if (output.exists()) {
|
||||
output.delete()
|
||||
}
|
||||
|
||||
def remapperBuilder = TinyRemapper.newRemapper()
|
||||
.withMappings(TinyUtils.createTinyMappingProvider(mappings.toPath(), from, to))
|
||||
.renameInvalidLocals(true)
|
||||
.rebuildSourceFilenames(true)
|
||||
.invalidLvNamePattern(~/\$\$\d+/)
|
||||
.inferNameFromSameLvIndex(true)
|
||||
|
||||
action.execute(remapperBuilder)
|
||||
def remapper = remapperBuilder
|
||||
.build()
|
||||
|
||||
try {
|
||||
def outputConsumerBuilder = new OutputConsumerPath.Builder(output.toPath())
|
||||
// expose output consumer builder to function if there is need in the future
|
||||
def outputConsumer = outputConsumerBuilder.build()
|
||||
outputConsumer.addNonClassFiles(input.toPath())
|
||||
remapper.readInputs(input.toPath())
|
||||
|
||||
libraries.eachFileRecurse(FileType.FILES) { file ->
|
||||
remapper.readClassPath(file.toPath())
|
||||
}
|
||||
remapper.apply(outputConsumer)
|
||||
outputConsumer.close()
|
||||
remapper.finish()
|
||||
} catch (Exception e) {
|
||||
remapper.finish()
|
||||
throw new RuntimeException("Failed to remap jar", e)
|
||||
}
|
||||
}
|
||||
|
||||
class FileOutput extends DefaultTask {
|
||||
@OutputFile
|
||||
File output
|
||||
|
|
|
@ -26,6 +26,7 @@ dependencies {
|
|||
implementation "net.fabricmc.unpick:unpick:$properties.unpick_version"
|
||||
implementation "net.fabricmc.unpick:unpick-format-utils:$properties.unpick_version"
|
||||
implementation "net.fabricmc:tiny-mappings-parser:$properties.tiny_mappings_parser_version"
|
||||
implementation "net.fabricmc:tiny-remapper:$properties.tiny_remapper_version"
|
||||
|
||||
testImplementation platform("org.junit:junit-bom:$properties.junit_version")
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.FileSystemLocation;
|
||||
import org.gradle.api.file.FileVisitDetails;
|
||||
import org.gradle.api.file.FileVisitor;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.MapProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.workers.WorkAction;
|
||||
import org.gradle.workers.WorkParameters;
|
||||
import org.gradle.workers.WorkQueue;
|
||||
import org.gradle.workers.WorkerExecutor;
|
||||
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import net.fabricmc.tinyremapper.TinyUtils;
|
||||
|
||||
public abstract class MapJarTask extends DefaultTask {
|
||||
@InputFile public abstract RegularFileProperty getInput();
|
||||
@InputFile public abstract RegularFileProperty getMappings();
|
||||
@OutputFile public abstract RegularFileProperty getOutput();
|
||||
@Classpath public abstract ConfigurableFileCollection getClasspath();
|
||||
@Input public abstract Property<String> getFrom();
|
||||
@Input public abstract Property<String> getTo();
|
||||
@Input public abstract MapProperty<String, String> getClassMappings();
|
||||
|
||||
@Inject
|
||||
protected abstract WorkerExecutor getWorkerExecutor();
|
||||
|
||||
public MapJarTask() {
|
||||
getClassMappings().convention(Map.of());
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void remap() {
|
||||
getProject().getLogger().lifecycle(":remapping {} from {} to {}", getInput().get().getAsFile(), getFrom().get(), getTo().get());
|
||||
|
||||
WorkQueue workQueue = getWorkerExecutor().noIsolation();
|
||||
workQueue.submit(RemapAction.class, parameters -> {
|
||||
parameters.getInput().set(getInput());
|
||||
parameters.getMappings().set(getMappings());
|
||||
parameters.getOutput().set(getOutput());
|
||||
parameters.getClasspath().setFrom(getClasspath());
|
||||
parameters.getFrom().set(getFrom());
|
||||
parameters.getTo().set(getTo());
|
||||
parameters.getClassMappings().set(getClassMappings());
|
||||
});
|
||||
}
|
||||
|
||||
public interface RemapParameters extends WorkParameters {
|
||||
@InputFile RegularFileProperty getInput();
|
||||
@InputFile RegularFileProperty getMappings();
|
||||
@OutputFile RegularFileProperty getOutput();
|
||||
@Classpath ConfigurableFileCollection getClasspath();
|
||||
@Input Property<String> getFrom();
|
||||
@Input Property<String> getTo();
|
||||
@Input MapProperty<String, String> getClassMappings();
|
||||
}
|
||||
|
||||
public abstract static class RemapAction implements WorkAction<RemapParameters> {
|
||||
@Inject
|
||||
public RemapAction() {
|
||||
}
|
||||
|
||||
private static Path getPath(Provider<? extends FileSystemLocation> provider) {
|
||||
return provider.get().getAsFile().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
doExecute();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to remap jar: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void doExecute() throws IOException {
|
||||
RemapParameters params = getParameters();
|
||||
Path output = getPath(params.getOutput());
|
||||
Files.deleteIfExists(output);
|
||||
|
||||
TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper()
|
||||
.withMappings(TinyUtils.createTinyMappingProvider(getPath(params.getMappings()), params.getFrom().get(), params.getTo().get()))
|
||||
.renameInvalidLocals(true)
|
||||
.rebuildSourceFilenames(true)
|
||||
.invalidLvNamePattern(Pattern.compile("\\$\\$\\d+"))
|
||||
.inferNameFromSameLvIndex(true);
|
||||
remapperBuilder.withMappings(out -> params.getClassMappings().get().forEach(out::acceptClass));
|
||||
TinyRemapper remapper = remapperBuilder.build();
|
||||
|
||||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) {
|
||||
Path input = getPath(params.getInput());
|
||||
outputConsumer.addNonClassFiles(input);
|
||||
remapper.readInputs(input);
|
||||
|
||||
params.getClasspath().getAsFileTree().visit(new FileVisitor() {
|
||||
@Override
|
||||
public void visitDir(FileVisitDetails dirDetails) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFile(FileVisitDetails fileDetails) {
|
||||
remapper.readClassPath(fileDetails.getFile().toPath());
|
||||
}
|
||||
});
|
||||
|
||||
remapper.apply(outputConsumer);
|
||||
} finally {
|
||||
remapper.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue