mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-04-01 21:17:46 -05:00
Rewrite migrate mappings task to be configuration cache compatible. (#1167)
This commit is contained in:
@@ -31,10 +31,16 @@ import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
@@ -45,12 +51,29 @@ public final class TinyMappingsService extends Service<TinyMappingsService.Optio
|
||||
public static final ServiceType<Options, TinyMappingsService> TYPE = new ServiceType<>(Options.class, TinyMappingsService.class);
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@InputFile
|
||||
RegularFileProperty getMappings();
|
||||
@InputFiles
|
||||
ConfigurableFileCollection getMappings(); // Only a single file
|
||||
|
||||
/**
|
||||
* When present, the mappings will be read from the specified zip entry path.
|
||||
*/
|
||||
@Optional
|
||||
@Input
|
||||
Property<String> getZipEntryPath();
|
||||
}
|
||||
|
||||
public static Provider<Options> createOptions(Project project, Path mappings) {
|
||||
return TYPE.create(project, options -> options.getMappings().set(project.file(mappings)));
|
||||
return TYPE.create(project, options -> {
|
||||
options.getMappings().from(project.file(mappings));
|
||||
options.getZipEntryPath().unset();
|
||||
});
|
||||
}
|
||||
|
||||
public static Provider<Options> createOptions(Project project, FileCollection mappings, @Nullable String zipEntryPath) {
|
||||
return TYPE.create(project, options -> {
|
||||
options.getMappings().from(mappings);
|
||||
options.getZipEntryPath().set(zipEntryPath);
|
||||
});
|
||||
}
|
||||
|
||||
public TinyMappingsService(Options options, ServiceFactory serviceFactory) {
|
||||
@@ -58,14 +81,28 @@ public final class TinyMappingsService extends Service<TinyMappingsService.Optio
|
||||
}
|
||||
|
||||
private final Supplier<MemoryMappingTree> mappingTree = Suppliers.memoize(() -> {
|
||||
Path mappings = getOptions().getMappings().getSingleFile().toPath();
|
||||
|
||||
if (getOptions().getZipEntryPath().isPresent()) {
|
||||
try (FileSystemUtil.Delegate delegate = FileSystemUtil.getJarFileSystem(mappings)) {
|
||||
return readMappings(delegate.fs().getPath(getOptions().getZipEntryPath().get()));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings from zip", e);
|
||||
}
|
||||
}
|
||||
|
||||
return readMappings(mappings);
|
||||
});
|
||||
|
||||
private MemoryMappingTree readMappings(Path mappings) {
|
||||
try {
|
||||
MemoryMappingTree mappingTree = new MemoryMappingTree();
|
||||
MappingReader.read(getOptions().getMappings().get().getAsFile().toPath(), mappingTree);
|
||||
MappingReader.read(mappings, mappingTree);
|
||||
return mappingTree;
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MemoryMappingTree getMappingTree() {
|
||||
return mappingTree.get();
|
||||
|
||||
@@ -47,7 +47,6 @@ import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
@@ -246,12 +245,6 @@ public abstract class AbstractRemapJarTask extends Jar {
|
||||
return getInputFile();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Internal
|
||||
protected LoomGradleExtension getLoomExtension() {
|
||||
return LoomGradleExtension.get(getProject());
|
||||
}
|
||||
|
||||
private SourceSet getClientSourceSet() {
|
||||
Preconditions.checkArgument(LoomGradleExtension.get(getProject()).areEnvironmentSourceSetsSplit(), "Cannot get client sourceset as project is not split");
|
||||
return SourceSetHelper.getSourceSetByName(getClientOnlySourceSetName().get(), getProject());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2019-2022 FabricMC
|
||||
* Copyright (c) 2019-2024 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,189 +24,47 @@
|
||||
|
||||
package net.fabricmc.loom.task;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.cadixdev.lorenz.MappingSet;
|
||||
import org.cadixdev.mercury.Mercury;
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.IllegalDependencyNotation;
|
||||
import org.gradle.api.JavaVersion;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputDirectory;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.tasks.options.Option;
|
||||
import org.gradle.work.DisableCachingByDefault;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsFactory;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.task.service.MigrateMappingsService;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
import net.fabricmc.lorenztiny.TinyMappingsJoiner;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
@DisableCachingByDefault(because = "Always rerun this task.")
|
||||
public abstract class MigrateMappingsTask extends AbstractLoomTask {
|
||||
private Path inputDir;
|
||||
private Path outputDir;
|
||||
private String mappings;
|
||||
@Input
|
||||
@Option(option = "mappings", description = "Target mappings")
|
||||
public abstract Property<String> getMappings();
|
||||
|
||||
@InputDirectory
|
||||
@Option(option = "input", description = "Java source file directory")
|
||||
public abstract DirectoryProperty getInputDir();
|
||||
|
||||
@OutputDirectory
|
||||
@Option(option = "output", description = "Remapped source output directory")
|
||||
public abstract DirectoryProperty getOutputDir();
|
||||
|
||||
@Nested
|
||||
protected abstract Property<MigrateMappingsService.Options> getMigrationServiceOptions();
|
||||
|
||||
public MigrateMappingsTask() {
|
||||
inputDir = getProject().file("src/main/java").toPath();
|
||||
outputDir = getProject().file("remappedSrc").toPath();
|
||||
|
||||
// Ensure we resolve the classpath inputs before running the task.
|
||||
getCompileClasspath().from(getProject().getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
|
||||
|
||||
notCompatibleWithConfigurationCache("Not yet supported.");
|
||||
getInputDir().convention(getProject().getLayout().getProjectDirectory().dir("src/main/java"));
|
||||
getOutputDir().convention(getProject().getLayout().getProjectDirectory().dir("remappedSrc"));
|
||||
getMigrationServiceOptions().set(MigrateMappingsService.createOptions(getProject(), getMappings(), getInputDir(), getOutputDir()));
|
||||
}
|
||||
|
||||
@Option(option = "input", description = "Java source file directory")
|
||||
public void setInputDir(String inputDir) {
|
||||
this.inputDir = getProject().file(inputDir).toPath();
|
||||
}
|
||||
|
||||
@Option(option = "output", description = "Remapped source output directory")
|
||||
public void setOutputDir(String outputDir) {
|
||||
this.outputDir = getProject().file(outputDir).toPath();
|
||||
}
|
||||
|
||||
@Option(option = "mappings", description = "Target mappings")
|
||||
public void setMappings(String mappings) {
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
public abstract ConfigurableFileCollection getCompileClasspath();
|
||||
|
||||
@TaskAction
|
||||
public void doTask() throws Throwable {
|
||||
Project project = getProject();
|
||||
LoomGradleExtension extension = getExtension();
|
||||
|
||||
project.getLogger().info(":loading mappings");
|
||||
|
||||
if (!Files.exists(inputDir) || !Files.isDirectory(inputDir)) {
|
||||
throw new IllegalArgumentException("Could not find input directory: " + inputDir.toAbsolutePath());
|
||||
}
|
||||
|
||||
Files.createDirectories(outputDir);
|
||||
|
||||
File mappings = loadMappings();
|
||||
MappingConfiguration mappingConfiguration = extension.getMappingConfiguration();
|
||||
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
MemoryMappingTree currentMappings = mappingConfiguration.getMappingsService(project, serviceFactory).getMappingTree();
|
||||
MemoryMappingTree targetMappings = getMappings(mappings);
|
||||
migrateMappings(project, extension, inputDir, outputDir, currentMappings, targetMappings);
|
||||
project.getLogger().lifecycle(":remapped project written to " + outputDir.toAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Error while loading mappings", e);
|
||||
MigrateMappingsService service = serviceFactory.get(getMigrationServiceOptions().get());
|
||||
service.migrateMapppings();
|
||||
}
|
||||
}
|
||||
|
||||
private File loadMappings() {
|
||||
Project project = getProject();
|
||||
|
||||
if (mappings == null || mappings.isEmpty()) {
|
||||
throw new IllegalArgumentException("No mappings were specified. Use --mappings=\"\" to specify target mappings");
|
||||
}
|
||||
|
||||
Set<File> files;
|
||||
|
||||
try {
|
||||
if (mappings.startsWith("net.minecraft:mappings:")) {
|
||||
if (!mappings.endsWith(":" + LoomGradleExtension.get(project).getMinecraftProvider().minecraftVersion())) {
|
||||
throw new UnsupportedOperationException("Migrating Mojang mappings is currently only supported for the specified minecraft version");
|
||||
}
|
||||
|
||||
LayeredMappingsFactory dep = new LayeredMappingsFactory(LayeredMappingSpecBuilderImpl.buildOfficialMojangMappings());
|
||||
files = Collections.singleton(dep.resolve(getProject()).toFile());
|
||||
} else {
|
||||
Dependency dependency = project.getDependencies().create(mappings);
|
||||
files = project.getConfigurations().detachedConfiguration(dependency).resolve();
|
||||
}
|
||||
} catch (IllegalDependencyNotation ignored) {
|
||||
project.getLogger().info("Could not locate mappings, presuming V2 Yarn");
|
||||
|
||||
try {
|
||||
files = project.getConfigurations().detachedConfiguration(project.getDependencies().create(ImmutableMap.of("group", "net.fabricmc", "name", "yarn", "version", mappings, "classifier", "v2"))).resolve();
|
||||
} catch (GradleException ignored2) {
|
||||
project.getLogger().info("Could not locate mappings, presuming V1 Yarn");
|
||||
files = project.getConfigurations().detachedConfiguration(project.getDependencies().create(ImmutableMap.of("group", "net.fabricmc", "name", "yarn", "version", mappings))).resolve();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to resolve mappings", e);
|
||||
}
|
||||
|
||||
if (files.isEmpty()) {
|
||||
throw new IllegalArgumentException("Mappings could not be found");
|
||||
}
|
||||
|
||||
return Iterables.getOnlyElement(files);
|
||||
}
|
||||
|
||||
private static MemoryMappingTree getMappings(File mappings) throws IOException {
|
||||
MemoryMappingTree mappingTree = new MemoryMappingTree();
|
||||
|
||||
try (FileSystemUtil.Delegate delegate = FileSystemUtil.getJarFileSystem(mappings.toPath())) {
|
||||
MappingReader.read(delegate.fs().getPath("mappings/mappings.tiny"), mappingTree);
|
||||
}
|
||||
|
||||
return mappingTree;
|
||||
}
|
||||
|
||||
private static void migrateMappings(Project project, LoomGradleExtension extension,
|
||||
Path inputDir, Path outputDir, MemoryMappingTree currentMappings, MemoryMappingTree targetMappings
|
||||
) throws IOException {
|
||||
project.getLogger().info(":joining mappings");
|
||||
|
||||
MappingSet mappingSet = new TinyMappingsJoiner(
|
||||
currentMappings, MappingsNamespace.NAMED.toString(),
|
||||
targetMappings, MappingsNamespace.NAMED.toString(),
|
||||
MappingsNamespace.INTERMEDIARY.toString()
|
||||
).read();
|
||||
|
||||
project.getLogger().lifecycle(":remapping");
|
||||
Mercury mercury = SourceRemapper.createMercuryWithClassPath(project, false);
|
||||
|
||||
final JavaVersion javaVersion = project.getExtensions().getByType(JavaPluginExtension.class).getSourceCompatibility();
|
||||
mercury.setSourceCompatibility(javaVersion.toString());
|
||||
|
||||
for (Path intermediaryJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
|
||||
mercury.getClassPath().add(intermediaryJar);
|
||||
}
|
||||
|
||||
for (Path intermediaryJar : extension.getMinecraftJars(MappingsNamespace.NAMED)) {
|
||||
mercury.getClassPath().add(intermediaryJar);
|
||||
}
|
||||
|
||||
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
|
||||
|
||||
try {
|
||||
mercury.rewrite(inputDir, outputDir);
|
||||
} catch (Exception e) {
|
||||
project.getLogger().warn("Could not remap fully!", e);
|
||||
}
|
||||
|
||||
project.getLogger().info(":cleaning file descriptors");
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2024 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.task.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.cadixdev.lorenz.MappingSet;
|
||||
import org.cadixdev.mercury.Mercury;
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||
import org.gradle.api.IllegalDependencyNotation;
|
||||
import org.gradle.api.JavaVersion;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputDirectory;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsFactory;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.TinyMappingsService;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
import net.fabricmc.lorenztiny.TinyMappingsJoiner;
|
||||
|
||||
public class MigrateMappingsService extends Service<MigrateMappingsService.Options> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MigrateMappingsService.class);
|
||||
private static final ServiceType<Options, MigrateMappingsService> TYPE = new ServiceType<>(Options.class, MigrateMappingsService.class);
|
||||
|
||||
public MigrateMappingsService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@Nested
|
||||
Property<MappingsService.Options> getSourceMappings();
|
||||
@Nested
|
||||
Property<TinyMappingsService.Options> getTargetMappings();
|
||||
@InputDirectory
|
||||
DirectoryProperty getInputDir();
|
||||
@Input
|
||||
Property<String> getSourceCompatibility();
|
||||
@InputFiles
|
||||
ConfigurableFileCollection getClasspath();
|
||||
@OutputDirectory
|
||||
DirectoryProperty getOutputDir();
|
||||
}
|
||||
|
||||
public static Provider<Options> createOptions(Project project, Provider<String> targetMappings, DirectoryProperty inputDir, DirectoryProperty outputDir) {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final Provider<String> from = project.provider(() -> "intermediary");
|
||||
final Provider<String> to = project.provider(() -> "named");
|
||||
final JavaVersion javaVersion = project.getExtensions().getByType(JavaPluginExtension.class).getSourceCompatibility();
|
||||
|
||||
ConfigurableFileCollection classpath = project.getObjects().fileCollection();
|
||||
classpath.from(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
|
||||
// Question: why are both of these needed?
|
||||
classpath.from(extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY));
|
||||
classpath.from(extension.getMinecraftJars(MappingsNamespace.NAMED));
|
||||
|
||||
return TYPE.create(project, (o) -> {
|
||||
FileCollection targetMappingsFile = getTargetMappingsFile(project, targetMappings.get());
|
||||
o.getSourceMappings().set(MappingsService.createOptionsWithProjectMappings(project, from, to));
|
||||
o.getTargetMappings().set(TinyMappingsService.createOptions(project, targetMappingsFile, "mappings/mappings.tiny"));
|
||||
o.getSourceCompatibility().set(javaVersion.toString());
|
||||
o.getInputDir().set(inputDir);
|
||||
o.getClasspath().from(classpath);
|
||||
o.getOutputDir().set(outputDir);
|
||||
});
|
||||
}
|
||||
|
||||
public void migrateMapppings() throws IOException {
|
||||
final Path inputDir = getOptions().getInputDir().get().getAsFile().toPath();
|
||||
final Path outputDir = getOptions().getOutputDir().get().getAsFile().toPath();
|
||||
|
||||
if (!Files.exists(inputDir) || !Files.isDirectory(inputDir)) {
|
||||
throw new IllegalArgumentException("Could not find input directory: " + inputDir.toAbsolutePath());
|
||||
}
|
||||
|
||||
Files.deleteIfExists(outputDir);
|
||||
Files.createDirectories(outputDir);
|
||||
|
||||
Mercury mercury = new Mercury();
|
||||
mercury.setGracefulClasspathChecks(true);
|
||||
mercury.setSourceCompatibility(getOptions().getSourceCompatibility().get());
|
||||
|
||||
final MappingsService sourceMappingsService = getServiceFactory().get(getOptions().getSourceMappings().get());
|
||||
final TinyMappingsService targetMappingsService = getServiceFactory().get(getOptions().getTargetMappings().get());
|
||||
|
||||
final MappingSet mappingSet = new TinyMappingsJoiner(
|
||||
sourceMappingsService.getMemoryMappingTree(), MappingsNamespace.NAMED.toString(),
|
||||
targetMappingsService.getMappingTree(), MappingsNamespace.NAMED.toString(),
|
||||
MappingsNamespace.INTERMEDIARY.toString()
|
||||
).read();
|
||||
|
||||
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
|
||||
|
||||
for (File file : getOptions().getClasspath().getFiles()) {
|
||||
mercury.getClassPath().add(file.toPath());
|
||||
}
|
||||
|
||||
try {
|
||||
mercury.rewrite(
|
||||
inputDir,
|
||||
outputDir
|
||||
);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Could not remap fully!", e);
|
||||
}
|
||||
|
||||
// clean file descriptors
|
||||
System.gc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mappings file for the requested mappings.
|
||||
*/
|
||||
private static FileCollection getTargetMappingsFile(Project project, String mappings) {
|
||||
if (mappings == null || mappings.isEmpty()) {
|
||||
throw new IllegalArgumentException("No mappings were specified. Use --mappings=\"\" to specify target mappings");
|
||||
}
|
||||
|
||||
try {
|
||||
if (mappings.startsWith("net.minecraft:mappings:")) {
|
||||
if (!mappings.endsWith(":" + LoomGradleExtension.get(project).getMinecraftProvider().minecraftVersion())) {
|
||||
throw new UnsupportedOperationException("Migrating Mojang mappings is currently only supported for the specified minecraft version");
|
||||
}
|
||||
|
||||
LayeredMappingsFactory dep = new LayeredMappingsFactory(LayeredMappingSpecBuilderImpl.buildOfficialMojangMappings());
|
||||
return project.files(dep.resolve(project).toFile());
|
||||
} else {
|
||||
Dependency dependency = project.getDependencies().create(mappings);
|
||||
return project.getConfigurations().detachedConfiguration(dependency);
|
||||
}
|
||||
} catch (IllegalDependencyNotation ignored) {
|
||||
LOGGER.info("Could not locate mappings, presuming V2 Yarn");
|
||||
return project.getConfigurations().detachedConfiguration(project.getDependencies().create(ImmutableMap.of("group", "net.fabricmc", "name", "yarn", "version", mappings, "classifier", "v2")));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to resolve mappings", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
@@ -55,6 +56,8 @@ public class GradleTypeAdapter implements TypeAdapterFactory {
|
||||
return new FileCollectionTypeAdapter();
|
||||
} else if (RegularFileProperty.class.isAssignableFrom(rawClass)) {
|
||||
return new RegularFilePropertyTypeAdapter();
|
||||
} else if (DirectoryProperty.class.isAssignableFrom(rawClass)) {
|
||||
return new DirectoryPropertyTypeAdapter();
|
||||
} else if (ListProperty.class.isAssignableFrom(rawClass)) {
|
||||
return new ListPropertyTypeAdapter(gson);
|
||||
} else if (MapProperty.class.isAssignableFrom(rawClass)) {
|
||||
@@ -117,6 +120,19 @@ public class GradleTypeAdapter implements TypeAdapterFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DirectoryPropertyTypeAdapter<T extends DirectoryProperty> extends WriteOnlyTypeAdapter<T> {
|
||||
@Override
|
||||
public void write(JsonWriter out, T property) throws IOException {
|
||||
if (!property.isPresent()) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
|
||||
final File file = property.get().getAsFile();
|
||||
out.value(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ListPropertyTypeAdapter<T extends ListProperty<?>> extends WriteOnlyTypeAdapter<T> {
|
||||
private final Gson gson;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2021 FabricMC
|
||||
* Copyright (c) 2021-2024 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,20 +34,125 @@ import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
|
||||
|
||||
class MigrateMappingsTest extends Specification implements GradleProjectTestTrait {
|
||||
@Unroll
|
||||
def "Migrate mappings (gradle #version)"() {
|
||||
def "Migrate mappings yarn short hand (gradle #version)"() {
|
||||
setup:
|
||||
def gradle = gradleProject(project: "java16", version: version)
|
||||
def gradle = gradleProject(project: "minimalBase", version: version)
|
||||
gradle.buildGradle << """
|
||||
dependencies {
|
||||
minecraft 'com.mojang:minecraft:24w36a'
|
||||
mappings 'net.fabricmc:yarn:24w36a+build.2:v2'
|
||||
}
|
||||
""".stripIndent()
|
||||
|
||||
def sourceFile = new File(gradle.projectDir, "src/main/java/example/Test.java")
|
||||
sourceFile.parentFile.mkdirs()
|
||||
sourceFile.text = """
|
||||
package example;
|
||||
|
||||
import net.minecraft.class_10184;
|
||||
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
class_10184 cls = null;
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
when:
|
||||
def result = gradle.run(tasks: [
|
||||
"migrateMappings",
|
||||
"--mappings",
|
||||
"21w38a+build.10"
|
||||
"24w36a+build.6"
|
||||
])
|
||||
def remapped = new File(gradle.projectDir, "remappedSrc/example/Test.java").text
|
||||
|
||||
then:
|
||||
result.task(":migrateMappings").outcome == SUCCESS
|
||||
// TODO check it actually did something
|
||||
remapped.contains("import net.minecraft.predicate.entity.InputPredicate;")
|
||||
remapped.contains("InputPredicate cls = null;")
|
||||
|
||||
where:
|
||||
version << STANDARD_TEST_VERSIONS
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "Migrate mappings maven complete (gradle #version)"() {
|
||||
setup:
|
||||
def gradle = gradleProject(project: "minimalBase", version: version)
|
||||
gradle.buildGradle << """
|
||||
dependencies {
|
||||
minecraft 'com.mojang:minecraft:24w36a'
|
||||
mappings 'net.fabricmc:yarn:24w36a+build.2:v2'
|
||||
}
|
||||
""".stripIndent()
|
||||
|
||||
def sourceFile = new File(gradle.projectDir, "src/main/java/example/Test.java")
|
||||
sourceFile.parentFile.mkdirs()
|
||||
sourceFile.text = """
|
||||
package example;
|
||||
|
||||
import net.minecraft.class_10184;
|
||||
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
class_10184 cls = null;
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
when:
|
||||
def result = gradle.run(tasks: [
|
||||
"migrateMappings",
|
||||
"--mappings",
|
||||
"net.fabricmc:yarn:24w36a+build.6:v2"
|
||||
])
|
||||
def remapped = new File(gradle.projectDir, "remappedSrc/example/Test.java").text
|
||||
|
||||
then:
|
||||
result.task(":migrateMappings").outcome == SUCCESS
|
||||
remapped.contains("import net.minecraft.predicate.entity.InputPredicate;")
|
||||
remapped.contains("InputPredicate cls = null;")
|
||||
|
||||
where:
|
||||
version << STANDARD_TEST_VERSIONS
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "Migrate mappings to mojmap (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"
|
||||
])
|
||||
def remapped = new File(gradle.projectDir, "remappedSrc/example/Test.java").text
|
||||
|
||||
then:
|
||||
result.task(":migrateMappings").outcome == SUCCESS
|
||||
remapped.contains("import net.minecraft.advancements.critereon.InputPredicate;")
|
||||
|
||||
where:
|
||||
version << STANDARD_TEST_VERSIONS
|
||||
|
||||
Reference in New Issue
Block a user