Migrate mapping improvements. (#1416)

* Migrate mapping improvements.

* Revert to old logic

* Fix

* Add --overrideInputsIHaveABackup

* Skip task when input is empty

* Fix again

* Update MM
This commit is contained in:
modmuss
2025-11-01 08:25:46 +00:00
committed by GitHub
parent 2e16a97f08
commit e41982c51e
6 changed files with 154 additions and 6 deletions

View File

@@ -8,8 +8,8 @@ tiny-remapper = "0.12.0"
clazz-tweaker = "0.1.1" clazz-tweaker = "0.1.1"
mapping-io = "0.7.1" mapping-io = "0.7.1"
lorenz-tiny = "4.0.2" lorenz-tiny = "4.0.2"
mercury = "0.4.2" mercury = "0.4.3"
mercury-mixin = "0.1.0" mercury-mixin = "0.2.1"
loom-native = "0.2.0" loom-native = "0.2.0"
unpick = "3.0.0-beta.9" unpick = "3.0.0-beta.9"

View File

@@ -49,6 +49,7 @@ import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.LoomVersions; import net.fabricmc.loom.util.LoomVersions;
import net.fabricmc.loom.util.Platform; import net.fabricmc.loom.util.Platform;
import net.fabricmc.loom.util.gradle.GradleUtils; import net.fabricmc.loom.util.gradle.GradleUtils;
import net.fabricmc.loom.util.gradle.SourceSetHelper;
public abstract class LoomTasks implements Runnable { public abstract class LoomTasks implements Runnable {
@Inject @Inject
@@ -59,8 +60,24 @@ public abstract class LoomTasks implements Runnable {
@Override @Override
public void run() { public void run() {
getTasks().register("migrateMappings", MigrateMappingsTask.class, t -> { SourceSetHelper.getSourceSets(getProject()).all(sourceSet -> {
t.setDescription("Migrates mappings to a new version."); if (SourceSetHelper.isMainSourceSet(sourceSet)) {
getTasks().register("migrateMappings", MigrateMappingsTask.class, t -> {
t.setDescription("Migrates mappings to a new version.");
});
return;
}
if (!SourceSetHelper.getFirstSrcDir(sourceSet).exists()) {
return;
}
getTasks().register(sourceSet.getTaskName("migrate", "mappings"), MigrateMappingsTask.class, t -> {
t.setDescription("Migrates mappings to a new version.");
t.getInputDir().set(SourceSetHelper.getFirstSrcDir(sourceSet));
t.getOutputDir().convention(getProject().getLayout().getProjectDirectory().dir(sourceSet.getTaskName("remapped", "src")));
});
}); });
var generateLog4jConfig = getTasks().register("generateLog4jConfig", GenerateLog4jConfigTask.class, t -> { var generateLog4jConfig = getTasks().register("generateLog4jConfig", GenerateLog4jConfigTask.class, t -> {

View File

@@ -24,17 +24,22 @@
package net.fabricmc.loom.task; package net.fabricmc.loom.task;
import java.nio.file.Files;
import java.nio.file.Path;
import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property; import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory; import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.SkipWhenEmpty;
import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.UntrackedTask; import org.gradle.api.tasks.UntrackedTask;
import org.gradle.api.tasks.options.Option; import org.gradle.api.tasks.options.Option;
import net.fabricmc.loom.task.service.MigrateMappingsService; import net.fabricmc.loom.task.service.MigrateMappingsService;
import net.fabricmc.loom.util.DeletingFileVisitor;
import net.fabricmc.loom.util.service.ScopedServiceFactory; import net.fabricmc.loom.util.service.ScopedServiceFactory;
@UntrackedTask(because = "Always rerun this task.") @UntrackedTask(because = "Always rerun this task.")
@@ -44,6 +49,7 @@ public abstract class MigrateMappingsTask extends AbstractLoomTask {
public abstract Property<String> getMappings(); public abstract Property<String> getMappings();
@InputDirectory @InputDirectory
@SkipWhenEmpty
@Option(option = "input", description = "Java source file directory") @Option(option = "input", description = "Java source file directory")
public abstract DirectoryProperty getInputDir(); public abstract DirectoryProperty getInputDir();
@@ -51,6 +57,10 @@ public abstract class MigrateMappingsTask extends AbstractLoomTask {
@Option(option = "output", description = "Remapped source output directory") @Option(option = "output", description = "Remapped source output directory")
public abstract DirectoryProperty getOutputDir(); public abstract DirectoryProperty getOutputDir();
@Input
@Option(option = "overrideInputsIHaveABackup", description = "Override input files with the remapped files")
public abstract Property<Boolean> getOverrideInputs();
@Nested @Nested
protected abstract Property<MigrateMappingsService.Options> getMigrationServiceOptions(); protected abstract Property<MigrateMappingsService.Options> getMigrationServiceOptions();
@@ -58,6 +68,7 @@ public abstract class MigrateMappingsTask extends AbstractLoomTask {
getInputDir().convention(getProject().getLayout().getProjectDirectory().dir("src/main/java")); getInputDir().convention(getProject().getLayout().getProjectDirectory().dir("src/main/java"));
getOutputDir().convention(getProject().getLayout().getProjectDirectory().dir("remappedSrc")); getOutputDir().convention(getProject().getLayout().getProjectDirectory().dir("remappedSrc"));
getMigrationServiceOptions().set(MigrateMappingsService.createOptions(getProject(), getMappings(), getInputDir(), getOutputDir())); getMigrationServiceOptions().set(MigrateMappingsService.createOptions(getProject(), getMappings(), getInputDir(), getOutputDir()));
getOverrideInputs().convention(false);
} }
@TaskAction @TaskAction
@@ -66,5 +77,13 @@ public abstract class MigrateMappingsTask extends AbstractLoomTask {
MigrateMappingsService service = serviceFactory.get(getMigrationServiceOptions().get()); MigrateMappingsService service = serviceFactory.get(getMigrationServiceOptions().get());
service.migrateMapppings(); service.migrateMapppings();
} }
if (getOverrideInputs().get()) {
Path inputPath = getInputDir().getAsFile().get().toPath();
Path outputPath = getOutputDir().getAsFile().get().toPath();
DeletingFileVisitor.deleteDirectory(inputPath);
Files.move(outputPath, inputPath);
}
} }
} }

View File

@@ -58,6 +58,8 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl;
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsFactory; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsFactory;
import net.fabricmc.loom.configuration.providers.mappings.TinyMappingsService; import net.fabricmc.loom.configuration.providers.mappings.TinyMappingsService;
import net.fabricmc.loom.util.DeletingFileVisitor;
import net.fabricmc.loom.util.ExceptionUtil;
import net.fabricmc.loom.util.service.Service; import net.fabricmc.loom.util.service.Service;
import net.fabricmc.loom.util.service.ServiceFactory; import net.fabricmc.loom.util.service.ServiceFactory;
import net.fabricmc.loom.util.service.ServiceType; import net.fabricmc.loom.util.service.ServiceType;
@@ -117,7 +119,10 @@ public class MigrateMappingsService extends Service<MigrateMappingsService.Optio
throw new IllegalArgumentException("Could not find input directory: " + inputDir.toAbsolutePath()); throw new IllegalArgumentException("Could not find input directory: " + inputDir.toAbsolutePath());
} }
Files.deleteIfExists(outputDir); if (Files.exists(outputDir)) {
DeletingFileVisitor.deleteDirectory(outputDir);
}
Files.createDirectories(outputDir); Files.createDirectories(outputDir);
Mercury mercury = new Mercury(); Mercury mercury = new Mercury();
@@ -146,7 +151,13 @@ public class MigrateMappingsService extends Service<MigrateMappingsService.Optio
outputDir outputDir
); );
} catch (Exception e) { } catch (Exception e) {
LOGGER.warn("Could not remap fully!", e); try {
DeletingFileVisitor.deleteDirectory(outputDir);
} catch (IOException ignored) {
// Nope
}
throw ExceptionUtil.createDescriptiveWrapper(RuntimeException::new, "Failed to migrate mappings", e);
} }
// clean file descriptors // clean file descriptors

