mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-27 19:57:00 -05:00
Merge commit '9157c22448cb4847586772f8028010f717accc14' into dev/1.8
This commit is contained in:
@@ -27,7 +27,7 @@ import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.LfWriter;
|
||||
import net.fabricmc.loom.util.aw2at.Aw2At;
|
||||
import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
public final class ModBuildExtensions {
|
||||
public static Set<String> readMixinConfigsFromManifest(File jarFile) {
|
||||
@@ -49,7 +49,7 @@ public final class ModBuildExtensions {
|
||||
}
|
||||
}
|
||||
|
||||
public static void convertAwToAt(SetProperty<String> atAccessWidenersProperty, Path outputFile, Property<String> mappingBuildServiceUuid) throws IOException {
|
||||
public static void convertAwToAt(ServiceFactory serviceFactory, SetProperty<String> atAccessWidenersProperty, Path outputFile, Property<MappingsService.Options> options) throws IOException {
|
||||
if (!atAccessWidenersProperty.isPresent()) {
|
||||
return;
|
||||
}
|
||||
@@ -84,8 +84,8 @@ public final class ModBuildExtensions {
|
||||
Files.delete(awPath);
|
||||
}
|
||||
|
||||
MappingsService service = UnsafeWorkQueueHelper.get(mappingBuildServiceUuid, MappingsService.class);
|
||||
at = at.remap(service.getMemoryMappingTree(), service.getFromNamespace(), service.getToNamespace());
|
||||
MappingsService service = serviceFactory.get(options);
|
||||
at = at.remap(service.getMemoryMappingTree(), service.getFrom(), service.getTo());
|
||||
|
||||
try (Writer writer = new LfWriter(Files.newBufferedWriter(atPath))) {
|
||||
AccessTransformFormats.FML.write(writer, at);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
package net.fabricmc.loom.api.remapping;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
@@ -31,7 +33,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
*
|
||||
* <p>Design based off of Gradle's {@link org.gradle.workers.WorkParameters}.
|
||||
*/
|
||||
public interface RemapperParameters {
|
||||
public interface RemapperParameters extends Serializable {
|
||||
final class None implements RemapperParameters {
|
||||
@ApiStatus.Internal
|
||||
public static None INSTANCE = new None();
|
||||
|
||||
@@ -91,8 +91,8 @@ import net.fabricmc.loom.util.ExceptionUtil;
|
||||
import net.fabricmc.loom.util.ProcessUtil;
|
||||
import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
public abstract class CompileConfiguration implements Runnable {
|
||||
@Inject
|
||||
@@ -110,8 +110,8 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath()));
|
||||
});
|
||||
|
||||
afterEvaluationWithService((serviceManager) -> {
|
||||
final ConfigContext configContext = new ConfigContextImpl(getProject(), serviceManager, extension);
|
||||
afterEvaluationWithService((serviceFactory) -> {
|
||||
final ConfigContext configContext = new ConfigContextImpl(getProject(), serviceFactory, extension);
|
||||
|
||||
MinecraftSourceSets.get(getProject()).afterEvaluate(getProject());
|
||||
|
||||
@@ -129,7 +129,7 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
|
||||
LoomDependencyManager dependencyManager = new LoomDependencyManager();
|
||||
extension.setDependencyManager(dependencyManager);
|
||||
dependencyManager.handleDependencies(getProject(), serviceManager);
|
||||
dependencyManager.handleDependencies(getProject(), serviceFactory);
|
||||
} catch (Exception e) {
|
||||
ExceptionUtil.processException(e, getProject());
|
||||
disownLock();
|
||||
@@ -159,7 +159,7 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
// because of https://github.com/architectury/architectury-loom/issues/72.
|
||||
if (!ModConfigurationRemapper.isCIBuild()) {
|
||||
try {
|
||||
ForgeSourcesRemapper.addBaseForgeSources(getProject());
|
||||
ForgeSourcesRemapper.addBaseForgeSources(getProject(), configContext.serviceFactory());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -225,7 +225,7 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
setupDependencyProviders(project, extension);
|
||||
|
||||
final DependencyInfo mappingsDep = DependencyInfo.create(getProject(), Configurations.MAPPINGS);
|
||||
final MappingConfiguration mappingConfiguration = MappingConfiguration.create(getProject(), configContext.serviceManager(), mappingsDep, minecraftProvider);
|
||||
final MappingConfiguration mappingConfiguration = MappingConfiguration.create(getProject(), configContext.serviceFactory(), mappingsDep, minecraftProvider);
|
||||
extension.setMappingConfiguration(mappingConfiguration);
|
||||
|
||||
if (extension.isForgeLike()) {
|
||||
@@ -241,7 +241,7 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
}
|
||||
|
||||
if (minecraftProvider instanceof ForgeMinecraftProvider patched) {
|
||||
patched.getPatchedProvider().remapJar();
|
||||
patched.getPatchedProvider().remapJar(configContext.serviceFactory());
|
||||
}
|
||||
|
||||
// Provide the remapped mc jars
|
||||
@@ -540,10 +540,12 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
dependencyProviders.handleDependencies(project);
|
||||
}
|
||||
|
||||
private void afterEvaluationWithService(Consumer<SharedServiceManager> consumer) {
|
||||
private void afterEvaluationWithService(Consumer<ServiceFactory> consumer) {
|
||||
GradleUtils.afterSuccessfulEvaluation(getProject(), () -> {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
consumer.accept(serviceManager);
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
consumer.accept(serviceFactory);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ package net.fabricmc.loom.configuration;
|
||||
import org.gradle.api.Project;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
public interface ConfigContext {
|
||||
Project project();
|
||||
SharedServiceManager serviceManager();
|
||||
ServiceFactory serviceFactory();
|
||||
LoomGradleExtension extension();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ package net.fabricmc.loom.configuration;
|
||||
import org.gradle.api.Project;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
public record ConfigContextImpl(Project project, SharedServiceManager serviceManager, LoomGradleExtension extension) implements ConfigContext {
|
||||
public record ConfigContextImpl(Project project, ServiceFactory serviceFactory, LoomGradleExtension extension) implements ConfigContext {
|
||||
}
|
||||
|
||||
@@ -29,18 +29,18 @@ import org.gradle.api.Project;
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.configuration.mods.ModConfigurationRemapper;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
public class LoomDependencyManager {
|
||||
public void handleDependencies(Project project, SharedServiceManager serviceManager) {
|
||||
public void handleDependencies(Project project, ServiceFactory serviceFactory) {
|
||||
project.getLogger().info(":setting up loom dependencies");
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
SourceRemapper sourceRemapper = new SourceRemapper(project, serviceManager, true);
|
||||
SourceRemapper sourceRemapper = new SourceRemapper(project, serviceFactory, true);
|
||||
String platformSuffix = extension.isForgeLike() ? "_forge" : extension.isQuilt() ? "_arch_quilt" : "";
|
||||
String mappingsIdentifier = extension.getMappingConfiguration().mappingsIdentifier() + platformSuffix;
|
||||
|
||||
ModConfigurationRemapper.supplyModConfigurations(project, serviceManager, mappingsIdentifier, extension, sourceRemapper);
|
||||
ModConfigurationRemapper.supplyModConfigurations(project, serviceFactory, mappingsIdentifier, extension, sourceRemapper);
|
||||
|
||||
sourceRemapper.remapAll();
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ExceptionUtil;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class ModConfigurationRemapper {
|
||||
@@ -76,7 +76,7 @@ public class ModConfigurationRemapper {
|
||||
// This can happen when the dependency is a FileCollectionDependency or from a flatDir repository.
|
||||
public static final String MISSING_GROUP = "unspecified";
|
||||
|
||||
public static void supplyModConfigurations(Project project, SharedServiceManager serviceManager, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) {
|
||||
public static void supplyModConfigurations(Project project, ServiceFactory serviceFactory, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) {
|
||||
final DependencyHandler dependencies = project.getDependencies();
|
||||
// The configurations where the source and remapped artifacts go.
|
||||
// key: source, value: target
|
||||
@@ -202,7 +202,7 @@ public class ModConfigurationRemapper {
|
||||
|
||||
if (!toRemap.isEmpty()) {
|
||||
try {
|
||||
new ModProcessor(project, sourceConfig, serviceManager).processMods(toRemap);
|
||||
new ModProcessor(project, sourceConfig, serviceFactory).processMods(toRemap);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to remap mods", e);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinClasspathService;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.srg.AtClassRemapper;
|
||||
import net.fabricmc.loom.util.srg.CoreModClassRemapper;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
@@ -81,12 +81,12 @@ public class ModProcessor {
|
||||
|
||||
private final Project project;
|
||||
private final Configuration sourceConfiguration;
|
||||
private final SharedServiceManager serviceManager;
|
||||
private final ServiceFactory serviceFactory;
|
||||
|
||||
public ModProcessor(Project project, Configuration sourceConfiguration, SharedServiceManager serviceManager) {
|
||||
public ModProcessor(Project project, Configuration sourceConfiguration, ServiceFactory serviceFactory) {
|
||||
this.project = project;
|
||||
this.sourceConfiguration = sourceConfiguration;
|
||||
this.serviceManager = serviceManager;
|
||||
this.serviceFactory = serviceFactory;
|
||||
}
|
||||
|
||||
public void processMods(List<ModDependency> remapList) throws IOException {
|
||||
@@ -174,7 +174,7 @@ public class ModProcessor {
|
||||
}
|
||||
|
||||
MappingOption mappingOption = MappingOption.forPlatform(extension);
|
||||
MemoryMappingTree mappings = mappingConfiguration.getMappingsService(serviceManager, mappingOption).getMappingTree();
|
||||
MemoryMappingTree mappings = mappingConfiguration.getMappingsService(project, serviceManager, mappingOption).getMappingTree();
|
||||
LoggerFilter.replaceSystemOut();
|
||||
|
||||
TinyRemapper.Builder builder = TinyRemapper.newRemapper()
|
||||
@@ -183,7 +183,7 @@ public class ModProcessor {
|
||||
.renameInvalidLocals(false)
|
||||
.extraAnalyzeVisitor(AccessWidenerAnalyzeVisitorProvider.createFromMods(fromM, remapList, extension.getPlatform().get()));
|
||||
|
||||
final KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project);
|
||||
final KotlinClasspathService kotlinClasspathService = serviceFactory.getOrNull(KotlinClasspathService.createOptions(project));
|
||||
KotlinRemapperClassloader kotlinRemapperClassloader = null;
|
||||
|
||||
if (kotlinClasspathService != null) {
|
||||
@@ -201,7 +201,7 @@ public class ModProcessor {
|
||||
}
|
||||
|
||||
for (RemapperExtensionHolder holder : extension.getRemapperExtensions().get()) {
|
||||
holder.apply(builder, fromM, toM, project.getObjects());
|
||||
holder.apply(builder, fromM, toM);
|
||||
}
|
||||
|
||||
final TinyRemapper remapper = builder.build();
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class ContextImplHelper {
|
||||
public static LazyCloseable<TinyRemapper> createRemapper(ConfigContext configContext, MappingsNamespace from, MappingsNamespace to) {
|
||||
return new LazyCloseable<>(() -> {
|
||||
try {
|
||||
TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(configContext.project(), configContext.serviceManager(), from.toString(), to.toString());
|
||||
TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(configContext.project(), configContext.serviceFactory(), from.toString(), to.toString());
|
||||
|
||||
for (Path minecraftJar : configContext.extension().getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
|
||||
tinyRemapper.readClassPath(minecraftJar);
|
||||
|
||||
@@ -66,6 +66,6 @@ public record ProcessorContextImpl(ConfigContext configContext, MinecraftJar min
|
||||
public MemoryMappingTree getMappings() {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(configContext().project());
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(extension);
|
||||
return extension.getMappingConfiguration().getMappingsService(configContext().serviceManager(), mappingOption).getMappingTree();
|
||||
return extension.getMappingConfiguration().getMappingsService(configContext().project(), configContext().serviceFactory(), mappingOption).getMappingTree();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
|
||||
import dev.architectury.loom.forge.UserdevConfig;
|
||||
import dev.architectury.loom.util.MappingOption;
|
||||
import dev.architectury.loom.util.TempFiles;
|
||||
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.logging.LogLevel;
|
||||
import org.gradle.api.logging.Logger;
|
||||
@@ -83,8 +86,6 @@ import net.fabricmc.loom.util.ThreadingUtils;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.function.FsPathConsumer;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.srg.CoreModClassRemapper;
|
||||
import net.fabricmc.loom.util.srg.InnerClassRemapper;
|
||||
import net.fabricmc.mappingio.tree.MappingTree;
|
||||
@@ -207,12 +208,9 @@ public class MinecraftPatchedProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public void remapJar() throws Exception {
|
||||
public void remapJar(ServiceFactory serviceFactory) throws Exception {
|
||||
if (dirty) {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
remapPatchedJar(serviceManager);
|
||||
}
|
||||
|
||||
remapPatchedJar(serviceFactory);
|
||||
fillClientExtraJar();
|
||||
}
|
||||
|
||||
@@ -226,9 +224,9 @@ public class MinecraftPatchedProvider {
|
||||
copyNonClassFiles(minecraftProvider.getMinecraftClientJar().toPath(), minecraftClientExtra);
|
||||
}
|
||||
|
||||
private TinyRemapper buildRemapper(SharedServiceManager serviceManager, Path input) throws IOException {
|
||||
private TinyRemapper buildRemapper(ServiceFactory serviceFactory, Path input) throws IOException {
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(getExtension());
|
||||
TinyMappingsService mappingsService = getExtension().getMappingConfiguration().getMappingsService(serviceManager, mappingOption);
|
||||
TinyMappingsService mappingsService = getExtension().getMappingConfiguration().getMappingsService(project, serviceFactory, mappingOption);
|
||||
final String sourceNamespace = IntermediaryNamespaces.intermediary(project);
|
||||
MemoryMappingTree mappings = mappingsService.getMappingTree();
|
||||
|
||||
@@ -408,7 +406,7 @@ public class MinecraftPatchedProvider {
|
||||
project.getLogger().lifecycle(":access transformed minecraft in " + stopwatch.stop());
|
||||
}
|
||||
|
||||
private void remapPatchedJar(SharedServiceManager serviceManager) throws Exception {
|
||||
private void remapPatchedJar(ServiceFactory serviceFactory) throws Exception {
|
||||
logger.lifecycle(":remapping minecraft (TinyRemapper, srg -> official)");
|
||||
Path mcInput = minecraftPatchedIntermediateAtJar;
|
||||
Path mcOutput = minecraftPatchedJar;
|
||||
@@ -416,7 +414,7 @@ public class MinecraftPatchedProvider {
|
||||
Path forgeUserdevJar = getForgeUserdevJar().toPath();
|
||||
Files.deleteIfExists(mcOutput);
|
||||
|
||||
TinyRemapper remapper = buildRemapper(serviceManager, mcInput);
|
||||
TinyRemapper remapper = buildRemapper(serviceFactory, mcInput);
|
||||
|
||||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(mcOutput).build()) {
|
||||
outputConsumer.addNonClassFiles(mcInput);
|
||||
@@ -435,13 +433,13 @@ public class MinecraftPatchedProvider {
|
||||
}
|
||||
|
||||
copyUserdevFiles(forgeUserdevJar, mcOutput);
|
||||
remapCoreMods(mcOutput, serviceManager);
|
||||
remapCoreMods(mcOutput, serviceFactory);
|
||||
applyLoomPatchVersion(mcOutput);
|
||||
}
|
||||
|
||||
private void remapCoreMods(Path patchedJar, SharedServiceManager serviceManager) throws Exception {
|
||||
private void remapCoreMods(Path patchedJar, ServiceFactory serviceFactory) throws Exception {
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(getExtension());
|
||||
final TinyMappingsService mappingsService = getExtension().getMappingConfiguration().getMappingsService(serviceManager, mappingOption);
|
||||
final TinyMappingsService mappingsService = getExtension().getMappingConfiguration().getMappingsService(project, serviceFactory, mappingOption);
|
||||
final MappingTree mappings = mappingsService.getMappingTree();
|
||||
CoreModClassRemapper.remapJar(project, getExtension().getPlatform().get(), patchedJar, mappings);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
package net.fabricmc.loom.configuration.providers.mappings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -39,7 +41,7 @@ import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingContext;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
|
||||
import net.fabricmc.loom.util.download.DownloadBuilder;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public class GradleMappingContext implements MappingContext {
|
||||
@@ -74,8 +76,11 @@ public class GradleMappingContext implements MappingContext {
|
||||
@Override
|
||||
public Supplier<MemoryMappingTree> intermediaryTree() {
|
||||
return () -> {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
return IntermediateMappingsService.getInstance(serviceManager, project, minecraftProvider()).getMemoryMappingTree();
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
IntermediateMappingsService intermediateMappingsService = serviceFactory.get(IntermediateMappingsService.createOptions(project, minecraftProvider()));
|
||||
return intermediateMappingsService.getMemoryMappingTree();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,77 +31,101 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
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.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
import net.fabricmc.mappingio.adapter.MappingNsCompleter;
|
||||
import net.fabricmc.mappingio.format.tiny.Tiny2FileReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public final class IntermediateMappingsService implements SharedService {
|
||||
private final Path intermediaryTiny;
|
||||
private final String expectedSrcNs;
|
||||
public final class IntermediateMappingsService extends Service<IntermediateMappingsService.Options> {
|
||||
public static final ServiceType<Options, IntermediateMappingsService> TYPE = new ServiceType<>(Options.class, IntermediateMappingsService.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(IntermediateMappingsService.class);
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@InputFile
|
||||
RegularFileProperty getIntermediaryTiny();
|
||||
@Input
|
||||
Property<String> getExpectedSrcNs();
|
||||
@Input
|
||||
Property<String> getMinecraftVersion();
|
||||
}
|
||||
|
||||
private final Supplier<MemoryMappingTree> memoryMappingTree = Suppliers.memoize(this::createMemoryMappingTree);
|
||||
|
||||
private IntermediateMappingsService(Path intermediaryTiny, String expectedSrcNs) {
|
||||
this.intermediaryTiny = intermediaryTiny;
|
||||
this.expectedSrcNs = expectedSrcNs;
|
||||
public IntermediateMappingsService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
public static synchronized IntermediateMappingsService getInstance(SharedServiceManager sharedServiceManager, Project project, MinecraftProvider minecraftProvider) {
|
||||
public static Provider<Options> createOptions(Project project, MinecraftProvider minecraftProvider) {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final IntermediateMappingsProvider intermediateProvider = extension.getIntermediateMappingsProvider();
|
||||
final String id = "IntermediateMappingsService:%s:%s".formatted(intermediateProvider.getName(), intermediateProvider.getMinecraftVersion().get());
|
||||
|
||||
return sharedServiceManager.getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider, project));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static IntermediateMappingsService create(IntermediateMappingsProvider intermediateMappingsProvider, MinecraftProvider minecraftProvider, Project project) {
|
||||
final Path intermediaryTiny = minecraftProvider.file(intermediateMappingsProvider.getName() + ".tiny").toPath();
|
||||
final Path intermediaryTiny = minecraftProvider.file(intermediateProvider.getName() + ".tiny").toPath();
|
||||
|
||||
try {
|
||||
if (intermediateMappingsProvider instanceof IntermediateMappingsProviderInternal internal) {
|
||||
if (intermediateProvider instanceof IntermediateMappingsProviderInternal internal) {
|
||||
internal.provide(intermediaryTiny, project);
|
||||
} else {
|
||||
intermediateMappingsProvider.provide(intermediaryTiny);
|
||||
intermediateProvider.provide(intermediaryTiny);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
Files.deleteIfExists(intermediaryTiny);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
LOGGER.warn("Failed to delete intermediary mappings file", ex);
|
||||
}
|
||||
|
||||
throw new UncheckedIOException("Failed to provide intermediate mappings", e);
|
||||
}
|
||||
|
||||
return createOptions(project, minecraftProvider, intermediaryTiny);
|
||||
}
|
||||
|
||||
private static Provider<Options> createOptions(Project project, MinecraftProvider minecraftProvider, Path intermediaryTiny) {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final IntermediateMappingsProvider intermediateProvider = extension.getIntermediateMappingsProvider();
|
||||
// When merging legacy versions there will be multiple named namespaces, so use intermediary as the common src ns
|
||||
// Newer versions will use intermediary as the src ns
|
||||
final String expectedSrcNs = minecraftProvider.isLegacyVersion()
|
||||
? MappingsNamespace.INTERMEDIARY.toString() // <1.3
|
||||
: MappingsNamespace.OFFICIAL.toString(); // >=1.3
|
||||
|
||||
return new IntermediateMappingsService(intermediaryTiny, expectedSrcNs);
|
||||
return TYPE.create(project, options -> {
|
||||
options.getIntermediaryTiny().set(intermediaryTiny.toFile());
|
||||
options.getExpectedSrcNs().set(expectedSrcNs);
|
||||
options.getMinecraftVersion().set(intermediateProvider.getMinecraftVersion());
|
||||
});
|
||||
}
|
||||
|
||||
private MemoryMappingTree createMemoryMappingTree() {
|
||||
return createMemoryMappingTree(getIntermediaryTiny(), getOptions().getExpectedSrcNs().get());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static MemoryMappingTree createMemoryMappingTree(Path mappingFile, String expectedSrcNs) {
|
||||
final MemoryMappingTree tree = new MemoryMappingTree();
|
||||
|
||||
try {
|
||||
MappingNsCompleter nsCompleter = new MappingNsCompleter(tree, Collections.singletonMap(MappingsNamespace.NAMED.toString(), MappingsNamespace.INTERMEDIARY.toString()), true);
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(getIntermediaryTiny(), StandardCharsets.UTF_8)) {
|
||||
try (BufferedReader reader = Files.newBufferedReader(mappingFile, StandardCharsets.UTF_8)) {
|
||||
Tiny2FileReader.read(reader, nsCompleter);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -120,6 +144,6 @@ public final class IntermediateMappingsService implements SharedService {
|
||||
}
|
||||
|
||||
public Path getIntermediaryTiny() {
|
||||
return Objects.requireNonNull(intermediaryTiny, "Intermediary mappings have not been setup");
|
||||
return getOptions().getIntermediaryTiny().get().getAsFile().toPath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,9 +47,15 @@ import com.google.common.base.Stopwatch;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.architectury.loom.util.MappingOption;
|
||||
|
||||
import dev.architectury.loom.util.MappingOption;
|
||||
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
import org.apache.tools.ant.util.StringUtils;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.slf4j.Logger;
|
||||
@@ -68,8 +74,7 @@ import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.DeletingFileVisitor;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.srg.ForgeMappingsMerger;
|
||||
import net.fabricmc.loom.util.srg.MCPReader;
|
||||
import net.fabricmc.loom.util.srg.SrgNamedWriter;
|
||||
@@ -119,7 +124,7 @@ public class MappingConfiguration {
|
||||
this.mappingOptions.put(MappingOption.DEFAULT, () -> this.tinyMappings);
|
||||
}
|
||||
|
||||
public static MappingConfiguration create(Project project, SharedServiceManager serviceManager, DependencyInfo dependency, MinecraftProvider minecraftProvider) {
|
||||
public static MappingConfiguration create(Project project, ServiceFactory serviceFactory, DependencyInfo dependency, MinecraftProvider minecraftProvider) {
|
||||
final String version = dependency.getResolvedVersion();
|
||||
final Path inputJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not resolve mappings: " + dependency)).toPath();
|
||||
final String mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged");
|
||||
@@ -146,29 +151,25 @@ public class MappingConfiguration {
|
||||
|
||||
final Path workingDir = minecraftProvider.dir(mappingsIdentifier).toPath();
|
||||
|
||||
MappingConfiguration mappingConfiguration;
|
||||
MappingConfiguration mappingProvider;
|
||||
|
||||
if (extension.isForgeLike()) {
|
||||
mappingConfiguration = new ForgeMigratedMappingConfiguration(mappingsIdentifier, workingDir);
|
||||
mappingProvider = new ForgeMigratedMappingConfiguration(mappingsIdentifier, workingDir);
|
||||
} else {
|
||||
mappingConfiguration = new MappingConfiguration(mappingsIdentifier, workingDir);
|
||||
mappingProvider = new MappingConfiguration(mappingsIdentifier, workingDir);
|
||||
}
|
||||
|
||||
try {
|
||||
mappingConfiguration.setup(project, serviceManager, minecraftProvider, inputJar);
|
||||
mappingProvider.setup(project, serviceFactory, minecraftProvider, inputJar);
|
||||
} catch (IOException e) {
|
||||
cleanWorkingDirectory(workingDir);
|
||||
throw new UncheckedIOException("Failed to setup mappings: " + dependency.getDepString(), e);
|
||||
}
|
||||
|
||||
return mappingConfiguration;
|
||||
return mappingProvider;
|
||||
}
|
||||
|
||||
public TinyMappingsService getMappingsService(SharedServiceManager serviceManager) {
|
||||
return getMappingsService(serviceManager, MappingOption.DEFAULT);
|
||||
}
|
||||
|
||||
public TinyMappingsService getMappingsService(SharedServiceManager serviceManager, MappingOption mappingOption) {
|
||||
public Path getMappingsPath(MappingOption mappingOption) {
|
||||
Supplier<Path> mappingsSupplier = this.mappingOptions.get(mappingOption);
|
||||
|
||||
if (mappingsSupplier == null) {
|
||||
@@ -177,16 +178,32 @@ public class MappingConfiguration {
|
||||
throw new UnsupportedOperationException("Mapping option " + mappingOption + " found but file does not exist!");
|
||||
}
|
||||
|
||||
return TinyMappingsService.create(serviceManager, Objects.requireNonNull(mappingsSupplier.get()));
|
||||
return Objects.requireNonNull(mappingsSupplier.get());
|
||||
}
|
||||
|
||||
protected void setup(Project project, SharedServiceManager serviceManager, MinecraftProvider minecraftProvider, Path inputJar) throws IOException {
|
||||
public Provider<TinyMappingsService.Options> getMappingsServiceOptions(Project project) {
|
||||
return getMappingsServiceOptions(project, MappingOption.DEFAULT);
|
||||
}
|
||||
|
||||
public Provider<TinyMappingsService.Options> getMappingsServiceOptions(Project project, MappingOption mappingOption) {
|
||||
return TinyMappingsService.createOptions(project, Objects.requireNonNull(getMappingsPath(mappingOption)));
|
||||
}
|
||||
|
||||
public TinyMappingsService getMappingsService(Project project, ServiceFactory serviceFactory) {
|
||||
return serviceFactory.get(getMappingsServiceOptions(project));
|
||||
}
|
||||
|
||||
public TinyMappingsService getMappingsService(Project project, ServiceFactory serviceFactory, MappingOption mappingOption) {
|
||||
return serviceFactory.get(getMappingsServiceOptions(project, mappingOption));
|
||||
}
|
||||
|
||||
protected void setup(Project project, ServiceFactory serviceFactory, MinecraftProvider minecraftProvider, Path inputJar) throws IOException {
|
||||
if (minecraftProvider.refreshDeps()) {
|
||||
cleanWorkingDirectory(mappingsWorkingDir);
|
||||
}
|
||||
|
||||
if (Files.notExists(tinyMappings) || minecraftProvider.refreshDeps()) {
|
||||
storeMappings(project, serviceManager, minecraftProvider, inputJar);
|
||||
storeMappings(project, serviceFactory, minecraftProvider, inputJar);
|
||||
} else {
|
||||
try (FileSystemUtil.Delegate fileSystem = FileSystemUtil.getJarFileSystem(inputJar, false)) {
|
||||
extractExtras(fileSystem.get());
|
||||
@@ -318,12 +335,12 @@ public class MappingConfiguration {
|
||||
return isV2 ? "-v2" : "";
|
||||
}
|
||||
|
||||
private void storeMappings(Project project, SharedServiceManager serviceManager, MinecraftProvider minecraftProvider, Path inputJar) throws IOException {
|
||||
private void storeMappings(Project project, ServiceFactory serviceFactory, MinecraftProvider minecraftProvider, Path inputJar) throws IOException {
|
||||
LOGGER.info(":extracting " + inputJar.getFileName());
|
||||
|
||||
if (isMCP(inputJar)) {
|
||||
try {
|
||||
readAndMergeMCP(project, serviceManager, minecraftProvider, inputJar);
|
||||
readAndMergeMCP(project, serviceFactory, minecraftProvider, inputJar);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -338,7 +355,7 @@ public class MappingConfiguration {
|
||||
|
||||
if (areMappingsV2(baseTinyMappings)) {
|
||||
// These are unmerged v2 mappings
|
||||
IntermediateMappingsService intermediateMappingsService = IntermediateMappingsService.getInstance(serviceManager, project, minecraftProvider);
|
||||
IntermediateMappingsService intermediateMappingsService = serviceFactory.get(IntermediateMappingsService.createOptions(project, minecraftProvider));
|
||||
|
||||
MappingsMerger.mergeAndSaveMappings(baseTinyMappings, tinyMappings, minecraftProvider, intermediateMappingsService);
|
||||
} else {
|
||||
@@ -365,7 +382,7 @@ public class MappingConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private void readAndMergeMCP(Project project, SharedServiceManager serviceManager, MinecraftProvider minecraftProvider, Path mcpJar) throws Exception {
|
||||
private void readAndMergeMCP(Project project, ServiceFactory serviceFactory, MinecraftProvider minecraftProvider, Path mcpJar) throws Exception {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
IntermediateMappingsService intermediateMappingsService = IntermediateMappingsService.getInstance(serviceManager, project, minecraftProvider);
|
||||
Path intermediaryTinyPath = intermediateMappingsService.getIntermediaryTiny();
|
||||
|
||||
@@ -27,29 +27,47 @@ package net.fabricmc.loom.configuration.providers.mappings;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public final class TinyMappingsService implements SharedService {
|
||||
private final MemoryMappingTree mappingTree;
|
||||
public final class TinyMappingsService extends Service<TinyMappingsService.Options> {
|
||||
public static final ServiceType<Options, TinyMappingsService> TYPE = new ServiceType<>(Options.class, TinyMappingsService.class);
|
||||
|
||||
public TinyMappingsService(Path tinyMappings) {
|
||||
public interface Options extends Service.Options {
|
||||
@InputFile
|
||||
RegularFileProperty getMappings();
|
||||
}
|
||||
|
||||
public static Provider<Options> createOptions(Project project, Path mappings) {
|
||||
return TYPE.create(project, options -> options.getMappings().set(project.file(mappings)));
|
||||
}
|
||||
|
||||
public TinyMappingsService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
private final Supplier<MemoryMappingTree> mappingTree = Suppliers.memoize(() -> {
|
||||
try {
|
||||
this.mappingTree = new MemoryMappingTree();
|
||||
MappingReader.read(tinyMappings, mappingTree);
|
||||
MemoryMappingTree mappingTree = new MemoryMappingTree();
|
||||
MappingReader.read(getOptions().getMappings().get().getAsFile().toPath(), mappingTree);
|
||||
return mappingTree;
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized TinyMappingsService create(SharedServiceManager serviceManager, Path tinyMappings) {
|
||||
return serviceManager.getOrCreateService("TinyMappingsService:" + tinyMappings.toAbsolutePath(), () -> new TinyMappingsService(tinyMappings));
|
||||
}
|
||||
});
|
||||
|
||||
public MemoryMappingTree getMappingTree() {
|
||||
return mappingTree;
|
||||
return mappingTree.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import net.fabricmc.tinyremapper.api.TrClass;
|
||||
|
||||
@@ -56,7 +56,7 @@ public record SignatureFixerApplyVisitor(Map<String, String> signatureFixes) imp
|
||||
};
|
||||
}
|
||||
|
||||
public static Map<String, String> getRemappedSignatures(boolean toIntermediary, MappingConfiguration mappingConfiguration, Project project, SharedServiceManager serviceManager, String targetNamespace) throws IOException {
|
||||
public static Map<String, String> getRemappedSignatures(boolean toIntermediary, MappingConfiguration mappingConfiguration, Project project, ServiceFactory serviceFactory, String targetNamespace) throws IOException {
|
||||
if (mappingConfiguration.getSignatureFixes() == null) {
|
||||
// No fixes
|
||||
return Collections.emptyMap();
|
||||
@@ -69,7 +69,7 @@ public record SignatureFixerApplyVisitor(Map<String, String> signatureFixes) imp
|
||||
|
||||
// Remap the sig fixes from intermediary to the target namespace
|
||||
final Map<String, String> remapped = new HashMap<>();
|
||||
final TinyRemapper sigTinyRemapper = TinyRemapperHelper.getTinyRemapper(project, serviceManager, MappingsNamespace.INTERMEDIARY.toString(), targetNamespace);
|
||||
final TinyRemapper sigTinyRemapper = TinyRemapperHelper.getTinyRemapper(project, serviceFactory, MappingsNamespace.INTERMEDIARY.toString(), targetNamespace);
|
||||
final Remapper sigAsmRemapper = sigTinyRemapper.getEnvironment().getRemapper();
|
||||
|
||||
// Remap the class names and the signatures using a new tiny remapper instance.
|
||||
|
||||
@@ -56,7 +56,6 @@ import net.fabricmc.loom.configuration.providers.minecraft.SignatureFixerApplyVi
|
||||
import net.fabricmc.loom.extension.LoomFiles;
|
||||
import net.fabricmc.loom.util.SidedClassVisitor;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.srg.InnerClassRemapper;
|
||||
import net.fabricmc.loom.util.srg.RemapObjectHolderVisitor;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
@@ -206,11 +205,11 @@ public abstract class AbstractMappedMinecraftProvider<M extends MinecraftProvide
|
||||
Files.deleteIfExists(remappedJars.outputJarPath());
|
||||
|
||||
final Set<String> classNames = extension.isForgeLike() ? InnerClassRemapper.readClassNames(remappedJars.inputJar()) : Set.of();
|
||||
final Map<String, String> remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceManager(), toM);
|
||||
final Map<String, String> remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceFactory(), toM);
|
||||
final MinecraftVersionMeta.JavaVersion javaVersion = minecraftProvider.getVersionInfo().javaVersion();
|
||||
final boolean fixRecords = javaVersion != null && javaVersion.majorVersion() >= 16;
|
||||
|
||||
TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(getProject(), configContext.serviceManager(), fromM, toM, fixRecords, (builder) -> {
|
||||
TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(getProject(), configContext.serviceFactory(), fromM, toM, fixRecords, (builder) -> {
|
||||
builder.extraPostApplyVisitor(new SignatureFixerApplyVisitor(remappedSignatures));
|
||||
if (extension.isNeoForge()) builder.extension(new MixinExtension(inputTag -> true));
|
||||
configureRemapper(remappedJars, builder);
|
||||
@@ -234,21 +233,19 @@ public abstract class AbstractMappedMinecraftProvider<M extends MinecraftProvide
|
||||
getMavenHelper(remappedJars.type()).savePom();
|
||||
|
||||
if (extension.isForgeLikeAndOfficial()) {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(extension);
|
||||
final TinyMappingsService mappingsService = extension.getMappingConfiguration().getMappingsService(serviceManager, mappingOption);
|
||||
final String className;
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(extension);
|
||||
final TinyMappingsService mappingsService = extension.getMappingConfiguration().getMappingsService(project, configContext.serviceFactory(), mappingOption);
|
||||
final String className;
|
||||
|
||||
if (extension.isNeoForge()) {
|
||||
className = "net.neoforged.neoforge.registries.ObjectHolderRegistry";
|
||||
} else {
|
||||
className = "net.minecraftforge.registries.ObjectHolderRegistry";
|
||||
}
|
||||
|
||||
final String sourceNamespace = IntermediaryNamespaces.runtimeIntermediary(project);
|
||||
final MemoryMappingTree mappings = mappingsService.getMappingTree();
|
||||
RemapObjectHolderVisitor.remapObjectHolder(remappedJars.outputJar().getPath(), className, mappings, sourceNamespace, "named");
|
||||
if (extension.isNeoForge()) {
|
||||
className = "net.neoforged.neoforge.registries.ObjectHolderRegistry";
|
||||
} else {
|
||||
className = "net.minecraftforge.registries.ObjectHolderRegistry";
|
||||
}
|
||||
|
||||
final String sourceNamespace = IntermediaryNamespaces.runtimeIntermediary(project);
|
||||
final MemoryMappingTree mappings = mappingsService.getMappingTree();
|
||||
RemapObjectHolderVisitor.remapObjectHolder(remappedJars.outputJar().getPath(), className, mappings, sourceNamespace, "named");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.cadixdev.lorenz.MappingSet;
|
||||
import org.cadixdev.mercury.Mercury;
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.gradle.api.Project;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
@@ -63,12 +63,11 @@ import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.ThreadingUtils;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.lorenztiny.TinyMappingsReader;
|
||||
|
||||
public class ForgeSourcesRemapper {
|
||||
public static void addBaseForgeSources(Project project) throws IOException {
|
||||
public static void addBaseForgeSources(Project project, ServiceFactory serviceFactory) throws IOException {
|
||||
List<Path> minecraftJars = LoomGradleExtension.get(project).getMinecraftJars(MappingsNamespace.NAMED);
|
||||
Path minecraftJar;
|
||||
|
||||
@@ -85,18 +84,16 @@ public class ForgeSourcesRemapper {
|
||||
Path sourcesJar = GenerateSourcesTask.getJarFileWithSuffix("-sources.jar", minecraftJar).toPath();
|
||||
|
||||
if (!Files.exists(sourcesJar)) {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
addForgeSources(project, serviceManager, minecraftJar, sourcesJar);
|
||||
}
|
||||
addForgeSources(project, serviceFactory, minecraftJar, sourcesJar);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addForgeSources(Project project, SharedServiceManager serviceManager, @Nullable Path inputJar, Path sourcesJar) throws IOException {
|
||||
public static void addForgeSources(Project project, ServiceFactory serviceFactory, @Nullable Path inputJar, Path sourcesJar) throws IOException {
|
||||
try (FileSystemUtil.Delegate inputFs = inputJar == null ? null : FileSystemUtil.getJarFileSystem(inputJar, true);
|
||||
FileSystemUtil.Delegate outputFs = FileSystemUtil.getJarFileSystem(sourcesJar, true)) {
|
||||
ThreadingUtils.TaskCompleter taskCompleter = ThreadingUtils.taskCompleter();
|
||||
|
||||
provideForgeSources(project, serviceManager, path -> {
|
||||
provideForgeSources(project, serviceFactory, path -> {
|
||||
Path inputPath = inputFs == null ? null : inputFs.get().getPath(path.replace(".java", ".class"));
|
||||
|
||||
if (inputPath != null && Files.notExists(inputPath)) {
|
||||
@@ -126,7 +123,7 @@ public class ForgeSourcesRemapper {
|
||||
}
|
||||
}
|
||||
|
||||
public static void provideForgeSources(Project project, SharedServiceManager serviceManager, Predicate<String> classFilter, BiConsumer<String, byte[]> consumer) throws IOException {
|
||||
public static void provideForgeSources(Project project, ServiceFactory serviceFactory, Predicate<String> classFilter, BiConsumer<String, byte[]> consumer) throws IOException {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
String sourceDependency = extension.getForgeUserdevProvider().getConfig().sources();
|
||||
List<Path> forgeInstallerSources = new ArrayList<>();
|
||||
@@ -140,11 +137,11 @@ public class ForgeSourcesRemapper {
|
||||
Map<String, byte[]> forgeSources = extractSources(forgeInstallerSources);
|
||||
forgeSources.keySet().removeIf(classFilter.negate());
|
||||
project.getLogger().lifecycle(":extracted {} forge source classes", forgeSources.size());
|
||||
remapSources(project, serviceManager, forgeSources);
|
||||
remapSources(project, serviceFactory, forgeSources);
|
||||
forgeSources.forEach(consumer);
|
||||
}
|
||||
|
||||
private static void remapSources(Project project, SharedServiceManager serviceManager, Map<String, byte[]> sources) throws IOException {
|
||||
private static void remapSources(Project project, ServiceFactory serviceFactory, Map<String, byte[]> sources) throws IOException {
|
||||
File tmpInput = File.createTempFile("tmpInputForgeSources", null);
|
||||
tmpInput.delete();
|
||||
tmpInput.deleteOnExit();
|
||||
@@ -178,7 +175,7 @@ public class ForgeSourcesRemapper {
|
||||
System.setErr(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM));
|
||||
}
|
||||
|
||||
remapForgeSourcesInner(project, serviceManager, tmpInput.toPath(), tmpOutput.toPath());
|
||||
remapForgeSourcesInner(project, serviceFactory, tmpInput.toPath(), tmpOutput.toPath());
|
||||
|
||||
if (!ForgeToolExecutor.shouldShowVerboseStderr(project)) {
|
||||
System.setOut(out);
|
||||
@@ -215,13 +212,13 @@ public class ForgeSourcesRemapper {
|
||||
}
|
||||
}
|
||||
|
||||
private static void remapForgeSourcesInner(Project project, SharedServiceManager serviceManager, Path tmpInput, Path tmpOutput) throws IOException {
|
||||
private static void remapForgeSourcesInner(Project project, ServiceFactory serviceFactory, Path tmpInput, Path tmpOutput) throws IOException {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
Mercury mercury = SourceRemapper.createMercuryWithClassPath(project, false);
|
||||
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(extension);
|
||||
final String sourceNamespace = IntermediaryNamespaces.intermediary(project);
|
||||
TinyMappingsService mappingsService = extension.getMappingConfiguration().getMappingsService(serviceManager, mappingOption);
|
||||
TinyMappingsService mappingsService = extension.getMappingConfiguration().getMappingsService(project, serviceFactory, mappingOption);
|
||||
MappingSet mappings = new TinyMappingsReader(mappingsService.getMappingTree(), sourceNamespace, "named").read();
|
||||
|
||||
for (Map.Entry<String, String> entry : TinyRemapperHelper.JSR_TO_JETBRAINS.entrySet()) {
|
||||
|
||||
@@ -484,7 +484,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
|
||||
holder = objectFactory.newInstance(RemapperExtensionHolder.class, RemapperParameters.None.INSTANCE);
|
||||
}
|
||||
|
||||
holder.getRemapperExtensionClass().set(remapperExtensionClass);
|
||||
holder.getRemapperExtensionClass().set(remapperExtensionClass.getName());
|
||||
remapperExtensions.add(holder);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
|
||||
package net.fabricmc.loom.extension;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
@@ -43,25 +43,19 @@ import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import net.fabricmc.tinyremapper.api.TrClass;
|
||||
|
||||
public abstract class RemapperExtensionHolder {
|
||||
// Null when RemapperParameters.None.class
|
||||
private final RemapperParameters remapperParameters;
|
||||
|
||||
@Inject
|
||||
public RemapperExtensionHolder(RemapperParameters remapperParameters) {
|
||||
this.remapperParameters = remapperParameters;
|
||||
this.getRemapperParameters().set(remapperParameters);
|
||||
}
|
||||
|
||||
@Input
|
||||
public abstract Property<Class<? extends RemapperExtension<?>>> getRemapperExtensionClass();
|
||||
public abstract Property<String> getRemapperExtensionClass();
|
||||
|
||||
@Nested
|
||||
@Optional
|
||||
public RemapperParameters getRemapperParameters() {
|
||||
return remapperParameters;
|
||||
}
|
||||
public abstract Property<RemapperParameters> getRemapperParameters();
|
||||
|
||||
public void apply(TinyRemapper.Builder tinyRemapperBuilder, String sourceNamespace, String targetNamespace, ObjectFactory objectFactory) {
|
||||
final RemapperExtension<?> remapperExtension = newInstance(objectFactory);
|
||||
public void apply(TinyRemapper.Builder tinyRemapperBuilder, String sourceNamespace, String targetNamespace) {
|
||||
final RemapperExtension<?> remapperExtension = newInstance();
|
||||
|
||||
tinyRemapperBuilder.extraPostApplyVisitor(new RemapperExtensionImpl(remapperExtension, sourceNamespace, targetNamespace));
|
||||
|
||||
@@ -86,20 +80,41 @@ public abstract class RemapperExtensionHolder {
|
||||
}
|
||||
}
|
||||
|
||||
private RemapperExtension<?> newInstance(ObjectFactory objectFactory) {
|
||||
private RemapperExtension<?> newInstance() {
|
||||
try {
|
||||
Class<? extends RemapperExtension<?>> remapperExtensionClass = getRemapperExtensionClass().get();
|
||||
//noinspection unchecked
|
||||
final Class<? extends RemapperExtension<?>> remapperExtensionClass = (Class<? extends RemapperExtension<?>>) Class.forName(getRemapperExtensionClass().get());
|
||||
final Constructor<?> constructor = getInjectedConstructor(remapperExtensionClass);
|
||||
|
||||
if (remapperParameters == RemapperParameters.None.INSTANCE) {
|
||||
return objectFactory.newInstance(remapperExtensionClass);
|
||||
if (getRemapperParameters().get() instanceof RemapperParameters.None) {
|
||||
return (RemapperExtension<?>) constructor.newInstance();
|
||||
}
|
||||
|
||||
return objectFactory.newInstance(remapperExtensionClass, remapperParameters);
|
||||
return (RemapperExtension<?>) constructor.newInstance(getRemapperParameters().get());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to create remapper extension", e);
|
||||
throw new RuntimeException("Failed to create remapper extension for class: " + getRemapperExtensionClass().get(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Constructor<?> getInjectedConstructor(Class<?> clazz) {
|
||||
Constructor<?>[] constructors = clazz.getConstructors();
|
||||
Constructor<?> injectedConstructor = null;
|
||||
|
||||
for (Constructor<?> constructor : constructors) {
|
||||
if (injectedConstructor != null) {
|
||||
throw new RuntimeException("RemapperExtension class " + clazz.getName() + " has more than one constructor");
|
||||
}
|
||||
|
||||
injectedConstructor = constructor;
|
||||
}
|
||||
|
||||
if (injectedConstructor == null) {
|
||||
throw new RuntimeException("RemapperExtension class " + clazz.getName() + " does not have a constructor");
|
||||
}
|
||||
|
||||
return injectedConstructor;
|
||||
}
|
||||
|
||||
private static final class RemapperExtensionImpl implements TinyRemapper.ApplyVisitorProvider {
|
||||
private final RemapperExtension<?> remapperExtension;
|
||||
private final String sourceNamespace;
|
||||
|
||||
@@ -230,7 +230,7 @@ public abstract class AbstractRemapJarTask extends Jar {
|
||||
return getInputFile();
|
||||
}
|
||||
|
||||
protected static List<String> getRootPaths(Set<File> files) {
|
||||
public static List<String> getRootPaths(Set<File> files) {
|
||||
return files.stream()
|
||||
.map(root -> {
|
||||
String rootPath = root.getAbsolutePath().replace("\\", "/");
|
||||
@@ -243,7 +243,7 @@ public abstract class AbstractRemapJarTask extends Jar {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
protected static Function<File, String> relativePath(List<String> rootPaths) {
|
||||
public static Function<File, String> relativePath(List<String> rootPaths) {
|
||||
return file -> {
|
||||
String s = file.getAbsolutePath().replace("\\", "/");
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ import net.fabricmc.loom.util.gradle.ThreadedSimpleProgressLogger;
|
||||
import net.fabricmc.loom.util.gradle.WorkerDaemonClientsManagerHelper;
|
||||
import net.fabricmc.loom.util.ipc.IPCClient;
|
||||
import net.fabricmc.loom.util.ipc.IPCServer;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
||||
import net.fabricmc.mappingio.format.tiny.Tiny2FileWriter;
|
||||
@@ -509,8 +509,8 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask {
|
||||
private MinecraftJar rebuildInputJar() {
|
||||
final List<MinecraftJar> minecraftJars;
|
||||
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
final var configContext = new ConfigContextImpl(getProject(), serviceManager, getExtension());
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
final var configContext = new ConfigContextImpl(getProject(), serviceFactory, getExtension());
|
||||
final var provideContext = new AbstractMappedMinecraftProvider.ProvideContext(false, true, configContext);
|
||||
minecraftJars = getExtension().getNamedMinecraftProvider().provide(provideContext);
|
||||
} catch (Exception e) {
|
||||
@@ -764,9 +764,11 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask {
|
||||
|
||||
if (minecraftJarProcessorManager != null) {
|
||||
mappingsProcessors.add(mappings -> {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
final var configContext = new ConfigContextImpl(getProject(), serviceManager, getExtension());
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
final var configContext = new ConfigContextImpl(getProject(), serviceFactory, getExtension());
|
||||
return minecraftJarProcessorManager.processMappings(mappings, new MappingProcessorContextImpl(configContext));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ 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.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
import net.fabricmc.lorenztiny.TinyMappingsJoiner;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
@@ -110,8 +110,8 @@ public abstract class MigrateMappingsTask extends AbstractLoomTask {
|
||||
File mappings = loadMappings();
|
||||
MappingConfiguration mappingConfiguration = extension.getMappingConfiguration();
|
||||
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
MemoryMappingTree currentMappings = mappingConfiguration.getMappingsService(serviceManager).getMappingTree();
|
||||
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());
|
||||
|
||||
@@ -25,18 +25,14 @@
|
||||
package net.fabricmc.loom.task;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -50,11 +46,10 @@ import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
@@ -71,8 +66,8 @@ import net.fabricmc.loom.build.nesting.JarNester;
|
||||
import net.fabricmc.loom.build.nesting.NestableJarGenerationTask;
|
||||
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
|
||||
import net.fabricmc.loom.configuration.mods.ArtifactMetadata;
|
||||
import net.fabricmc.loom.extension.MixinExtension;
|
||||
import net.fabricmc.loom.task.service.MappingsService;
|
||||
import net.fabricmc.loom.task.service.MixinRefmapService;
|
||||
import net.fabricmc.loom.task.service.TinyRemapperService;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ExceptionUtil;
|
||||
@@ -80,11 +75,10 @@ import net.fabricmc.loom.util.ModPlatform;
|
||||
import net.fabricmc.loom.util.Pair;
|
||||
import net.fabricmc.loom.util.SidedClassVisitor;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonUtils;
|
||||
import net.fabricmc.loom.util.service.BuildSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
|
||||
@@ -137,13 +131,14 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
@Input
|
||||
@ApiStatus.Internal
|
||||
public abstract Property<Boolean> getUseMixinAP();
|
||||
|
||||
private final Provider<BuildSharedServiceManager> serviceManagerProvider;
|
||||
@Nested
|
||||
public abstract Property<TinyRemapperService.Options> getTinyRemapperServiceOptions();
|
||||
@Nested
|
||||
public abstract ListProperty<MixinRefmapService.Options> getMixinRefmapServiceOptions();
|
||||
|
||||
@Inject
|
||||
public RemapJarTask() {
|
||||
super();
|
||||
serviceManagerProvider = BuildSharedServiceManager.createForTask(this, getBuildEventsListenerRegistry());
|
||||
final ConfigurationContainer configurations = getProject().getConfigurations();
|
||||
getClasspath().from(configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
|
||||
getAddNestedDependencies().convention(true).finalizeValueOnRead();
|
||||
@@ -162,6 +157,9 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
setPreserveFileTimestamps(false);
|
||||
|
||||
getJarType().set("classes");
|
||||
|
||||
getTinyRemapperServiceOptions().set(TinyRemapperService.createOptions(this));
|
||||
getMixinRefmapServiceOptions().set(MixinRefmapService.createOptions(this));
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
@@ -174,16 +172,14 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
}
|
||||
|
||||
if (!params.namespacesMatch()) {
|
||||
params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(getTinyRemapperService()));
|
||||
params.getTinyRemapperServiceOptions().set(getTinyRemapperServiceOptions());
|
||||
params.getMixinRefmapServiceOptions().set(getMixinRefmapServiceOptions());
|
||||
|
||||
params.getRemapClasspath().from(getClasspath());
|
||||
|
||||
final boolean mixinAp = getUseMixinAP().get();
|
||||
params.getUseMixinExtension().set(!mixinAp);
|
||||
|
||||
if (mixinAp) {
|
||||
setupLegacyMixinRefmapRemapping(params);
|
||||
}
|
||||
|
||||
// Add the mixin refmap remap type to the manifest
|
||||
// This is used by the mod dependency remapper to determine if it should remap the refmap
|
||||
// or if the refmap should be remapped by mixin at runtime.
|
||||
@@ -199,56 +195,17 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
params.getInjectAccessWidener().set(extension.getAccessWidenerPath());
|
||||
}
|
||||
|
||||
params.getMappingBuildServiceUuid().convention("this should be unavailable!");
|
||||
params.getReadMixinConfigsFromManifest().set(getReadMixinConfigsFromManifest());
|
||||
params.getAtAccessWideners().set(getAtAccessWideners());
|
||||
|
||||
if (!getAtAccessWideners().get().isEmpty()) {
|
||||
params.getMappingBuildServiceUuid().set(UnsafeWorkQueueHelper.create(MappingsService.createDefault(getProject(), serviceManagerProvider.get().get(), getSourceNamespace().get(), getTargetNamespace().get())));
|
||||
params.getMappingsServiceOptions().set(MappingsService.createOptionsWithProjectMappings(getProject(), getSourceNamespace(), getTargetNamespace()));
|
||||
}
|
||||
|
||||
params.getOptimizeFmj().set(getOptimizeFabricModJson().get());
|
||||
});
|
||||
}
|
||||
|
||||
private void setupLegacyMixinRefmapRemapping(RemapParams params) {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(getProject());
|
||||
final MixinExtension mixinExtension = extension.getMixin();
|
||||
|
||||
final Collection<String> allMixinConfigs = new LinkedHashSet<>();
|
||||
final FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(getInputFile().getAsFile().get().toPath());
|
||||
|
||||
if (fabricModJson != null) {
|
||||
allMixinConfigs.addAll(fabricModJson.getMixinConfigurations());
|
||||
}
|
||||
|
||||
if (getReadMixinConfigsFromManifest().get()) {
|
||||
allMixinConfigs.addAll(ModBuildExtensions.readMixinConfigsFromManifest(getInputFile().get().getAsFile()));
|
||||
}
|
||||
|
||||
if (allMixinConfigs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (SourceSet sourceSet : mixinExtension.getMixinSourceSets()) {
|
||||
MixinExtension.MixinInformationContainer container = Objects.requireNonNull(
|
||||
MixinExtension.getMixinInformationContainer(sourceSet)
|
||||
);
|
||||
|
||||
final List<String> rootPaths = getRootPaths(sourceSet.getResources().getSrcDirs());
|
||||
|
||||
final String refmapName = container.refmapNameProvider().get();
|
||||
final List<String> mixinConfigs = container.sourceSet().getResources()
|
||||
.matching(container.mixinConfigPattern())
|
||||
.getFiles()
|
||||
.stream()
|
||||
.map(relativePath(rootPaths))
|
||||
.filter(allMixinConfigs::contains)
|
||||
.toList();
|
||||
|
||||
params.getMixinData().add(new RemapParams.RefmapData(mixinConfigs, refmapName));
|
||||
}
|
||||
}
|
||||
|
||||
public interface RemapParams extends AbstractRemapParams {
|
||||
ConfigurableFileCollection getNestedJars();
|
||||
|
||||
@@ -257,36 +214,35 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
Property<ModPlatform> getPlatform();
|
||||
|
||||
RegularFileProperty getInjectAccessWidener();
|
||||
|
||||
Property<Boolean> getReadMixinConfigsFromManifest();
|
||||
SetProperty<String> getAtAccessWideners();
|
||||
|
||||
Property<Boolean> getUseMixinExtension();
|
||||
Property<Boolean> getOptimizeFmj();
|
||||
|
||||
record RefmapData(List<String> mixinConfigs, String refmapName) implements Serializable { }
|
||||
ListProperty<RefmapData> getMixinData();
|
||||
|
||||
Property<String> getTinyRemapperBuildServiceUuid();
|
||||
Property<String> getMappingBuildServiceUuid();
|
||||
Property<TinyRemapperService.Options> getTinyRemapperServiceOptions();
|
||||
ListProperty<MixinRefmapService.Options> getMixinRefmapServiceOptions();
|
||||
Property<MappingsService.Options> getMappingsServiceOptions();
|
||||
}
|
||||
|
||||
public abstract static class RemapAction extends AbstractRemapAction<RemapParams> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RemapAction.class);
|
||||
|
||||
private final @Nullable TinyRemapperService tinyRemapperService;
|
||||
private @Nullable TinyRemapperService tinyRemapperService;
|
||||
private @Nullable TinyRemapper tinyRemapper;
|
||||
|
||||
public RemapAction() {
|
||||
this.tinyRemapperService = getParameters().getTinyRemapperBuildServiceUuid().isPresent()
|
||||
? UnsafeWorkQueueHelper.get(getParameters().getTinyRemapperBuildServiceUuid(), TinyRemapperService.class)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
LOGGER.info("Remapping {} to {}", inputFile, outputFile);
|
||||
|
||||
this.tinyRemapperService = getParameters().getTinyRemapperServiceOptions().isPresent()
|
||||
? serviceFactory.get(getParameters().getTinyRemapperServiceOptions().get())
|
||||
: null;
|
||||
|
||||
prepare();
|
||||
|
||||
if (tinyRemapperService != null) {
|
||||
@@ -305,9 +261,9 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
remapAccessWidener();
|
||||
}
|
||||
|
||||
addRefmaps();
|
||||
addRefmaps(serviceFactory);
|
||||
addNestedJars();
|
||||
ModBuildExtensions.convertAwToAt(getParameters().getAtAccessWideners(), outputFile, getParameters().getMappingBuildServiceUuid());
|
||||
ModBuildExtensions.convertAwToAt(serviceFactory, getParameters().getAtAccessWideners(), outputFile, getParameters().getMappingsServiceOptions());
|
||||
|
||||
if (!getParameters().getPlatform().get().isForgeLike()) {
|
||||
modifyJarManifest();
|
||||
@@ -433,21 +389,14 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
JarNester.nestJars(nestedJars.getFiles(), outputFile.toFile(), getParameters().getPlatform().get(), LOGGER);
|
||||
}
|
||||
|
||||
private void addRefmaps() throws IOException {
|
||||
private void addRefmaps(ServiceFactory serviceFactory) throws IOException {
|
||||
if (getParameters().getUseMixinExtension().getOrElse(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (RemapParams.RefmapData refmapData : getParameters().getMixinData().get()) {
|
||||
if (ZipUtils.contains(outputFile, refmapData.refmapName())) {
|
||||
int transformed = ZipUtils.transformJson(JsonObject.class, outputFile, refmapData.mixinConfigs().stream().collect(Collectors.toMap(s -> s, s -> json -> {
|
||||
if (!json.has("refmap")) {
|
||||
json.addProperty("refmap", refmapData.refmapName());
|
||||
}
|
||||
|
||||
return json;
|
||||
})));
|
||||
}
|
||||
for (MixinRefmapService.Options options : getParameters().getMixinRefmapServiceOptions().get()) {
|
||||
MixinRefmapService mixinRefmapService = serviceFactory.get(options);
|
||||
mixinRefmapService.applyToJar(outputFile, getParameters().getReadMixinConfigsFromManifest().get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,9 +424,4 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
.map(relativePath(rootPaths))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Internal
|
||||
public TinyRemapperService getTinyRemapperService() {
|
||||
return TinyRemapperService.getOrCreate(serviceManagerProvider.get().get(), this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.loom.task.service.SourceRemapperService;
|
||||
import net.fabricmc.loom.util.newService.ScopedServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory;
|
||||
|
||||
public abstract class RemapSourcesJarTask extends AbstractRemapJarTask {
|
||||
@Nested
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class JarManifestService implements BuildService<JarManifestServ
|
||||
Property<MixinVersion> getMixinVersion();
|
||||
}
|
||||
|
||||
public static synchronized Provider<JarManifestService> get(Project project) {
|
||||
public static Provider<JarManifestService> get(Project project) {
|
||||
return project.getGradle().getSharedServices().registerIfAbsent("LoomJarManifestService:" + project.getName(), JarManifestService.class, spec -> {
|
||||
spec.parameters(params -> {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
@@ -26,53 +26,65 @@ package net.fabricmc.loom.task.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import dev.architectury.loom.util.MappingOption;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
import org.cadixdev.lorenz.MappingSet;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
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.TinyMappingsReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public final class LorenzMappingService implements SharedService {
|
||||
private MappingSet mappings;
|
||||
public final class LorenzMappingService extends Service<LorenzMappingService.Options> {
|
||||
public static final ServiceType<Options, LorenzMappingService> TYPE = new ServiceType<>(Options.class, LorenzMappingService.class);
|
||||
|
||||
public LorenzMappingService(MappingSet mappings) {
|
||||
this.mappings = mappings;
|
||||
public interface Options extends Service.Options {
|
||||
@Nested
|
||||
Property<MappingsService.Options> getMappings();
|
||||
}
|
||||
|
||||
public static synchronized LorenzMappingService create(SharedServiceManager sharedServiceManager, MappingConfiguration mappingConfiguration, MappingsNamespace from, MappingsNamespace to) {
|
||||
return sharedServiceManager.getOrCreateService(mappingConfiguration.getBuildServiceName("LorenzMappingService", from.toString(), to.toString()), () -> {
|
||||
MappingOption mappingOption = MappingOption.DEFAULT;
|
||||
public static Provider<Options> createOptions(Project project, MappingConfiguration mappingConfiguration, MappingsNamespace from, MappingsNamespace to) {
|
||||
MappingOption mappingOption = from == MappingsNamespace.SRG || to == MappingsNamespace.SRG ? MappingOption.WITH_SRG
|
||||
: from == MappingsNamespace.MOJANG || to == MappingsNamespace.MOJANG ? MappingOption.WITH_MOJANG : MappingOption.DEFAULT;
|
||||
|
||||
if (from == MappingsNamespace.SRG || to == MappingsNamespace.SRG) {
|
||||
mappingOption = MappingOption.WITH_SRG;
|
||||
} else if (from == MappingsNamespace.MOJANG || to == MappingsNamespace.MOJANG) {
|
||||
mappingOption = MappingOption.WITH_MOJANG;
|
||||
return TYPE.create(project, options -> options.getMappings().set(
|
||||
MappingsService.createOptions(
|
||||
project,
|
||||
mappingConfiguration.getMappingsPath(mappingOption),
|
||||
to.toString(),
|
||||
from.toString(),
|
||||
false)
|
||||
));
|
||||
}
|
||||
|
||||
private final Supplier<MappingSet> mappings = Suppliers.memoize(this::readMappings);
|
||||
|
||||
public LorenzMappingService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
private MappingSet readMappings() {
|
||||
MappingsService mappingsService = getServiceFactory().get(getOptions().getMappings().get());
|
||||
|
||||
try {
|
||||
try (var reader = new TinyMappingsReader(mappingsService.getMemoryMappingTree(), mappingsService.getFrom(), mappingsService.getTo())) {
|
||||
return reader.read();
|
||||
}
|
||||
|
||||
MemoryMappingTree m = mappingConfiguration.getMappingsService(sharedServiceManager, mappingOption).getMappingTree();
|
||||
|
||||
try {
|
||||
try (var reader = new TinyMappingsReader(m, from.toString(), to.toString())) {
|
||||
return new LorenzMappingService(reader.read());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read lorenz mappings", e);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read lorenz mappings", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.mappings = null;
|
||||
}
|
||||
|
||||
public MappingSet mappings() {
|
||||
return Objects.requireNonNull(mappings);
|
||||
public MappingSet getMappings() {
|
||||
return mappings.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,83 +24,121 @@
|
||||
|
||||
package net.fabricmc.loom.task.service;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
|
||||
public final class MappingsService implements SharedService {
|
||||
private record Options(Path mappingsFile, String from, String to, boolean remapLocals) { }
|
||||
/**
|
||||
* A service that provides mappings for remapping.
|
||||
*/
|
||||
public final class MappingsService extends Service<MappingsService.Options> implements Closeable {
|
||||
public static ServiceType<Options, MappingsService> TYPE = new ServiceType<>(Options.class, MappingsService.class);
|
||||
|
||||
public static synchronized MappingsService create(SharedServiceManager sharedServiceManager, String name, Path mappingsFile, String from, String to, boolean remapLocals) {
|
||||
final Options options = new Options(mappingsFile, from, to, remapLocals);
|
||||
final String id = name + options.hashCode();
|
||||
return sharedServiceManager.getOrCreateService(id, () -> new MappingsService(options));
|
||||
// TODO use a nested TinyMappingsService instead of duplicating it
|
||||
public interface Options extends Service.Options {
|
||||
@InputFile
|
||||
RegularFileProperty getMappingsFile();
|
||||
@Input
|
||||
Property<String> getFrom();
|
||||
@Input
|
||||
Property<String> getTo();
|
||||
@Input
|
||||
Property<Boolean> getRemapLocals();
|
||||
}
|
||||
|
||||
public static MappingsService createDefault(Project project, SharedServiceManager serviceManager, String from, String to) {
|
||||
/**
|
||||
* Returns options for creating a new mappings service, with a given mappings file.
|
||||
*/
|
||||
public static Provider<Options> createOptions(Project project, Path mappingsFile, String from, String to, boolean remapLocals) {
|
||||
return createOptions(project, mappingsFile, project.provider(() -> from), project.provider(() -> to), remapLocals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options for creating a new mappings service, with a given mappings file.
|
||||
*/
|
||||
public static Provider<Options> createOptions(Project project, Path mappingsFile, Provider<String> from, Provider<String> to, boolean remapLocals) {
|
||||
return TYPE.create(project, o -> {
|
||||
o.getMappingsFile().set(mappingsFile.toFile());
|
||||
o.getFrom().set(from);
|
||||
o.getTo().set(to);
|
||||
o.getRemapLocals().set(remapLocals);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options for creating a new mappings service, using the mappings as specified in the project's mapping configuration.
|
||||
*/
|
||||
public static Provider<Options> createOptionsWithProjectMappings(Project project, Provider<String> from, Provider<String> to) {
|
||||
final MappingConfiguration mappingConfiguration = LoomGradleExtension.get(project).getMappingConfiguration();
|
||||
|
||||
final String name = mappingConfiguration.getBuildServiceName("mappingsProvider", from, to);
|
||||
return MappingsService.create(serviceManager, name, LoomGradleExtension.get(project).getPlatformMappingFile(), from, to, false);
|
||||
return createOptions(project, LoomGradleExtension.get(project).getPlatformMappingFile(), from, to, false);
|
||||
}
|
||||
|
||||
private final Options options;
|
||||
|
||||
public MappingsService(Options options) {
|
||||
this.options = options;
|
||||
public MappingsService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
private IMappingProvider mappingProvider = null;
|
||||
private MemoryMappingTree memoryMappingTree = null;
|
||||
|
||||
public synchronized IMappingProvider getMappingsProvider() {
|
||||
public IMappingProvider getMappingsProvider() {
|
||||
if (mappingProvider == null) {
|
||||
try {
|
||||
mappingProvider = TinyRemapperHelper.create(
|
||||
options.mappingsFile(),
|
||||
options.from(),
|
||||
options.to(),
|
||||
options.remapLocals()
|
||||
getMappingsPath(),
|
||||
getFrom(),
|
||||
getTo(),
|
||||
getOptions().getRemapLocals().get()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + options.mappingsFile(), e);
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + getMappingsPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return mappingProvider;
|
||||
}
|
||||
|
||||
public synchronized MemoryMappingTree getMemoryMappingTree() {
|
||||
public MemoryMappingTree getMemoryMappingTree() {
|
||||
if (memoryMappingTree == null) {
|
||||
memoryMappingTree = new MemoryMappingTree();
|
||||
|
||||
try {
|
||||
MappingReader.read(options.mappingsFile(), memoryMappingTree);
|
||||
MappingReader.read(getMappingsPath(), memoryMappingTree);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + options.mappingsFile(), e);
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + getMappingsPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return memoryMappingTree;
|
||||
}
|
||||
|
||||
public String getFromNamespace() {
|
||||
return options.from();
|
||||
public String getFrom() {
|
||||
return getOptions().getFrom().get();
|
||||
}
|
||||
|
||||
public String getToNamespace() {
|
||||
return options.to();
|
||||
public String getTo() {
|
||||
return getOptions().getTo().get();
|
||||
}
|
||||
|
||||
public Path getMappingsPath() {
|
||||
return getOptions().getMappingsFile().get().getAsFile().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.build.mixin.AnnotationProcessorInvoker;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
|
||||
public class MixinAPMappingService extends Service<MixinAPMappingService.Options> {
|
||||
public static final ServiceType<Options, MixinAPMappingService> TYPE = new ServiceType<>(Options.class, MixinAPMappingService.class);
|
||||
|
||||
// TODO look into seeing if we can make this an option, it likely breaks project isolation.
|
||||
private static final boolean INCLUDE_CROSS_PROJECT_MAPPINGS = true;
|
||||
// Again look into what the result of changing this would be.
|
||||
private static final boolean USE_ALL_SOURCE_SETS = true;
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MixinAPMappingService.class);
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@InputFiles // We need to depend on all the outputs, as we don't know if the mixin mapping will exist at the time of task creation
|
||||
ConfigurableFileCollection getCompileOutputs();
|
||||
@Input
|
||||
Property<String> getMixinMappingFileName();
|
||||
@Input
|
||||
Property<String> getFrom();
|
||||
@Input
|
||||
Property<String> getTo();
|
||||
}
|
||||
|
||||
public static Provider<List<Options>> createOptions(Project thisProject, Provider<String> from, Provider<String> to) {
|
||||
final LoomGradleExtension thisExtension = LoomGradleExtension.get(thisProject);
|
||||
String mappingId = thisExtension.getMappingConfiguration().mappingsIdentifier;
|
||||
|
||||
var providers = new ArrayList<Provider<Options>>();
|
||||
|
||||
Consumer<Project> processProject = project -> {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
Collection<SourceSet> sourceSets = USE_ALL_SOURCE_SETS ? SourceSetHelper.getSourceSets(project) : extension.getMixin().getMixinSourceSets();
|
||||
|
||||
for (SourceSet sourceSet : sourceSets) {
|
||||
LOGGER.debug("Creating MixinAPMappingService for source set: {}", sourceSet.getName());
|
||||
|
||||
var provider = createOptions(
|
||||
thisProject,
|
||||
sourceSet,
|
||||
from,
|
||||
to
|
||||
);
|
||||
|
||||
if (provider != null) {
|
||||
providers.add(provider);
|
||||
} else {
|
||||
LOGGER.debug("Failed to create MixinAPMappingService for source set: {}", sourceSet.getName());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!INCLUDE_CROSS_PROJECT_MAPPINGS) {
|
||||
processProject.accept(thisProject);
|
||||
} else {
|
||||
GradleUtils.allLoomProjects(thisProject.getGradle(), project -> {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
if (!mappingId.equals(extension.getMappingConfiguration().mappingsIdentifier)) {
|
||||
// Only find mixin mappings that are from other projects with the same mapping id.
|
||||
return;
|
||||
}
|
||||
|
||||
processProject.accept(project);
|
||||
});
|
||||
}
|
||||
|
||||
return thisProject.provider(() -> providers.stream().map(Provider::get).toList());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Provider<Options> createOptions(Project project, SourceSet sourceSet, Provider<String> from, Provider<String> to) {
|
||||
final File mixinMappings = AnnotationProcessorInvoker.getMixinMappingsForSourceSet(project, sourceSet);
|
||||
final Task compileTask = project.getTasks().findByName(sourceSet.getCompileJavaTaskName()); // TODO what about other languages?
|
||||
|
||||
if (compileTask == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean containsOutput = false;
|
||||
|
||||
for (File file : compileTask.getOutputs().getFiles()) {
|
||||
if (file.getName().equals(mixinMappings.getName())) {
|
||||
containsOutput = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containsOutput) {
|
||||
LOGGER.warn("Failed to find mixin mappings {} in task outputs: {}", mixinMappings.getName(), compileTask.getOutputs().getFiles());
|
||||
return null;
|
||||
}
|
||||
|
||||
return TYPE.create(project, o -> {
|
||||
o.getCompileOutputs().from(compileTask.getOutputs());
|
||||
o.getMixinMappingFileName().set(mixinMappings.getName());
|
||||
o.getFrom().set(from);
|
||||
o.getTo().set(to);
|
||||
});
|
||||
}
|
||||
|
||||
private IMappingProvider mappingProvider = null;
|
||||
private boolean exists = true;
|
||||
|
||||
public MixinAPMappingService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IMappingProvider getMappingsProvider() {
|
||||
if (!exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mappingProvider == null) {
|
||||
final Path mappingsPath = getMappingsPath();
|
||||
|
||||
if (!Files.exists(mappingsPath)) {
|
||||
exists = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
mappingProvider = TinyRemapperHelper.create(
|
||||
mappingsPath,
|
||||
getOptions().getFrom().get(),
|
||||
getOptions().getTo().get(),
|
||||
false
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + mappingsPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
return mappingProvider;
|
||||
}
|
||||
|
||||
// We should always find the file in the task outputs, regardless of if it exists or not.
|
||||
private Path getMappingsPath() {
|
||||
for (File file : getOptions().getCompileOutputs().getFiles()) {
|
||||
if (file.getName().equals(getOptions().getMixinMappingFileName().get())) {
|
||||
return file.toPath();
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Failed to find mixin mappings file: " + getOptions().getMixinMappingFileName().get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.architectury.loom.extensions.ModBuildExtensions;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.extension.MixinExtension;
|
||||
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
||||
import net.fabricmc.loom.task.RemapJarTask;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
|
||||
public class MixinRefmapService extends Service<MixinRefmapService.Options> {
|
||||
public static final ServiceType<Options, MixinRefmapService> TYPE = new ServiceType<>(Options.class, MixinRefmapService.class);
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@Input
|
||||
ListProperty<String> getMixinConfigs();
|
||||
@Input
|
||||
Property<String> getRefmapName();
|
||||
}
|
||||
|
||||
public static Provider<List<Options>> createOptions(RemapJarTask task) {
|
||||
final Project project = task.getProject();
|
||||
return project.provider(() -> {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
if (!extension.getMixin().getUseLegacyMixinAp().get()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
final MixinExtension mixinExtension = extension.getMixin();
|
||||
|
||||
List<Provider<Options>> options = new ArrayList<>();
|
||||
|
||||
for (SourceSet sourceSet : mixinExtension.getMixinSourceSets()) {
|
||||
MixinExtension.MixinInformationContainer container = Objects.requireNonNull(
|
||||
MixinExtension.getMixinInformationContainer(sourceSet)
|
||||
);
|
||||
|
||||
final List<String> rootPaths = AbstractRemapJarTask.getRootPaths(sourceSet.getResources().getSrcDirs());
|
||||
|
||||
final String refmapName = container.refmapNameProvider().get();
|
||||
final List<String> mixinConfigs = container.sourceSet().getResources()
|
||||
.matching(container.mixinConfigPattern())
|
||||
.getFiles()
|
||||
.stream()
|
||||
.map(AbstractRemapJarTask.relativePath(rootPaths))
|
||||
.toList();
|
||||
|
||||
options.add(createOptions(project, mixinConfigs, refmapName));
|
||||
}
|
||||
|
||||
return options.stream().map(Provider::get).toList();
|
||||
});
|
||||
}
|
||||
|
||||
private static Provider<Options> createOptions(Project project, List<String> mixinConfigs, String refmapName) {
|
||||
return TYPE.create(project, o -> {
|
||||
o.getMixinConfigs().set(mixinConfigs);
|
||||
o.getRefmapName().set(refmapName);
|
||||
});
|
||||
}
|
||||
|
||||
public MixinRefmapService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
public void applyToJar(Path path, boolean readConfigsFromManifest) throws IOException {
|
||||
final FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(path);
|
||||
final List<String> allMixinConfigs = new ArrayList<>();
|
||||
|
||||
if (fabricModJson != null) {
|
||||
allMixinConfigs.addAll(fabricModJson.getMixinConfigurations());
|
||||
}
|
||||
|
||||
if (readConfigsFromManifest) {
|
||||
allMixinConfigs.addAll(ModBuildExtensions.readMixinConfigsFromManifest(path.toFile()));
|
||||
}
|
||||
|
||||
if (allMixinConfigs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> mixinConfigs = getOptions().getMixinConfigs().get().stream()
|
||||
.filter(allMixinConfigs::contains)
|
||||
.toList();
|
||||
final String refmapName = getOptions().getRefmapName().get();
|
||||
|
||||
if (ZipUtils.contains(path, refmapName)) {
|
||||
int transformed = ZipUtils.transformJson(JsonObject.class, path, mixinConfigs.stream().collect(Collectors.toMap(s -> s, s -> json -> {
|
||||
if (!json.has("refmap")) {
|
||||
json.addProperty("refmap", refmapName);
|
||||
}
|
||||
|
||||
return json;
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2021 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.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.newService.Service;
|
||||
import net.fabricmc.loom.util.newService.ServiceFactory;
|
||||
import net.fabricmc.loom.util.newService.ServiceType;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
|
||||
/**
|
||||
* A service that provides mappings for remapping.
|
||||
*/
|
||||
public final class NewMappingsService extends Service<NewMappingsService.Options> implements Closeable {
|
||||
public static ServiceType<Options, NewMappingsService> TYPE = new ServiceType<>(Options.class, NewMappingsService.class);
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@InputFile
|
||||
RegularFileProperty getMappingsFile();
|
||||
@Input
|
||||
Property<String> getFrom();
|
||||
@Input
|
||||
Property<String> getTo();
|
||||
@Input
|
||||
Property<Boolean> getRemapLocals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options for creating a new mappings service, with a given mappings file.
|
||||
*/
|
||||
public static Provider<Options> createOptions(Project project, Path mappingsFile, String from, String to, boolean remapLocals) {
|
||||
return TYPE.create(project, o -> {
|
||||
o.getMappingsFile().set(project.file(mappingsFile));
|
||||
o.getFrom().set(from);
|
||||
o.getTo().set(to);
|
||||
o.getRemapLocals().set(remapLocals);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options for creating a new mappings service, using the mappings as specified in the project's mapping configuration.
|
||||
*/
|
||||
public static Provider<Options> createOptionsWithProjectMappings(Project project, String from, String to) {
|
||||
final MappingConfiguration mappingConfiguration = LoomGradleExtension.get(project).getMappingConfiguration();
|
||||
return createOptions(project, mappingConfiguration.tinyMappings, from, to, false);
|
||||
}
|
||||
|
||||
public NewMappingsService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
private IMappingProvider mappingProvider = null;
|
||||
private MemoryMappingTree memoryMappingTree = null;
|
||||
|
||||
public IMappingProvider getMappingsProvider() {
|
||||
if (mappingProvider == null) {
|
||||
try {
|
||||
mappingProvider = TinyRemapperHelper.create(
|
||||
getMappingsPath(),
|
||||
getFrom(),
|
||||
getTo(),
|
||||
getOptions().getRemapLocals().get()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + getMappingsPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return mappingProvider;
|
||||
}
|
||||
|
||||
public MemoryMappingTree getMemoryMappingTree() {
|
||||
if (memoryMappingTree == null) {
|
||||
memoryMappingTree = new MemoryMappingTree();
|
||||
|
||||
try {
|
||||
MappingReader.read(getMappingsPath(), memoryMappingTree);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read mappings from: " + getMappingsPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return memoryMappingTree;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return getOptions().getFrom().get();
|
||||
}
|
||||
|
||||
public String getTo() {
|
||||
return getOptions().getTo().get();
|
||||
}
|
||||
|
||||
public Path getMappingsPath() {
|
||||
return getOptions().getMappingsFile().get().getAsFile().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
mappingProvider = null;
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,9 @@ import net.fabricmc.loom.util.DeletingFileVisitor;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.newService.Service;
|
||||
import net.fabricmc.loom.util.newService.ServiceFactory;
|
||||
import net.fabricmc.loom.util.newService.ServiceType;
|
||||
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.TinyMappingsReader;
|
||||
|
||||
public final class SourceRemapperService extends Service<SourceRemapperService.Options> {
|
||||
@@ -55,7 +55,7 @@ public final class SourceRemapperService extends Service<SourceRemapperService.O
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@Nested
|
||||
Property<NewMappingsService.Options> getMappings();
|
||||
Property<MappingsService.Options> getMappings();
|
||||
@Input
|
||||
Property<Integer> getJavaCompileRelease();
|
||||
@InputFiles
|
||||
@@ -64,10 +64,10 @@ public final class SourceRemapperService extends Service<SourceRemapperService.O
|
||||
|
||||
public static Provider<Options> createOptions(RemapSourcesJarTask task) {
|
||||
return TYPE.create(task.getProject(), o -> {
|
||||
o.getMappings().set(NewMappingsService.createOptionsWithProjectMappings(
|
||||
o.getMappings().set(MappingsService.createOptionsWithProjectMappings(
|
||||
task.getProject(),
|
||||
task.getSourceNamespace().get(),
|
||||
task.getTargetNamespace().get()
|
||||
task.getSourceNamespace(),
|
||||
task.getTargetNamespace()
|
||||
));
|
||||
o.getJavaCompileRelease().set(SourceRemapper.getJavaCompileRelease(task.getProject()));
|
||||
o.getClasspath().from(task.getClasspath());
|
||||
@@ -123,7 +123,7 @@ public final class SourceRemapperService extends Service<SourceRemapperService.O
|
||||
mercury.setGracefulClasspathChecks(true);
|
||||
mercury.setSourceCompatibilityFromRelease(getOptions().getJavaCompileRelease().get());
|
||||
|
||||
NewMappingsService mappingsService = getServiceFactory().get(getOptions().getMappings());
|
||||
MappingsService mappingsService = getServiceFactory().get(getOptions().getMappings());
|
||||
var tinyMappingsReader = new TinyMappingsReader(mappingsService.getMemoryMappingTree(), mappingsService.getFrom(), mappingsService.getTo()).read();
|
||||
mercury.getProcessors().add(MercuryRemapper.create(tinyMappingsReader));
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
package net.fabricmc.loom.task.service;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -35,111 +36,83 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.invocation.Gradle;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.build.IntermediaryNamespaces;
|
||||
import net.fabricmc.loom.build.mixin.AnnotationProcessorInvoker;
|
||||
import net.fabricmc.loom.extension.RemapperExtensionHolder;
|
||||
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinClasspath;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinClasspathService;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader;
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
import net.fabricmc.tinyremapper.InputTag;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
import net.fabricmc.tinyremapper.extension.mixin.MixinExtension;
|
||||
|
||||
public class TinyRemapperService implements SharedService {
|
||||
public static synchronized TinyRemapperService getOrCreate(SharedServiceManager serviceManager, AbstractRemapJarTask remapJarTask) {
|
||||
final Project project = remapJarTask.getProject();
|
||||
final String to = remapJarTask.getTargetNamespace().get();
|
||||
final String from = remapJarTask.getSourceNamespace().get();
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get();
|
||||
final @Nullable KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project);
|
||||
public class TinyRemapperService extends Service<TinyRemapperService.Options> implements Closeable {
|
||||
public static final ServiceType<Options, TinyRemapperService> TYPE = new ServiceType<>(Options.class, TinyRemapperService.class);
|
||||
|
||||
// Generates an id that is used to share the remapper across projects. This tasks in the remap jar task name to handle custom remap jar tasks separately.
|
||||
final var joiner = new StringJoiner(":");
|
||||
joiner.add(extension.getMappingConfiguration().getBuildServiceName("remapJarService", from, to));
|
||||
joiner.add(remapJarTask.getName());
|
||||
|
||||
if (kotlinClasspathService != null) {
|
||||
joiner.add("kotlin-" + kotlinClasspathService.version());
|
||||
}
|
||||
|
||||
// TODO remove this when removing shared service manager.
|
||||
joiner.add(project.getPath());
|
||||
|
||||
extension.getKnownIndyBsms().get().stream().sorted().forEach(joiner::add);
|
||||
|
||||
if (extension.isForgeLike()) {
|
||||
joiner.add(extension.getPlatform().get().id());
|
||||
}
|
||||
|
||||
final String id = joiner.toString();
|
||||
|
||||
TinyRemapperService service = serviceManager.getOrCreateService(id, () -> {
|
||||
List<IMappingProvider> mappings = new ArrayList<>();
|
||||
mappings.add(MappingsService.createDefault(project, serviceManager, from, to).getMappingsProvider());
|
||||
|
||||
if (legacyMixin) {
|
||||
mappings.add(gradleMixinMappingProvider(serviceManager, project.getGradle(), extension.getMappingConfiguration().mappingsIdentifier, from, to));
|
||||
}
|
||||
|
||||
return new TinyRemapperService(mappings, !legacyMixin, kotlinClasspathService, extension.getKnownIndyBsms().get(), extension.getRemapperExtensions().get(), from, to, project.getObjects());
|
||||
});
|
||||
|
||||
final ConfigurationContainer configurations = project.getConfigurations();
|
||||
ConfigurableFileCollection excludedMinecraftJars = project.files();
|
||||
|
||||
List<Path> classPath = remapJarTask.getClasspath()
|
||||
.minus(configurations.getByName(Constants.Configurations.MINECRAFT_COMPILE_LIBRARIES))
|
||||
.minus(configurations.getByName(Constants.Configurations.MINECRAFT_RUNTIME_LIBRARIES))
|
||||
.minus(excludedMinecraftJars)
|
||||
.getFiles()
|
||||
.stream()
|
||||
.map(File::toPath)
|
||||
.filter(Files::exists)
|
||||
.toList();
|
||||
|
||||
service.readClasspath(classPath);
|
||||
return service;
|
||||
public interface Options extends Service.Options {
|
||||
@Input
|
||||
Property<String> getFrom();
|
||||
@Input
|
||||
Property<String> getTo();
|
||||
@Nested
|
||||
ListProperty<MappingsService.Options> getMappings();
|
||||
@Input
|
||||
Property<Boolean> getUselegacyMixinAP();
|
||||
@Nested
|
||||
ListProperty<MixinAPMappingService.Options> getMixinApMappings();
|
||||
@Nested
|
||||
@Optional
|
||||
Property<KotlinClasspathService.Options> getKotlinClasspathService();
|
||||
@InputFiles
|
||||
ConfigurableFileCollection getClasspath();
|
||||
@Input
|
||||
ListProperty<String> getKnownIndyBsms();
|
||||
@Input
|
||||
ListProperty<RemapperExtensionHolder> getRemapperExtensions();
|
||||
}
|
||||
|
||||
// Add all of the mixin mappings from all loom projects.
|
||||
private static IMappingProvider gradleMixinMappingProvider(SharedServiceManager serviceManager, Gradle gradle, String mappingId, String from, String to) {
|
||||
return out -> GradleUtils.allLoomProjects(gradle, project -> {
|
||||
public static Provider<Options> createOptions(AbstractRemapJarTask remapJarTask) {
|
||||
final Project project = remapJarTask.getProject();
|
||||
return TYPE.create(project, options -> {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final ConfigurationContainer configurations = project.getConfigurations();
|
||||
final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get();
|
||||
final FileCollection classpath = remapJarTask.getClasspath()
|
||||
.minus(configurations.getByName(Constants.Configurations.MINECRAFT_COMPILE_LIBRARIES))
|
||||
.minus(configurations.getByName(Constants.Configurations.MINECRAFT_RUNTIME_LIBRARIES));
|
||||
|
||||
if (!mappingId.equals(extension.getMappingConfiguration().mappingsIdentifier)) {
|
||||
// Only find mixin mappings that are from other projects with the same mapping id.
|
||||
return;
|
||||
options.getFrom().set(remapJarTask.getSourceNamespace());
|
||||
options.getTo().set(remapJarTask.getTargetNamespace());
|
||||
options.getMappings().add(MappingsService.createOptionsWithProjectMappings(project, options.getFrom(), options.getTo()));
|
||||
|
||||
if (legacyMixin) {
|
||||
options.getMixinApMappings().set(MixinAPMappingService.createOptions(project, options.getFrom(), options.getTo().map(to -> IntermediaryNamespaces.replaceMixinIntermediaryNamespace(project, to))));
|
||||
}
|
||||
|
||||
for (SourceSet sourceSet : SourceSetHelper.getSourceSets(project)) {
|
||||
final File mixinMappings = AnnotationProcessorInvoker.getMixinMappingsForSourceSet(project, sourceSet);
|
||||
|
||||
if (!mixinMappings.exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String newTo = IntermediaryNamespaces.replaceMixinIntermediaryNamespace(project, to);
|
||||
MappingsService service = MappingsService.create(serviceManager, mixinMappings.getAbsolutePath(), mixinMappings.toPath(), from, newTo, false);
|
||||
service.getMappingsProvider().load(out);
|
||||
}
|
||||
options.getUselegacyMixinAP().set(legacyMixin);
|
||||
options.getKotlinClasspathService().set(KotlinClasspathService.createOptions(project));
|
||||
options.getClasspath().from(classpath);
|
||||
options.getKnownIndyBsms().set(extension.getKnownIndyBsms());
|
||||
options.getRemapperExtensions().set(extension.getRemapperExtensions());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -151,30 +124,50 @@ public class TinyRemapperService implements SharedService {
|
||||
// Set to true once remapping has started, once set no inputs can be read.
|
||||
private boolean isRemapping = false;
|
||||
|
||||
private TinyRemapperService(List<IMappingProvider> mappings, boolean useMixinExtension, @Nullable KotlinClasspath kotlinClasspath, Set<String> knownIndyBsms, List<RemapperExtensionHolder> remapperExtensions, String sourceNamespace, String targetNamespace, ObjectFactory objectFactory) {
|
||||
TinyRemapper.Builder builder = TinyRemapper.newRemapper().withKnownIndyBsm(knownIndyBsms);
|
||||
public TinyRemapperService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
tinyRemapper = createTinyRemapper();
|
||||
readClasspath();
|
||||
}
|
||||
|
||||
for (IMappingProvider provider : mappings) {
|
||||
builder.withMappings(provider);
|
||||
private TinyRemapper createTinyRemapper() {
|
||||
TinyRemapper.Builder builder = TinyRemapper.newRemapper()
|
||||
.withKnownIndyBsm(Set.copyOf(getOptions().getKnownIndyBsms().get()));
|
||||
|
||||
for (MappingsService.Options options : getOptions().getMappings().get()) {
|
||||
MappingsService mappingsService = getServiceFactory().get(options);
|
||||
builder.withMappings(mappingsService.getMappingsProvider());
|
||||
}
|
||||
|
||||
if (useMixinExtension) {
|
||||
builder.extension(new net.fabricmc.tinyremapper.extension.mixin.MixinExtension());
|
||||
if (!getOptions().getUselegacyMixinAP().get()) {
|
||||
builder.extension(new MixinExtension());
|
||||
}
|
||||
|
||||
if (kotlinClasspath != null) {
|
||||
kotlinRemapperClassloader = KotlinRemapperClassloader.create(kotlinClasspath);
|
||||
if (getOptions().getKotlinClasspathService().isPresent()) {
|
||||
KotlinClasspathService kotlinClasspathService = getServiceFactory().get(getOptions().getKotlinClasspathService());
|
||||
kotlinRemapperClassloader = KotlinRemapperClassloader.create(kotlinClasspathService);
|
||||
builder.extension(kotlinRemapperClassloader.getTinyRemapperExtension());
|
||||
}
|
||||
|
||||
for (RemapperExtensionHolder holder : remapperExtensions) {
|
||||
holder.apply(builder, sourceNamespace, targetNamespace, objectFactory);
|
||||
for (RemapperExtensionHolder holder : getOptions().getRemapperExtensions().get()) {
|
||||
holder.apply(builder, getOptions().getFrom().get(), getOptions().getTo().get());
|
||||
}
|
||||
|
||||
tinyRemapper = builder.build();
|
||||
if (getOptions().getUselegacyMixinAP().get()) {
|
||||
for (MixinAPMappingService.Options options : getOptions().getMixinApMappings().get()) {
|
||||
MixinAPMappingService mixinAPMappingService = getServiceFactory().get(options);
|
||||
IMappingProvider provider = mixinAPMappingService.getMappingsProvider();
|
||||
|
||||
if (provider != null) {
|
||||
builder.withMappings(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public synchronized InputTag getOrCreateTag(Path file) {
|
||||
public InputTag getOrCreateTag(Path file) {
|
||||
InputTag tag = inputTagMap.get(file.toAbsolutePath().toString());
|
||||
|
||||
if (tag == null) {
|
||||
@@ -186,34 +179,30 @@ public class TinyRemapperService implements SharedService {
|
||||
}
|
||||
|
||||
public TinyRemapper getTinyRemapperForRemapping() {
|
||||
synchronized (this) {
|
||||
isRemapping = true;
|
||||
return Objects.requireNonNull(tinyRemapper, "Tiny remapper has not been setup");
|
||||
}
|
||||
isRemapping = true;
|
||||
return Objects.requireNonNull(tinyRemapper, "Tiny remapper has not been setup");
|
||||
}
|
||||
|
||||
public synchronized TinyRemapper getTinyRemapperForInputs() {
|
||||
synchronized (this) {
|
||||
if (isRemapping) {
|
||||
throw new IllegalStateException("Cannot read inputs as remapping has already started");
|
||||
}
|
||||
|
||||
return tinyRemapper;
|
||||
public TinyRemapper getTinyRemapperForInputs() {
|
||||
if (isRemapping) {
|
||||
throw new IllegalStateException("Cannot read inputs as remapping has already started");
|
||||
}
|
||||
|
||||
return tinyRemapper;
|
||||
}
|
||||
|
||||
void readClasspath(List<Path> paths) {
|
||||
private void readClasspath() {
|
||||
List<Path> toRead = new ArrayList<>();
|
||||
|
||||
synchronized (classpath) {
|
||||
for (Path path: paths) {
|
||||
if (classpath.contains(path)) {
|
||||
continue;
|
||||
}
|
||||
for (File file : getOptions().getClasspath().getFiles()) {
|
||||
Path path = file.toPath();
|
||||
|
||||
toRead.add(path);
|
||||
classpath.add(path);
|
||||
if (classpath.contains(path) || Files.notExists(path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
toRead.add(path);
|
||||
classpath.add(path);
|
||||
}
|
||||
|
||||
if (toRead.isEmpty()) {
|
||||
|
||||
@@ -53,24 +53,24 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.build.IntermediaryNamespaces;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration;
|
||||
import net.fabricmc.loom.task.service.LorenzMappingService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
|
||||
public class SourceRemapper {
|
||||
private final Project project;
|
||||
private final SharedServiceManager serviceManager;
|
||||
private final ServiceFactory serviceFactory;
|
||||
private String from;
|
||||
private String to;
|
||||
private final List<Consumer<ProgressLogger>> remapTasks = new ArrayList<>();
|
||||
|
||||
private Mercury mercury;
|
||||
|
||||
public SourceRemapper(Project project, SharedServiceManager serviceManager, boolean toNamed) {
|
||||
this(project, serviceManager, toNamed ? IntermediaryNamespaces.runtimeIntermediary(project) : "named", !toNamed ? IntermediaryNamespaces.runtimeIntermediary(project) : "named");
|
||||
public SourceRemapper(Project project, ServiceFactory serviceFactory, boolean toNamed) {
|
||||
this(project, serviceFactory, toNamed ? IntermediaryNamespaces.runtimeIntermediary(project) : "named", !toNamed ? IntermediaryNamespaces.runtimeIntermediary(project) : "named");
|
||||
}
|
||||
|
||||
public SourceRemapper(Project project, SharedServiceManager serviceManager, String from, String to) {
|
||||
public SourceRemapper(Project project, ServiceFactory serviceFactory, String from, String to) {
|
||||
this.project = project;
|
||||
this.serviceManager = serviceManager;
|
||||
this.serviceFactory = serviceFactory;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
@@ -174,11 +174,12 @@ public class SourceRemapper {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
MappingConfiguration mappingConfiguration = extension.getMappingConfiguration();
|
||||
|
||||
MappingSet mappings = LorenzMappingService.create(serviceManager,
|
||||
mappingConfiguration,
|
||||
LorenzMappingService lorenzMappingService = serviceFactory.get(LorenzMappingService.createOptions(
|
||||
project,
|
||||
mappingConfiguration,
|
||||
Objects.requireNonNull(MappingsNamespace.of(from)),
|
||||
Objects.requireNonNull(MappingsNamespace.of(to))
|
||||
).mappings();
|
||||
Objects.requireNonNull(MappingsNamespace.of(to))));
|
||||
MappingSet mappings = lorenzMappingService.getMappings();
|
||||
|
||||
Mercury mercury = createMercuryWithClassPath(project, MappingsNamespace.of(to) == MappingsNamespace.NAMED);
|
||||
mercury.setSourceCompatibilityFromRelease(getJavaCompileRelease(project));
|
||||
|
||||
@@ -33,11 +33,12 @@ import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import dev.architectury.loom.util.MappingOption;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.srg.InnerClassRemapper;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MappingTree;
|
||||
@@ -64,14 +65,14 @@ public final class TinyRemapperHelper {
|
||||
private TinyRemapperHelper() {
|
||||
}
|
||||
|
||||
public static TinyRemapper getTinyRemapper(Project project, SharedServiceManager serviceManager, String fromM, String toM) throws IOException {
|
||||
return getTinyRemapper(project, serviceManager, fromM, toM, false, (builder) -> { }, Set.of());
|
||||
public static TinyRemapper getTinyRemapper(Project project, ServiceFactory serviceFactory, String fromM, String toM) throws IOException {
|
||||
return getTinyRemapper(project, serviceFactory, fromM, toM, false, (builder) -> { }, Set.of());
|
||||
}
|
||||
|
||||
public static TinyRemapper getTinyRemapper(Project project, SharedServiceManager serviceManager, String fromM, String toM, boolean fixRecords, Consumer<TinyRemapper.Builder> builderConsumer, Set<String> fromClassNames) throws IOException {
|
||||
public static TinyRemapper getTinyRemapper(Project project, ServiceFactory serviceFactory, String fromM, String toM, boolean fixRecords, Consumer<TinyRemapper.Builder> builderConsumer, Set<String> fromClassNames) throws IOException {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final MappingOption mappingOption = MappingOption.forPlatform(extension);
|
||||
MemoryMappingTree mappingTree = extension.getMappingConfiguration().getMappingsService(serviceManager, mappingOption).getMappingTree();
|
||||
MemoryMappingTree mappingTree = extension.getMappingConfiguration().getMappingsService(project, serviceFactory, mappingOption).getMappingTree();
|
||||
|
||||
if (fixRecords && !mappingTree.getSrcNamespace().equals(fromM)) {
|
||||
throw new IllegalStateException("Mappings src namespace must match remap src namespace, expected " + fromM + " but got " + mappingTree.getSrcNamespace());
|
||||
|
||||
@@ -75,6 +75,11 @@ public class GradleTypeAdapter implements TypeAdapterFactory {
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, T property) throws IOException {
|
||||
if (!property.isPresent()) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
|
||||
final Object o = property.get();
|
||||
final TypeAdapter adapter = gson.getAdapter(o.getClass());
|
||||
adapter.write(out, o);
|
||||
@@ -102,6 +107,11 @@ public class GradleTypeAdapter implements TypeAdapterFactory {
|
||||
private static final class RegularFilePropertyTypeAdapter<T extends RegularFileProperty> 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());
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
package net.fabricmc.loom.util.kotlin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@@ -32,27 +33,40 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.Service;
|
||||
import net.fabricmc.loom.util.service.ServiceFactory;
|
||||
import net.fabricmc.loom.util.service.ServiceType;
|
||||
|
||||
public record KotlinClasspathService(Set<URL> classpath, String version) implements KotlinClasspath, SharedService {
|
||||
@Nullable
|
||||
public static KotlinClasspathService getOrCreateIfRequired(SharedServiceManager sharedServiceManager, Project project) {
|
||||
public final class KotlinClasspathService extends Service<KotlinClasspathService.Options> implements KotlinClasspath {
|
||||
public static ServiceType<Options, KotlinClasspathService> TYPE = new ServiceType<>(Options.class, KotlinClasspathService.class);
|
||||
|
||||
public interface Options extends Service.Options {
|
||||
@InputFiles
|
||||
ConfigurableFileCollection getClasspath();
|
||||
@Input
|
||||
Property<String> getKotlinVersion();
|
||||
}
|
||||
|
||||
public static Provider<Options> createOptions(Project project) {
|
||||
if (!KotlinPluginUtils.hasKotlinPlugin(project)) {
|
||||
return null;
|
||||
// Return an empty provider
|
||||
return project.getObjects().property(Options.class);
|
||||
}
|
||||
|
||||
return getOrCreate(sharedServiceManager, project, KotlinPluginUtils.getKotlinPluginVersion(project), KotlinPluginUtils.getKotlinMetadataVersion());
|
||||
return createOptions(
|
||||
project,
|
||||
KotlinPluginUtils.getKotlinPluginVersion(project),
|
||||
KotlinPluginUtils.getKotlinMetadataVersion()
|
||||
);
|
||||
}
|
||||
|
||||
public static synchronized KotlinClasspathService getOrCreate(SharedServiceManager sharedServiceManager, Project project, String kotlinVersion, String kotlinMetadataVersion) {
|
||||
final String id = "kotlinclasspath:%s:%s".formatted(kotlinVersion, kotlinMetadataVersion);
|
||||
return sharedServiceManager.getOrCreateService(id, () -> create(project, kotlinVersion, kotlinMetadataVersion));
|
||||
}
|
||||
|
||||
private static KotlinClasspathService create(Project project, String kotlinVersion, String kotlinMetadataVersion) {
|
||||
private static Provider<Options> createOptions(Project project, String kotlinVersion, String kotlinMetadataVersion) {
|
||||
// Create a detached config to resolve the kotlin std lib for the provided version.
|
||||
Configuration detachedConfiguration = project.getConfigurations().detachedConfiguration(
|
||||
project.getDependencies().create("org.jetbrains.kotlin:kotlin-stdlib:" + kotlinVersion),
|
||||
@@ -60,15 +74,36 @@ public record KotlinClasspathService(Set<URL> classpath, String version) impleme
|
||||
project.getDependencies().create("org.jetbrains.kotlinx:kotlinx-metadata-jvm:" + kotlinMetadataVersion)
|
||||
);
|
||||
|
||||
Set<URL> classpath = detachedConfiguration.getFiles().stream()
|
||||
.map(file -> {
|
||||
try {
|
||||
return file.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}).collect(Collectors.toSet());;
|
||||
return TYPE.create(project, options -> {
|
||||
options.getClasspath().from(detachedConfiguration);
|
||||
options.getKotlinVersion().set(kotlinVersion);
|
||||
});
|
||||
}
|
||||
|
||||
return new KotlinClasspathService(classpath, kotlinVersion);
|
||||
public KotlinClasspathService(Options options, ServiceFactory serviceFactory) {
|
||||
super(options, serviceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String version() {
|
||||
return getOptions().getKotlinVersion().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<URL> classpath() {
|
||||
return getOptions()
|
||||
.getClasspath()
|
||||
.getFiles()
|
||||
.stream()
|
||||
.map(KotlinClasspathService::fileToUrl)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static URL fileToUrl(File file) {
|
||||
try {
|
||||
return file.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.util.service;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.services.BuildService;
|
||||
import org.gradle.api.services.BuildServiceParameters;
|
||||
import org.gradle.build.event.BuildEventsListenerRegistry;
|
||||
import org.gradle.tooling.events.OperationCompletionListener;
|
||||
import org.gradle.tooling.events.task.TaskOperationDescriptor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class BuildSharedServiceManager implements BuildService<BuildServiceParameters.None> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class);
|
||||
private static final String NAME = "loom:sharedServiceManager";
|
||||
|
||||
private SharedServiceManager sharedServiceManager = new BuildSharedServiceManagerImpl();
|
||||
private final AtomicInteger refCount = new AtomicInteger(0);
|
||||
|
||||
public static Provider<BuildSharedServiceManager> createForTask(Task task, BuildEventsListenerRegistry buildEventsListenerRegistry) {
|
||||
Provider<BuildSharedServiceManager> provider = task.getProject().getGradle().getSharedServices().registerIfAbsent(NAME, BuildSharedServiceManager.class, spec -> {
|
||||
});
|
||||
task.usesService(provider);
|
||||
|
||||
final BuildSharedServiceManager serviceManager = provider.get();
|
||||
buildEventsListenerRegistry.onTaskCompletion(registerTaskCompletion(task, serviceManager::onFinish));
|
||||
int count = serviceManager.refCount.incrementAndGet();
|
||||
LOGGER.debug("Creating shared service manager provider for task: {} count: {}", task.getName(), count);
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
public BuildSharedServiceManager() {
|
||||
LOGGER.debug("New BuildSharedServiceManager instance");
|
||||
}
|
||||
|
||||
public SharedServiceManager get() {
|
||||
LOGGER.debug("Shared build service get");
|
||||
return Objects.requireNonNull(sharedServiceManager);
|
||||
}
|
||||
|
||||
private void onFinish() {
|
||||
int count = refCount.decrementAndGet();
|
||||
|
||||
LOGGER.debug("Build service finish. count: {}", count);
|
||||
|
||||
if (count == 0) {
|
||||
sharedServiceManager.onFinish();
|
||||
sharedServiceManager = null;
|
||||
} else if (count < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static Provider<OperationCompletionListener> registerTaskCompletion(Task task, Runnable runnable) {
|
||||
return task.getProject().provider(() -> event -> {
|
||||
if (event.getDescriptor() instanceof TaskOperationDescriptor taskDescriptor) {
|
||||
if (taskDescriptor.getTaskPath().equals(task.getPath())) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final class BuildSharedServiceManagerImpl extends SharedServiceManager {
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.newService;
|
||||
package net.fabricmc.loom.util.service;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.newService;
|
||||
package net.fabricmc.loom.util.service;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -51,8 +51,6 @@ public final class ScopedServiceFactory implements ServiceFactory, Closeable {
|
||||
return service;
|
||||
}
|
||||
|
||||
// TODO skip serialization if we know there is no service with the same type
|
||||
|
||||
// If the service is not already created, serialize the options and check the json map as it may be an equivalent service
|
||||
String key = getOptionsCacheKey(options);
|
||||
//noinspection unchecked
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.util.service;
|
||||
|
||||
public final class ScopedSharedServiceManager extends SharedServiceManager implements AutoCloseable {
|
||||
public ScopedSharedServiceManager() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
onFinish();
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.newService;
|
||||
package net.fabricmc.loom.util.service;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
@@ -22,9 +22,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.newService;
|
||||
package net.fabricmc.loom.util.service;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A factory for creating {@link Service} instances.
|
||||
@@ -38,10 +39,26 @@ public interface ServiceFactory {
|
||||
* @param <S> The service type.
|
||||
* @return The service instance.
|
||||
*/
|
||||
default <O extends Service.Options, S extends Service<O>> S get(Property<O> options) {
|
||||
default <O extends Service.Options, S extends Service<O>> S get(Provider<O> options) {
|
||||
return get(options.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or creates a service instance with the given options, or returns null if the options are not present.
|
||||
* @param options The options to use.
|
||||
* @param <O> The options type.
|
||||
* @param <S> The service type.
|
||||
* @return The service instance, or null if the options are not present.
|
||||
*/
|
||||
@Nullable
|
||||
default <O extends Service.Options, S extends Service<O>> S getOrNull(Provider<O> options) {
|
||||
if (options.isPresent()) {
|
||||
return get(options);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or creates a service instance with the given options.
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.newService;
|
||||
package net.fabricmc.loom.util.service;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.util.service;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface SharedService extends Closeable {
|
||||
@Override
|
||||
default void close() throws IOException {
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.util.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A simple manager for {@link SharedService} to be used across gradle (sub) projects.
|
||||
* This is a basic replacement for gradle's build service api.
|
||||
*/
|
||||
public abstract class SharedServiceManager {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class);
|
||||
private final Map<String, SharedService> sharedServiceMap = new HashMap<>();
|
||||
|
||||
private boolean shutdown = false;
|
||||
|
||||
SharedServiceManager() {
|
||||
LOGGER.info("Creating new SharedServiceManager({})", hashCode());
|
||||
}
|
||||
|
||||
public <S extends SharedService> S getOrCreateService(String id, Supplier<S> function) {
|
||||
synchronized (sharedServiceMap) {
|
||||
if (shutdown) {
|
||||
throw new UnsupportedOperationException("Cannot get or create service has the manager has been shutdown.");
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
S sharedService = (S) sharedServiceMap.get(id);
|
||||
|
||||
if (sharedService == null) {
|
||||
LOGGER.debug("Creating service for {}", id);
|
||||
sharedService = function.get();
|
||||
sharedServiceMap.put(id, sharedService);
|
||||
}
|
||||
|
||||
return sharedService;
|
||||
}
|
||||
}
|
||||
|
||||
protected void onFinish() {
|
||||
synchronized (sharedServiceMap) {
|
||||
shutdown = true;
|
||||
}
|
||||
|
||||
LOGGER.info("Closing SharedServiceManager({})", hashCode());
|
||||
|
||||
final List<IOException> exceptionList = new ArrayList<>();
|
||||
|
||||
for (SharedService sharedService : sharedServiceMap.values()) {
|
||||
try {
|
||||
sharedService.close();
|
||||
} catch (IOException e) {
|
||||
exceptionList.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
sharedServiceMap.clear();
|
||||
|
||||
// This is required to ensure that mercury releases all of the file handles.
|
||||
System.gc();
|
||||
|
||||
if (!exceptionList.isEmpty()) {
|
||||
// Done to try and close all the services.
|
||||
RuntimeException exception = new RuntimeException("Failed to close all shared services");
|
||||
exceptionList.forEach(exception::addSuppressed);
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.util.service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
// Massive hack to work around WorkerExecutor.noIsolation() doing isolation checks.
|
||||
public final class UnsafeWorkQueueHelper {
|
||||
private static final Map<String, SharedService> SERVICE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private UnsafeWorkQueueHelper() {
|
||||
}
|
||||
|
||||
public static String create(SharedService service) {
|
||||
final String uuid = UUID.randomUUID().toString();
|
||||
SERVICE_MAP.put(uuid, service);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public static <S> S get(Property<String> property, Class<S> clazz) {
|
||||
SharedService service = SERVICE_MAP.remove(property.get());
|
||||
|
||||
if (service == null) {
|
||||
throw new NullPointerException("Failed to get service for " + clazz);
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (S) service;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class FabricAPIBenchmark implements GradleProjectTestTrait {
|
||||
allowExistingRepo: true,
|
||||
|
||||
repo: "https://github.com/FabricMC/fabric.git",
|
||||
commit: "efa5891941a32589207dc58c2e77183d599465b8",
|
||||
commit: "41bc64cd617f03d49ecc4a4f7788cb65d465415c",
|
||||
patch: "fabric_api"
|
||||
)
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ class ConfigurationCacheTest extends Specification implements GradleProjectTestT
|
||||
"jar" | _
|
||||
"check" | _
|
||||
"remapSourcesJar" | _
|
||||
"build" | _
|
||||
}
|
||||
|
||||
// Test GradleUtils.configurationInputFile invalidates the cache when the file changes
|
||||
|
||||
@@ -34,7 +34,7 @@ import net.fabricmc.loom.api.remapping.RemapperExtension
|
||||
import net.fabricmc.loom.api.remapping.RemapperParameters
|
||||
import net.fabricmc.loom.util.Constants
|
||||
|
||||
abstract class TestRemapperExtension implements RemapperExtension<Params> {
|
||||
class TestRemapperExtension implements RemapperExtension<Params> {
|
||||
final Params parameters
|
||||
|
||||
@Inject
|
||||
|
||||
@@ -44,10 +44,23 @@ class GradleTypeAdapterTest extends Specification {
|
||||
def json = GradleTypeAdapter.GSON.toJson(property)
|
||||
|
||||
then:
|
||||
1 * property.isPresent() >> true
|
||||
1 * property.get() >> "value"
|
||||
json == "\"value\""
|
||||
}
|
||||
|
||||
def "Empty Property"() {
|
||||
given:
|
||||
def property = Mock(Property)
|
||||
|
||||
when:
|
||||
def json = GradleTypeAdapter.GSON.toJson(property)
|
||||
|
||||
then:
|
||||
1 * property.isPresent() >> false
|
||||
json == "null"
|
||||
}
|
||||
|
||||
@IgnoreIf({ os.windows })
|
||||
def "FileCollection"() {
|
||||
given:
|
||||
@@ -74,11 +87,24 @@ class GradleTypeAdapterTest extends Specification {
|
||||
def json = GradleTypeAdapter.GSON.toJson(regularFileProperty)
|
||||
|
||||
then:
|
||||
1 * regularFileProperty.isPresent() >> true
|
||||
1 * regularFileProperty.get() >> regularFile
|
||||
1 * regularFile.getAsFile() >> file
|
||||
json == "\"${file.getAbsolutePath()}\""
|
||||
}
|
||||
|
||||
def "Empty RegularFileProperty"() {
|
||||
given:
|
||||
def regularFileProperty = Mock(RegularFileProperty)
|
||||
|
||||
when:
|
||||
def json = GradleTypeAdapter.GSON.toJson(regularFileProperty)
|
||||
|
||||
then:
|
||||
1 * regularFileProperty.isPresent() >> false
|
||||
json == "null"
|
||||
}
|
||||
|
||||
def "ListProperty"() {
|
||||
given:
|
||||
def listProperty = Mock(ListProperty)
|
||||
|
||||
@@ -38,6 +38,7 @@ class LoomMocks {
|
||||
def minecraftVersionProperty = GradleTestUtil.mockProperty(minecraftVersion)
|
||||
def intermediaryUrlProperty = GradleTestUtil.mockProperty(intermediaryUrl)
|
||||
def downloaderProperty = GradleTestUtil.mockProperty(Download.&create as Function)
|
||||
def refreshDeps = GradleTestUtil.mockProperty(false)
|
||||
|
||||
Objects.requireNonNull(minecraftVersionProperty.get())
|
||||
|
||||
@@ -45,6 +46,7 @@ class LoomMocks {
|
||||
when(mock.getMinecraftVersion()).thenReturn(minecraftVersionProperty)
|
||||
when(mock.getIntermediaryUrl()).thenReturn(intermediaryUrlProperty)
|
||||
when(mock.getDownloader()).thenReturn(downloaderProperty)
|
||||
when(mock.getRefreshDeps()).thenReturn(refreshDeps)
|
||||
return mock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,15 @@ import spock.lang.Specification
|
||||
|
||||
import net.fabricmc.loom.configuration.providers.BundleMetadata
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarSplitter
|
||||
import net.fabricmc.loom.test.LoomTestConstants
|
||||
import net.fabricmc.loom.test.util.GradleTestUtil
|
||||
import net.fabricmc.loom.util.download.Download
|
||||
|
||||
class MinecraftJarSplitterTest extends Specification {
|
||||
public static final String CLIENT_JAR_URL = "https://launcher.mojang.com/v1/objects/7e46fb47609401970e2818989fa584fd467cd036/client.jar"
|
||||
public static final String SERVER_BUNDLE_JAR_URL = "https://launcher.mojang.com/v1/objects/125e5adf40c659fd3bce3e66e67a16bb49ecc1b9/server.jar"
|
||||
|
||||
public static final File mcJarDir = File.createTempDir()
|
||||
public static final File mcJarDir = new File(LoomTestConstants.TEST_DIR, "jar-splitter")
|
||||
|
||||
def "split jars"() {
|
||||
given:
|
||||
@@ -63,7 +65,9 @@ class MinecraftJarSplitterTest extends Specification {
|
||||
|
||||
if (!dst.exists()) {
|
||||
dst.parentFile.mkdirs()
|
||||
dst << new URL(url).newInputStream()
|
||||
Download.create(url)
|
||||
.defaultCache()
|
||||
.downloadPath(dst.toPath())
|
||||
}
|
||||
|
||||
return dst
|
||||
|
||||
@@ -42,6 +42,7 @@ class FileMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_17_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.17"
|
||||
setupType.setup.delegate = this
|
||||
def mappingFile = setupType.setup.call()
|
||||
when:
|
||||
@@ -71,6 +72,7 @@ class FileMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_17_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.17"
|
||||
def mappingsDownload = VERSION_META_1_17.download('client_mappings')
|
||||
def mappingsFile = new File(tempDir, 'mappings.txt')
|
||||
Download.create(mappingsDownload.url())
|
||||
|
||||
@@ -31,6 +31,7 @@ class IntermediaryMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_17_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.17"
|
||||
when:
|
||||
def mappings = getSingleMapping(new IntermediaryMappingsSpec())
|
||||
def tiny = getTiny(mappings)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
package net.fabricmc.loom.test.unit.layeredmappings
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.function.Supplier
|
||||
import java.util.zip.ZipFile
|
||||
@@ -45,6 +46,7 @@ import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLa
|
||||
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingLayer
|
||||
import net.fabricmc.loom.configuration.providers.mappings.utils.AddConstructorMappingVisitor
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider
|
||||
import net.fabricmc.loom.test.LoomTestConstants
|
||||
import net.fabricmc.loom.test.unit.LoomMocks
|
||||
import net.fabricmc.loom.util.download.Download
|
||||
import net.fabricmc.loom.util.download.DownloadBuilder
|
||||
@@ -60,7 +62,7 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
|
||||
String intermediaryUrl
|
||||
MappingContext mappingContext = new TestMappingContext()
|
||||
|
||||
File tempDir = File.createTempDir()
|
||||
File tempDir = new File(LoomTestConstants.TEST_DIR, "layered/${getClass().name}")
|
||||
|
||||
Map<String, File> mavenFiles = [:]
|
||||
|
||||
@@ -70,8 +72,11 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
|
||||
|
||||
File downloadFile(String url, String name) {
|
||||
File dst = new File(tempDir, name)
|
||||
dst.parentFile.mkdirs()
|
||||
dst << new URL(url).newInputStream()
|
||||
if (!dst.exists()) {
|
||||
Download.create(url)
|
||||
.defaultCache()
|
||||
.downloadPath(dst.toPath())
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
@@ -148,7 +153,15 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay
|
||||
@Override
|
||||
Supplier<MemoryMappingTree> intermediaryTree() {
|
||||
return {
|
||||
IntermediateMappingsService.create(LoomMocks.intermediaryMappingsProviderMock("test", intermediaryUrl), minecraftProvider(), null).memoryMappingTree
|
||||
def path = LoomTestConstants.TEST_DIR.toPath().resolve("intermediary").resolve(Objects.requireNonNull(minecraftVersion()) + ".tiny")
|
||||
|
||||
if (!Files.exists(path)) {
|
||||
Files.createDirectories(path.parent)
|
||||
def provider = LoomMocks.intermediaryMappingsProviderMock(minecraftVersion(), intermediaryUrl)
|
||||
provider.provide(path, null)
|
||||
}
|
||||
|
||||
return IntermediateMappingsService.createMemoryMappingTree(path, MappingsNamespace.OFFICIAL.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class MojangMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_17_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.17"
|
||||
when:
|
||||
def mappings = getLayeredMappings(
|
||||
new IntermediaryMappingsSpec(),
|
||||
@@ -52,6 +53,7 @@ class MojangMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_17_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.17"
|
||||
when:
|
||||
def mappings = getLayeredMappings(
|
||||
new IntermediaryMappingsSpec(),
|
||||
|
||||
@@ -34,6 +34,7 @@ class ParchmentMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_16_5_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.16.5"
|
||||
when:
|
||||
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
|
||||
def mappings = getLayeredMappings(
|
||||
@@ -58,6 +59,7 @@ class ParchmentMappingLayerTest extends LayeredMappingsSpecification {
|
||||
setup:
|
||||
intermediaryUrl = INTERMEDIARY_1_16_5_URL
|
||||
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
|
||||
mockMinecraftProvider.minecraftVersion() >> "1.16.5"
|
||||
when:
|
||||
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
|
||||
def mappings = getLayeredMappings(
|
||||
|
||||
@@ -27,13 +27,13 @@ package net.fabricmc.loom.test.unit.service
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
||||
import net.fabricmc.loom.task.service.NewMappingsService
|
||||
import net.fabricmc.loom.task.service.MappingsService
|
||||
import net.fabricmc.loom.test.util.GradleTestUtil
|
||||
|
||||
class MappingsServiceTest extends ServiceTestBase {
|
||||
def "get mapping tree"() {
|
||||
given:
|
||||
NewMappingsService service = factory.get(new TestOptions(
|
||||
MappingsService service = factory.get(new TestOptions(
|
||||
mappingsFile: GradleTestUtil.mockRegularFileProperty(new File("src/test/resources/mappings/PosInChunk.mappings")),
|
||||
from: GradleTestUtil.mockProperty("intermediary"),
|
||||
to: GradleTestUtil.mockProperty("named"),
|
||||
@@ -49,11 +49,12 @@ class MappingsServiceTest extends ServiceTestBase {
|
||||
service.to == "named"
|
||||
}
|
||||
|
||||
static class TestOptions implements NewMappingsService.Options {
|
||||
static class TestOptions implements MappingsService.Options {
|
||||
RegularFileProperty mappingsFile
|
||||
Property<String> from
|
||||
Property<String> to
|
||||
Property<Boolean> remapLocals = GradleTestUtil.mockProperty(false)
|
||||
Property<String> serviceClass = serviceClassProperty(NewMappingsService.TYPE)
|
||||
Property<Boolean> AllowNoneExistent = GradleTestUtil.mockProperty(false)
|
||||
Property<String> serviceClass = serviceClassProperty(MappingsService.TYPE)
|
||||
}
|
||||
}
|
||||
@@ -31,9 +31,9 @@ import org.gradle.api.tasks.Input
|
||||
import spock.lang.Specification
|
||||
|
||||
import net.fabricmc.loom.test.util.GradleTestUtil
|
||||
import net.fabricmc.loom.util.newService.ScopedServiceFactory
|
||||
import net.fabricmc.loom.util.newService.Service
|
||||
import net.fabricmc.loom.util.newService.ServiceType
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory
|
||||
import net.fabricmc.loom.util.service.Service
|
||||
import net.fabricmc.loom.util.service.ServiceType
|
||||
|
||||
class ScopedServiceFactoryTest extends Specification {
|
||||
def "create service"() {
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.gradle.api.provider.Property
|
||||
import spock.lang.Specification
|
||||
|
||||
import net.fabricmc.loom.test.util.GradleTestUtil
|
||||
import net.fabricmc.loom.util.newService.ScopedServiceFactory
|
||||
import net.fabricmc.loom.util.newService.Service
|
||||
import net.fabricmc.loom.util.newService.ServiceType
|
||||
import net.fabricmc.loom.util.service.ScopedServiceFactory
|
||||
import net.fabricmc.loom.util.service.Service
|
||||
import net.fabricmc.loom.util.service.ServiceType
|
||||
|
||||
abstract class ServiceTestBase extends Specification {
|
||||
ScopedServiceFactory factory
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.provider.Property
|
||||
import org.intellij.lang.annotations.Language
|
||||
|
||||
import net.fabricmc.loom.task.service.NewMappingsService
|
||||
import net.fabricmc.loom.task.service.MappingsService
|
||||
import net.fabricmc.loom.task.service.SourceRemapperService
|
||||
import net.fabricmc.loom.test.util.GradleTestUtil
|
||||
import net.fabricmc.loom.util.DeletingFileVisitor
|
||||
@@ -87,7 +87,7 @@ class SourceRemapperServiceTest extends ServiceTestBase {
|
||||
""".trim()
|
||||
|
||||
static class TestOptions implements SourceRemapperService.Options {
|
||||
Property<NewMappingsService.Options> mappings
|
||||
Property<MappingsService.Options> mappings
|
||||
Property<Integer> javaCompileRelease = GradleTestUtil.mockProperty(17)
|
||||
ConfigurableFileCollection classpath = GradleTestUtil.mockConfigurableFileCollection()
|
||||
Property<String> serviceClass = serviceClassProperty(SourceRemapperService.TYPE)
|
||||
|
||||
@@ -52,6 +52,7 @@ class GradleTestUtil {
|
||||
static <T> Property<T> mockProperty(T value) {
|
||||
def mock = mock(Property.class)
|
||||
when(mock.get()).thenReturn(Objects.requireNonNull(value))
|
||||
when(mock.isPresent()).thenReturn(true)
|
||||
return mock
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user