diff --git a/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java b/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java index d67755c4..f40fc64c 100644 --- a/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java +++ b/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java @@ -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 readMixinConfigsFromManifest(File jarFile) { @@ -49,7 +49,7 @@ public final class ModBuildExtensions { } } - public static void convertAwToAt(SetProperty atAccessWidenersProperty, Path outputFile, Property mappingBuildServiceUuid) throws IOException { + public static void convertAwToAt(ServiceFactory serviceFactory, SetProperty atAccessWidenersProperty, Path outputFile, Property 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); diff --git a/src/main/java/net/fabricmc/loom/api/remapping/RemapperParameters.java b/src/main/java/net/fabricmc/loom/api/remapping/RemapperParameters.java index 32f806a7..2c6a402e 100644 --- a/src/main/java/net/fabricmc/loom/api/remapping/RemapperParameters.java +++ b/src/main/java/net/fabricmc/loom/api/remapping/RemapperParameters.java @@ -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; * *

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(); diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 6b527d0c..9614f5b3 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -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 consumer) { + private void afterEvaluationWithService(Consumer 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); } }); } diff --git a/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java b/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java index 470ac414..aa5ff3c1 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java +++ b/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java @@ -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(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java index 94a4eee4..4a602706 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java @@ -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 { } diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index 18c20c19..7c8051b9 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -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(); diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java index e5867324..6a90736e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java @@ -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); } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index 952a5022..4d321986 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -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 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(); diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ContextImplHelper.java b/src/main/java/net/fabricmc/loom/configuration/processors/ContextImplHelper.java index 283f2cc7..87c70445 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ContextImplHelper.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ContextImplHelper.java @@ -41,7 +41,7 @@ public final class ContextImplHelper { public static LazyCloseable 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); diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java index 689b10aa..205dbdd1 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java @@ -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(); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index e2b684bd..89ac1617 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -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); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java index 4fd53a3a..3db4043c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java @@ -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 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); } }; } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java index a0568de9..b9edaffe 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java @@ -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 { + public static final ServiceType 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 getExpectedSrcNs(); + @Input + Property getMinecraftVersion(); + } + private final Supplier 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 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 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(); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java index e9b4b9e8..a2b72854 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java @@ -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 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 getMappingsServiceOptions(Project project) { + return getMappingsServiceOptions(project, MappingOption.DEFAULT); + } + + public Provider 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(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java index cd32313d..80519337 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java @@ -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 { + public static final ServiceType TYPE = new ServiceType<>(Options.class, TinyMappingsService.class); - public TinyMappingsService(Path tinyMappings) { + public interface Options extends Service.Options { + @InputFile + RegularFileProperty getMappings(); + } + + public static Provider 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 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(); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java index 7094dbf0..620dabee 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java @@ -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 signatureFixes) imp }; } - public static Map getRemappedSignatures(boolean toIntermediary, MappingConfiguration mappingConfiguration, Project project, SharedServiceManager serviceManager, String targetNamespace) throws IOException { + public static Map 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 signatureFixes) imp // Remap the sig fixes from intermediary to the target namespace final Map 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. diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java index 9b2656b0..ac6f2eb2 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java @@ -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 classNames = extension.isForgeLike() ? InnerClassRemapper.readClassNames(remappedJars.inputJar()) : Set.of(); - final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceManager(), toM); + final Map 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 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 classFilter, BiConsumer consumer) throws IOException { + public static void provideForgeSources(Project project, ServiceFactory serviceFactory, Predicate classFilter, BiConsumer consumer) throws IOException { LoomGradleExtension extension = LoomGradleExtension.get(project); String sourceDependency = extension.getForgeUserdevProvider().getConfig().sources(); List forgeInstallerSources = new ArrayList<>(); @@ -140,11 +137,11 @@ public class ForgeSourcesRemapper { Map 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 sources) throws IOException { + private static void remapSources(Project project, ServiceFactory serviceFactory, Map 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 entry : TinyRemapperHelper.JSR_TO_JETBRAINS.entrySet()) { diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 46b03dbd..fcbbc090 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -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); } diff --git a/src/main/java/net/fabricmc/loom/extension/RemapperExtensionHolder.java b/src/main/java/net/fabricmc/loom/extension/RemapperExtensionHolder.java index cb97b954..45f778ff 100644 --- a/src/main/java/net/fabricmc/loom/extension/RemapperExtensionHolder.java +++ b/src/main/java/net/fabricmc/loom/extension/RemapperExtensionHolder.java @@ -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>> getRemapperExtensionClass(); + public abstract Property getRemapperExtensionClass(); - @Nested @Optional - public RemapperParameters getRemapperParameters() { - return remapperParameters; - } + public abstract Property 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> remapperExtensionClass = getRemapperExtensionClass().get(); + //noinspection unchecked + final Class> remapperExtensionClass = (Class>) 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; diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java index 2aeedd79..926bcb3e 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java @@ -230,7 +230,7 @@ public abstract class AbstractRemapJarTask extends Jar { return getInputFile(); } - protected static List getRootPaths(Set files) { + public static List getRootPaths(Set 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 relativePath(List rootPaths) { + public static Function relativePath(List rootPaths) { return file -> { String s = file.getAbsolutePath().replace("\\", "/"); diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index 9a1f79b1..aa710862 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -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 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); } }); } diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index dc343a86..26001eff 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -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()); diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index cc83ab23..f43527ff 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -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 getUseMixinAP(); - - private final Provider serviceManagerProvider; + @Nested + public abstract Property getTinyRemapperServiceOptions(); + @Nested + public abstract ListProperty 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 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 rootPaths = getRootPaths(sourceSet.getResources().getSrcDirs()); - - final String refmapName = container.refmapNameProvider().get(); - final List 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 getPlatform(); RegularFileProperty getInjectAccessWidener(); - + Property getReadMixinConfigsFromManifest(); SetProperty getAtAccessWideners(); Property getUseMixinExtension(); Property getOptimizeFmj(); - record RefmapData(List mixinConfigs, String refmapName) implements Serializable { } - ListProperty getMixinData(); - - Property getTinyRemapperBuildServiceUuid(); - Property getMappingBuildServiceUuid(); + Property getTinyRemapperServiceOptions(); + ListProperty getMixinRefmapServiceOptions(); + Property getMappingsServiceOptions(); } public abstract static class RemapAction extends AbstractRemapAction { 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); - } } diff --git a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java index 6bdecf65..0cee99d3 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java @@ -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 diff --git a/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java b/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java index 7a42a50e..67e100dc 100644 --- a/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java +++ b/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java @@ -56,7 +56,7 @@ public abstract class JarManifestService implements BuildService getMixinVersion(); } - public static synchronized Provider get(Project project) { + public static Provider get(Project project) { return project.getGradle().getSharedServices().registerIfAbsent("LoomJarManifestService:" + project.getName(), JarManifestService.class, spec -> { spec.parameters(params -> { LoomGradleExtension extension = LoomGradleExtension.get(project); diff --git a/src/main/java/net/fabricmc/loom/task/service/LorenzMappingService.java b/src/main/java/net/fabricmc/loom/task/service/LorenzMappingService.java index 5f272560..4bbc2d5f 100644 --- a/src/main/java/net/fabricmc/loom/task/service/LorenzMappingService.java +++ b/src/main/java/net/fabricmc/loom/task/service/LorenzMappingService.java @@ -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 { + public static final ServiceType TYPE = new ServiceType<>(Options.class, LorenzMappingService.class); - public LorenzMappingService(MappingSet mappings) { - this.mappings = mappings; + public interface Options extends Service.Options { + @Nested + Property 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 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 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(); } } diff --git a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java index 4954507e..44a7ced8 100644 --- a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java +++ b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java @@ -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 implements Closeable { + public static ServiceType 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 getFrom(); + @Input + Property getTo(); + @Input + Property 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 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 createOptions(Project project, Path mappingsFile, Provider from, Provider 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 createOptionsWithProjectMappings(Project project, Provider from, Provider 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 diff --git a/src/main/java/net/fabricmc/loom/task/service/MixinAPMappingService.java b/src/main/java/net/fabricmc/loom/task/service/MixinAPMappingService.java new file mode 100644 index 00000000..4f0430b8 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/task/service/MixinAPMappingService.java @@ -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 { + public static final ServiceType 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 getMixinMappingFileName(); + @Input + Property getFrom(); + @Input + Property getTo(); + } + + public static Provider> createOptions(Project thisProject, Provider from, Provider to) { + final LoomGradleExtension thisExtension = LoomGradleExtension.get(thisProject); + String mappingId = thisExtension.getMappingConfiguration().mappingsIdentifier; + + var providers = new ArrayList>(); + + Consumer processProject = project -> { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + + Collection 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 createOptions(Project project, SourceSet sourceSet, Provider from, Provider 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()); + } +} diff --git a/src/main/java/net/fabricmc/loom/task/service/MixinRefmapService.java b/src/main/java/net/fabricmc/loom/task/service/MixinRefmapService.java new file mode 100644 index 00000000..52847b0b --- /dev/null +++ b/src/main/java/net/fabricmc/loom/task/service/MixinRefmapService.java @@ -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 { + public static final ServiceType TYPE = new ServiceType<>(Options.class, MixinRefmapService.class); + + public interface Options extends Service.Options { + @Input + ListProperty getMixinConfigs(); + @Input + Property getRefmapName(); + } + + public static Provider> 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> options = new ArrayList<>(); + + for (SourceSet sourceSet : mixinExtension.getMixinSourceSets()) { + MixinExtension.MixinInformationContainer container = Objects.requireNonNull( + MixinExtension.getMixinInformationContainer(sourceSet) + ); + + final List rootPaths = AbstractRemapJarTask.getRootPaths(sourceSet.getResources().getSrcDirs()); + + final String refmapName = container.refmapNameProvider().get(); + final List 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 createOptions(Project project, List 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 allMixinConfigs = new ArrayList<>(); + + if (fabricModJson != null) { + allMixinConfigs.addAll(fabricModJson.getMixinConfigurations()); + } + + if (readConfigsFromManifest) { + allMixinConfigs.addAll(ModBuildExtensions.readMixinConfigsFromManifest(path.toFile())); + } + + if (allMixinConfigs.isEmpty()) { + return; + } + + final List 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; + }))); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/task/service/NewMappingsService.java b/src/main/java/net/fabricmc/loom/task/service/NewMappingsService.java deleted file mode 100644 index 2e90f40e..00000000 --- a/src/main/java/net/fabricmc/loom/task/service/NewMappingsService.java +++ /dev/null @@ -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 implements Closeable { - public static ServiceType TYPE = new ServiceType<>(Options.class, NewMappingsService.class); - - public interface Options extends Service.Options { - @InputFile - RegularFileProperty getMappingsFile(); - @Input - Property getFrom(); - @Input - Property getTo(); - @Input - Property getRemapLocals(); - } - - /** - * Returns options for creating a new mappings service, with a given mappings file. - */ - public static Provider 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 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; - } -} diff --git a/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java index cf1b2c9b..13b197f7 100644 --- a/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java @@ -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 { @@ -55,7 +55,7 @@ public final class SourceRemapperService extends Service getMappings(); + Property getMappings(); @Input Property getJavaCompileRelease(); @InputFiles @@ -64,10 +64,10 @@ public final class SourceRemapperService extends Service 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 implements Closeable { + public static final ServiceType 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 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 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 getFrom(); + @Input + Property getTo(); + @Nested + ListProperty getMappings(); + @Input + Property getUselegacyMixinAP(); + @Nested + ListProperty getMixinApMappings(); + @Nested + @Optional + Property getKotlinClasspathService(); + @InputFiles + ConfigurableFileCollection getClasspath(); + @Input + ListProperty getKnownIndyBsms(); + @Input + ListProperty 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 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 mappings, boolean useMixinExtension, @Nullable KotlinClasspath kotlinClasspath, Set knownIndyBsms, List 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 paths) { + private void readClasspath() { List 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()) { diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index 18699011..4e7567c1 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -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> 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)); diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java index 50e32aca..72b2ca88 100644 --- a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java +++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java @@ -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 builderConsumer, Set fromClassNames) throws IOException { + public static TinyRemapper getTinyRemapper(Project project, ServiceFactory serviceFactory, String fromM, String toM, boolean fixRecords, Consumer builderConsumer, Set 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()); diff --git a/src/main/java/net/fabricmc/loom/util/gradle/GradleTypeAdapter.java b/src/main/java/net/fabricmc/loom/util/gradle/GradleTypeAdapter.java index 90e7173d..8f4782bc 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/GradleTypeAdapter.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/GradleTypeAdapter.java @@ -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 extends WriteOnlyTypeAdapter { @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()); } diff --git a/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java b/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java index 9657413b..9672dc90 100644 --- a/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java +++ b/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java @@ -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 classpath, String version) implements KotlinClasspath, SharedService { - @Nullable - public static KotlinClasspathService getOrCreateIfRequired(SharedServiceManager sharedServiceManager, Project project) { +public final class KotlinClasspathService extends Service implements KotlinClasspath { + public static ServiceType TYPE = new ServiceType<>(Options.class, KotlinClasspathService.class); + + public interface Options extends Service.Options { + @InputFiles + ConfigurableFileCollection getClasspath(); + @Input + Property getKotlinVersion(); + } + + public static Provider 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 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 classpath, String version) impleme project.getDependencies().create("org.jetbrains.kotlinx:kotlinx-metadata-jvm:" + kotlinMetadataVersion) ); - Set 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 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); + } } } diff --git a/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java deleted file mode 100644 index 6575611d..00000000 --- a/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java +++ /dev/null @@ -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 { - 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 createForTask(Task task, BuildEventsListenerRegistry buildEventsListenerRegistry) { - Provider 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 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 { - } -} diff --git a/src/main/java/net/fabricmc/loom/util/newService/ExampleService.java b/src/main/java/net/fabricmc/loom/util/service/ExampleService.java similarity index 98% rename from src/main/java/net/fabricmc/loom/util/newService/ExampleService.java rename to src/main/java/net/fabricmc/loom/util/service/ExampleService.java index 7417221c..cdb1b2ef 100644 --- a/src/main/java/net/fabricmc/loom/util/newService/ExampleService.java +++ b/src/main/java/net/fabricmc/loom/util/service/ExampleService.java @@ -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; diff --git a/src/main/java/net/fabricmc/loom/util/newService/ScopedServiceFactory.java b/src/main/java/net/fabricmc/loom/util/service/ScopedServiceFactory.java similarity index 97% rename from src/main/java/net/fabricmc/loom/util/newService/ScopedServiceFactory.java rename to src/main/java/net/fabricmc/loom/util/service/ScopedServiceFactory.java index 1648a346..c7d8dbc2 100644 --- a/src/main/java/net/fabricmc/loom/util/newService/ScopedServiceFactory.java +++ b/src/main/java/net/fabricmc/loom/util/service/ScopedServiceFactory.java @@ -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 diff --git a/src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java deleted file mode 100644 index 8431ac3a..00000000 --- a/src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/java/net/fabricmc/loom/util/newService/Service.java b/src/main/java/net/fabricmc/loom/util/service/Service.java similarity index 98% rename from src/main/java/net/fabricmc/loom/util/newService/Service.java rename to src/main/java/net/fabricmc/loom/util/service/Service.java index 0e6ab54c..e22fb775 100644 --- a/src/main/java/net/fabricmc/loom/util/newService/Service.java +++ b/src/main/java/net/fabricmc/loom/util/service/Service.java @@ -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; diff --git a/src/main/java/net/fabricmc/loom/util/newService/ServiceFactory.java b/src/main/java/net/fabricmc/loom/util/service/ServiceFactory.java similarity index 74% rename from src/main/java/net/fabricmc/loom/util/newService/ServiceFactory.java rename to src/main/java/net/fabricmc/loom/util/service/ServiceFactory.java index e6fcdf6e..267405f5 100644 --- a/src/main/java/net/fabricmc/loom/util/newService/ServiceFactory.java +++ b/src/main/java/net/fabricmc/loom/util/service/ServiceFactory.java @@ -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 The service type. * @return The service instance. */ - default > S get(Property options) { + default > S get(Provider 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 The options type. + * @param The service type. + * @return The service instance, or null if the options are not present. + */ + @Nullable + default > S getOrNull(Provider options) { + if (options.isPresent()) { + return get(options); + } else { + return null; + } + } + /** * Gets or creates a service instance with the given options. * diff --git a/src/main/java/net/fabricmc/loom/util/newService/ServiceType.java b/src/main/java/net/fabricmc/loom/util/service/ServiceType.java similarity index 98% rename from src/main/java/net/fabricmc/loom/util/newService/ServiceType.java rename to src/main/java/net/fabricmc/loom/util/service/ServiceType.java index 13f47a18..e8db626b 100644 --- a/src/main/java/net/fabricmc/loom/util/newService/ServiceType.java +++ b/src/main/java/net/fabricmc/loom/util/service/ServiceType.java @@ -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; diff --git a/src/main/java/net/fabricmc/loom/util/service/SharedService.java b/src/main/java/net/fabricmc/loom/util/service/SharedService.java deleted file mode 100644 index 53cb2c7c..00000000 --- a/src/main/java/net/fabricmc/loom/util/service/SharedService.java +++ /dev/null @@ -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 { - } -} diff --git a/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java deleted file mode 100644 index fbdc9820..00000000 --- a/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java +++ /dev/null @@ -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 sharedServiceMap = new HashMap<>(); - - private boolean shutdown = false; - - SharedServiceManager() { - LOGGER.info("Creating new SharedServiceManager({})", hashCode()); - } - - public S getOrCreateService(String id, Supplier 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 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; - } - } -} diff --git a/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java b/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java deleted file mode 100644 index 13ab18bb..00000000 --- a/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java +++ /dev/null @@ -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 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 get(Property property, Class 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; - } -} diff --git a/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy b/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy index 9be4cdbb..d40b9ee5 100644 --- a/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy @@ -44,7 +44,7 @@ class FabricAPIBenchmark implements GradleProjectTestTrait { allowExistingRepo: true, repo: "https://github.com/FabricMC/fabric.git", - commit: "efa5891941a32589207dc58c2e77183d599465b8", + commit: "41bc64cd617f03d49ecc4a4f7788cb65d465415c", patch: "fabric_api" ) diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/ConfigurationCacheTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/ConfigurationCacheTest.groovy index 44d70bdd..79f444a2 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/ConfigurationCacheTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/ConfigurationCacheTest.groovy @@ -61,6 +61,7 @@ class ConfigurationCacheTest extends Specification implements GradleProjectTestT "jar" | _ "check" | _ "remapSourcesJar" | _ + "build" | _ } // Test GradleUtils.configurationInputFile invalidates the cache when the file changes diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/buildSrc/remapext/TestRemapperExtension.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/buildSrc/remapext/TestRemapperExtension.groovy index 7f71841d..233fbca1 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/buildSrc/remapext/TestRemapperExtension.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/buildSrc/remapext/TestRemapperExtension.groovy @@ -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 { +class TestRemapperExtension implements RemapperExtension { final Params parameters @Inject diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/GradleTypeAdapterTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/GradleTypeAdapterTest.groovy index 5efed261..1191734a 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/GradleTypeAdapterTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/GradleTypeAdapterTest.groovy @@ -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) diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy index 3037a2c3..1e0c4116 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy @@ -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 } } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/MinecraftJarSplitterTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/MinecraftJarSplitterTest.groovy index 6d27ecab..1d727790 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/MinecraftJarSplitterTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/MinecraftJarSplitterTest.groovy @@ -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 diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy index 55474054..bf92b1d8 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy @@ -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()) diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy index 5afbf436..1f40a2f3 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/IntermediaryMappingLayerTest.groovy @@ -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) diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy index 83c43dca..a8985796 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy @@ -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 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 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()) } } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy index a14d84fb..9924406a 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/MojangMappingLayerTest.groovy @@ -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(), diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy index ff2dfa1b..478fac43 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy @@ -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( diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/service/MappingsServiceTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/service/MappingsServiceTest.groovy index 97232f09..93f5b6f1 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/service/MappingsServiceTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/service/MappingsServiceTest.groovy @@ -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 from Property to Property remapLocals = GradleTestUtil.mockProperty(false) - Property serviceClass = serviceClassProperty(NewMappingsService.TYPE) + Property AllowNoneExistent = GradleTestUtil.mockProperty(false) + Property serviceClass = serviceClassProperty(MappingsService.TYPE) } } \ No newline at end of file diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/service/ScopedServiceFactoryTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/service/ScopedServiceFactoryTest.groovy index 0b8907e2..8af9bfa6 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/service/ScopedServiceFactoryTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/service/ScopedServiceFactoryTest.groovy @@ -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"() { diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/service/ServiceTestBase.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/service/ServiceTestBase.groovy index 7eba4b3f..5123727c 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/service/ServiceTestBase.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/service/ServiceTestBase.groovy @@ -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 diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/service/SourceRemapperServiceTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/service/SourceRemapperServiceTest.groovy index 51bfb230..0be082c6 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/service/SourceRemapperServiceTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/service/SourceRemapperServiceTest.groovy @@ -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 mappings + Property mappings Property javaCompileRelease = GradleTestUtil.mockProperty(17) ConfigurableFileCollection classpath = GradleTestUtil.mockConfigurableFileCollection() Property serviceClass = serviceClassProperty(SourceRemapperService.TYPE) diff --git a/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy b/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy index c98e8486..4964064f 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy @@ -52,6 +52,7 @@ class GradleTestUtil { static Property mockProperty(T value) { def mock = mock(Property.class) when(mock.get()).thenReturn(Objects.requireNonNull(value)) + when(mock.isPresent()).thenReturn(true) return mock }