View File

@@ -87,6 +87,10 @@ public final class SourceSetHelper {
return getSourceSetByName(SourceSet.MAIN_SOURCE_SET_NAME, project); return getSourceSetByName(SourceSet.MAIN_SOURCE_SET_NAME, project);
} }
public static boolean isMainSourceSet(SourceSet sourceSet) {
return SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName());
}
public static SourceSet createSourceSet(String name, Project project) { public static SourceSet createSourceSet(String name, Project project) {
return getSourceSets(project).create(name); return getSourceSets(project).create(name);
} }
@@ -303,4 +307,14 @@ public final class SourceSetHelper {
return null; return null;
} }
public static File getFirstSrcDir(SourceSet sourceSet) {
Iterator<File> iterator = sourceSet.getJava().getSrcDirs().iterator();
if (iterator.hasNext()) {
return iterator.next();
}
throw new IllegalStateException("SourceSet " + sourceSet.getName() + " has no source directories.");
}
} }

View File

@@ -157,4 +157,91 @@ class MigrateMappingsTest extends Specification implements GradleProjectTestTrai
where: where:
version << STANDARD_TEST_VERSIONS version << STANDARD_TEST_VERSIONS
} }
@Unroll
def "Migrate client mappings (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << """
loom {
splitEnvironmentSourceSets()
}
dependencies {
minecraft 'com.mojang:minecraft:24w36a'
mappings 'net.fabricmc:yarn:24w36a+build.6:v2'
}
""".stripIndent()
def sourceFile = new File(gradle.projectDir, "src/client/java/example/Test.java")
sourceFile.parentFile.mkdirs()
sourceFile.text = """
package example;
import net.minecraft.predicate.entity.InputPredicate;
public class Test {
public static void main(String[] args) {
InputPredicate cls = null;
}
}
"""
when:
def result = gradle.run(tasks: [
"migrateClientMappings",
"--mappings",
"net.minecraft:mappings:24w36a"
])
def remapped = new File(gradle.projectDir, "remappedClientSrc/example/Test.java").text
then:
result.task(":migrateClientMappings").outcome == SUCCESS
remapped.contains("import net.minecraft.advancements.critereon.InputPredicate;")
where:
version << STANDARD_TEST_VERSIONS
}
@Unroll
def "Override inputs (gradle #version)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: version)
gradle.buildGradle << """
dependencies {
minecraft 'com.mojang:minecraft:24w36a'
mappings 'net.fabricmc:yarn:24w36a+build.6:v2'
}
""".stripIndent()
def sourceFile = new File(gradle.projectDir, "src/main/java/example/Test.java")
sourceFile.parentFile.mkdirs()
sourceFile.text = """
package example;
import net.minecraft.predicate.entity.InputPredicate;
public class Test {
public static void main(String[] args) {
InputPredicate cls = null;
}
}
"""
when:
def result = gradle.run(tasks: [
"migrateMappings",
"--mappings",
"net.minecraft:mappings:24w36a",
"--overrideInputsIHaveABackup"
])
def remapped = new File(gradle.projectDir, "src/main/java/example/Test.java").text
then:
result.task(":migrateMappings").outcome == SUCCESS
remapped.contains("import net.minecraft.advancements.critereon.InputPredicate;")
where:
version << STANDARD_TEST_VERSIONS
}
} }