From de31f1e0832d659fa69fc05cdaa5e3f5b73e80b3 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Wed, 9 Feb 2022 13:49:15 +0000 Subject: [PATCH] Intermediate mapping handling improvements. (#593) * Add API for intermediate mappings. Add hacky option to run with no intermediate mappings. * Add setter, and some getters that I need :) * Remove unused inject. * Don't add asm-all to the libraries. * Fix unit tests. --- build.gradle | 1 + .../fabricmc/loom/LoomGradleExtension.java | 4 -- .../loom/api/LoomGradleExtensionAPI.java | 19 +++++ .../IntermediateMappingsProvider.java | 47 ++++++++++++ .../mappings/GradleMappingContext.java | 10 ++- .../IntermediaryMappingsProvider.java | 71 +++++++++++++++++++ ....java => IntermediateMappingsService.java} | 45 +++++------- .../mappings/MappingsProviderImpl.java | 8 +-- .../NoOpIntermediateMappingsProvider.java | 51 +++++++++++++ .../mappings/tiny/MappingsMerger.java | 6 +- .../minecraft/MinecraftLibraryProvider.java | 3 + .../extension/LoomGradleExtensionApiImpl.java | 30 ++++++++ .../extension/LoomGradleExtensionImpl.java | 15 ++++ .../test/integration/LegacyProjectTest.groovy | 5 +- .../fabricmc/loom/test/unit/LoomMocks.groovy | 45 ++++++++++++ .../LayeredMappingsSpecification.groovy | 5 +- .../loom/test/util/GradleTestUtil.groovy | 38 ++++++++++ 17 files changed, 359 insertions(+), 44 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/api/mappings/intermediate/IntermediateMappingsProvider.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryMappingsProvider.java rename src/main/java/net/fabricmc/loom/configuration/providers/mappings/{IntermediaryService.java => IntermediateMappingsService.java} (66%) create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/NoOpIntermediateMappingsProvider.java create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy diff --git a/build.gradle b/build.gradle index 08aa6a87..3b98d34a 100644 --- a/build.gradle +++ b/build.gradle @@ -116,6 +116,7 @@ dependencies { exclude group: 'org.jetbrains.kotlin' } testImplementation 'net.fabricmc:fabric-installer:0.9.0' + testImplementation 'org.mockito:mockito-core:4.3.1' compileOnly 'org.jetbrains:annotations:23.0.0' } diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 5514a79f..a654db74 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -112,10 +112,6 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { boolean isRootProject(); - default String getIntermediaryUrl(String minecraftVersion) { - return String.format(this.getIntermediaryUrl().get(), minecraftVersion); - } - @Override MixinExtension getMixin(); diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java index 14c8f0d3..af2479f5 100644 --- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java @@ -35,9 +35,11 @@ import org.gradle.api.publish.maven.MavenPublication; import org.jetbrains.annotations.ApiStatus; import net.fabricmc.loom.api.decompilers.DecompilerOptions; +import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.processors.JarProcessor; +import net.fabricmc.loom.configuration.providers.mappings.NoOpIntermediateMappingsProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.util.DeprecationHelper; @@ -130,6 +132,23 @@ public interface LoomGradleExtensionAPI { */ Property getEnableTransitiveAccessWideners(); + @ApiStatus.Experimental + IntermediateMappingsProvider getIntermediateMappingsProvider(); + + @ApiStatus.Experimental + void setIntermediateMappingsProvider(IntermediateMappingsProvider intermediateMappingsProvider); + + @ApiStatus.Experimental + void setIntermediateMappingsProvider(Class clazz, Action action); + + /** + * An Experimental option to provide empty intermediate mappings, to be used for game versions without any intermediate mappings. + */ + @ApiStatus.Experimental + default void noIntermediateMappings() { + setIntermediateMappingsProvider(NoOpIntermediateMappingsProvider.class, p -> { }); + } + /** * Use "%1$s" as a placeholder for the minecraft version. * diff --git a/src/main/java/net/fabricmc/loom/api/mappings/intermediate/IntermediateMappingsProvider.java b/src/main/java/net/fabricmc/loom/api/mappings/intermediate/IntermediateMappingsProvider.java new file mode 100644 index 00000000..f6b578a3 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/api/mappings/intermediate/IntermediateMappingsProvider.java @@ -0,0 +1,47 @@ +/* + * 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.api.mappings.intermediate; + +import java.io.IOException; +import java.nio.file.Path; + +import org.gradle.api.Named; +import org.gradle.api.provider.Property; +import org.jetbrains.annotations.ApiStatus; + +/** + * A simple API to allow 3rd party plugins. + * Implement by creating an abstract class overriding provide and getName + */ +@ApiStatus.Experimental +public abstract class IntermediateMappingsProvider implements Named { + public abstract Property getMinecraftVersion(); + + /** + * Generate or download a tinyv2 mapping file with intermediary and named namespaces. + * @throws IOException + */ + public abstract void provide(Path tinyMappings) throws IOException; +} 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 e2a83da6..39fe06db 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 @@ -65,7 +65,7 @@ public class GradleMappingContext implements MappingContext { @Override public Supplier intermediaryTree() { - return () -> IntermediaryService.getInstance(project, minecraftProvider()).getMemoryMappingTree(); + return () -> IntermediateMappingsService.getInstance(project, minecraftProvider()).getMemoryMappingTree(); } @Override @@ -82,4 +82,12 @@ public class GradleMappingContext implements MappingContext { public Logger getLogger() { return project.getLogger(); } + + public Project getProject() { + return project; + } + + public LoomGradleExtension getExtension() { + return extension; + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryMappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryMappingsProvider.java new file mode 100644 index 00000000..b29c70f3 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryMappingsProvider.java @@ -0,0 +1,71 @@ +/* + * 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.configuration.providers.mappings; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; + +import com.google.common.net.UrlEscapers; +import org.gradle.api.provider.Property; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; +import net.fabricmc.loom.util.DownloadUtil; + +public abstract class IntermediaryMappingsProvider extends IntermediateMappingsProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(IntermediateMappingsProvider.class); + + public abstract Property getIntermediaryUrl(); + + @Override + public void provide(Path tinyMappings) throws IOException { + if (Files.exists(tinyMappings) && !LoomGradlePlugin.refreshDeps) { + return; + } + + // Download and extract intermediary + final Path intermediaryJarPath = Files.createTempFile(getName(), ".jar"); + final String encodedMcVersion = UrlEscapers.urlFragmentEscaper().escape(getMinecraftVersion().get()); + final URL url = new URL(getIntermediaryUrl().get().formatted(encodedMcVersion)); + + LOGGER.info("Downloading intermediary from {}", url); + + Files.deleteIfExists(tinyMappings); + Files.deleteIfExists(intermediaryJarPath); + + DownloadUtil.downloadIfChanged(url, intermediaryJarPath.toFile(), LOGGER); + MappingsProviderImpl.extractMappings(intermediaryJarPath, tinyMappings); + } + + @Override + public @NotNull String getName() { + return "intermediary-v2"; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryService.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java similarity index 66% rename from src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryService.java rename to src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java index bd0c4e90..13b1427c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryService.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsService.java @@ -25,10 +25,8 @@ package net.fabricmc.loom.configuration.providers.mappings; import java.io.BufferedReader; -import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -37,59 +35,52 @@ import java.util.Objects; import java.util.function.Supplier; import com.google.common.base.Suppliers; -import com.google.common.net.UrlEscapers; import org.gradle.api.Project; import org.jetbrains.annotations.VisibleForTesting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.LoomGradlePlugin; +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.DownloadUtil; import net.fabricmc.loom.util.service.SharedService; import net.fabricmc.loom.util.service.SharedServiceManager; import net.fabricmc.mappingio.adapter.MappingNsCompleter; import net.fabricmc.mappingio.format.Tiny2Reader; import net.fabricmc.mappingio.tree.MemoryMappingTree; -public final class IntermediaryService implements SharedService { - private static final Logger LOGGER = LoggerFactory.getLogger(IntermediaryService.class); - +public final class IntermediateMappingsService implements SharedService { private final Path intermediaryTiny; private final Supplier memoryMappingTree = Suppliers.memoize(this::createMemoryMappingTree); - private IntermediaryService(Path intermediaryTiny) { + private IntermediateMappingsService(Path intermediaryTiny) { this.intermediaryTiny = intermediaryTiny; } - public static synchronized IntermediaryService getInstance(Project project, MinecraftProvider minecraftProvider) { + public static synchronized IntermediateMappingsService getInstance(Project project, MinecraftProvider minecraftProvider) { final LoomGradleExtension extension = LoomGradleExtension.get(project); - final String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftProvider.minecraftVersion()); - final String intermediaryArtifactUrl = extension.getIntermediaryUrl(encodedMinecraftVersion); + final IntermediateMappingsProvider intermediateProvider = extension.getIntermediateMappingsProvider(); + final String id = "IntermediateMappingsService:%s:%s".formatted(intermediateProvider.getName(), intermediateProvider.getMinecraftVersion().get()); - return SharedServiceManager.get(project).getOrCreateService("IntermediaryService:" + intermediaryArtifactUrl, - () -> create(intermediaryArtifactUrl, minecraftProvider)); + return SharedServiceManager.get(project).getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider)); } @VisibleForTesting - public static IntermediaryService create(String intermediaryUrl, MinecraftProvider minecraftProvider) { - final Path intermediaryTiny = minecraftProvider.file("intermediary-v2.tiny").toPath(); - - if (!Files.exists(intermediaryTiny) || LoomGradlePlugin.refreshDeps) { - // Download and extract intermediary - File intermediaryJar = minecraftProvider.file("intermediary-v2.jar"); + public static IntermediateMappingsService create(IntermediateMappingsProvider intermediateMappingsProvider, MinecraftProvider minecraftProvider) { + final Path intermediaryTiny = minecraftProvider.file(intermediateMappingsProvider.getName() + ".tiny").toPath(); + try { + intermediateMappingsProvider.provide(intermediaryTiny); + } catch (IOException e) { try { - DownloadUtil.downloadIfChanged(new URL(intermediaryUrl), intermediaryJar, LOGGER); - MappingsProviderImpl.extractMappings(intermediaryJar.toPath(), intermediaryTiny); - } catch (IOException e) { - throw new UncheckedIOException("Failed to download and extract intermediary", e); + Files.deleteIfExists(intermediaryTiny); + } catch (IOException ex) { + ex.printStackTrace(); } + + throw new UncheckedIOException("Failed to provide intermediate mappings", e); } - return new IntermediaryService(intermediaryTiny); + return new IntermediateMappingsService(intermediaryTiny); } private MemoryMappingTree createMemoryMappingTree() { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index 9b2b78b6..7c02ee4d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -83,9 +83,9 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { private UnpickMetadata unpickMetadata; private Map signatureFixes; - private final Supplier intermediaryService; + private final Supplier intermediaryService; - private MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, Supplier intermediaryService) { + private MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, Supplier intermediaryService) { this.mappingsIdentifier = mappingsIdentifier; this.mappingsWorkingDir = mappingsWorkingDir; @@ -99,7 +99,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { public static synchronized MappingsProviderImpl getInstance(Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) { return SharedServiceManager.get(project).getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> { - Supplier intermediaryService = Suppliers.memoize(() -> IntermediaryService.getInstance(project, minecraftProvider)); + Supplier intermediaryService = Suppliers.memoize(() -> IntermediateMappingsService.getInstance(project, minecraftProvider)); return create(dependency, minecraftProvider, intermediaryService); }); } @@ -108,7 +108,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { return Objects.requireNonNull(mappingTree, "Cannot get mappings before they have been read").get(); } - private static MappingsProviderImpl create(DependencyInfo dependency, MinecraftProvider minecraftProvider, Supplier intermediaryService) { + private static MappingsProviderImpl create(DependencyInfo dependency, MinecraftProvider minecraftProvider, Supplier intermediaryService) { 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"); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/NoOpIntermediateMappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/NoOpIntermediateMappingsProvider.java new file mode 100644 index 00000000..28ddfc63 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/NoOpIntermediateMappingsProvider.java @@ -0,0 +1,51 @@ +/* + * 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.configuration.providers.mappings; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.jetbrains.annotations.NotNull; + +import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; + +/** + * A bit of a hack, creates an empty intermediary mapping file to be used for mc versions without any intermediate mappings. + */ +public abstract class NoOpIntermediateMappingsProvider extends IntermediateMappingsProvider { + private static final String HEADER = "tiny\t2\t0\tofficial\tintermediary"; + + @Override + public void provide(Path tinyMappings) throws IOException { + Files.writeString(tinyMappings, HEADER, StandardCharsets.UTF_8); + } + + @Override + public @NotNull String getName() { + return "empty-intermediate"; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/MappingsMerger.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/MappingsMerger.java index 86aa7afa..5988f143 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/MappingsMerger.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/MappingsMerger.java @@ -38,7 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.configuration.providers.mappings.IntermediaryService; +import net.fabricmc.loom.configuration.providers.mappings.IntermediateMappingsService; import net.fabricmc.mappingio.adapter.MappingNsCompleter; import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; import net.fabricmc.mappingio.format.Tiny2Reader; @@ -49,12 +49,12 @@ import net.fabricmc.mappingio.tree.MemoryMappingTree; public final class MappingsMerger { private static final Logger LOGGER = LoggerFactory.getLogger(MappingsMerger.class); - public static void mergeAndSaveMappings(Path from, Path out, IntermediaryService intermediaryService) throws IOException { + public static void mergeAndSaveMappings(Path from, Path out, IntermediateMappingsService intermediateMappingsService) throws IOException { Stopwatch stopwatch = Stopwatch.createStarted(); LOGGER.info(":merging mappings"); MemoryMappingTree intermediaryTree = new MemoryMappingTree(); - intermediaryService.getMemoryMappingTree().accept(new MappingSourceNsSwitch(intermediaryTree, MappingsNamespace.INTERMEDIARY.toString())); + intermediateMappingsService.getMemoryMappingTree().accept(new MappingSourceNsSwitch(intermediaryTree, MappingsNamespace.INTERMEDIARY.toString())); try (BufferedReader reader = Files.newBufferedReader(from, StandardCharsets.UTF_8)) { Tiny2Reader.read(reader, intermediaryTree); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java index bcc1d148..249a0a06 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java @@ -62,6 +62,9 @@ public class MinecraftLibraryProvider { // 1.4.7 contains an LWJGL version with an invalid maven pom, set the metadata sources to not use the pom for this version. if ("org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3".equals(library.name())) { LoomRepositoryPlugin.setupForLegacyVersions(project); + } else if (library.name().startsWith("org.ow2.asm:asm-all")) { + // Don't want asm-all, use the modern split version. + continue; } if (runtimeOnlyLog4j && library.name().startsWith("org.apache.logging.log4j")) { diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 02b23e2c..d6594e01 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -40,6 +40,7 @@ import net.fabricmc.loom.api.InterfaceInjectionExtensionAPI; import net.fabricmc.loom.api.LoomGradleExtensionAPI; import net.fabricmc.loom.api.MixinExtensionAPI; import net.fabricmc.loom.api.decompilers.DecompilerOptions; +import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.mods.ModVersionParser; @@ -65,6 +66,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA protected final Property setupRemappedVariants; protected final Property transitiveAccessWideners; protected final Property intermediary; + protected final Property intermediateMappingsProvider; private final Property runtimeOnlyLog4j; private final Property minecraftJarConfiguration; private final InterfaceInjectionExtensionAPI interfaceInjectionExtension; @@ -92,6 +94,9 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA this.intermediary = project.getObjects().property(String.class) .convention("https://maven.fabricmc.net/net/fabricmc/intermediary/%1$s/intermediary-%1$s-v2.jar"); + this.intermediateMappingsProvider = project.getObjects().property(IntermediateMappingsProvider.class); + this.intermediateMappingsProvider.finalizeValueOnRead(); + this.versionParser = new ModVersionParser(project); this.deprecationHelper = new DeprecationHelper.ProjectBased(project); @@ -214,6 +219,26 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA return intermediary; } + @Override + public IntermediateMappingsProvider getIntermediateMappingsProvider() { + return intermediateMappingsProvider.get(); + } + + @Override + public void setIntermediateMappingsProvider(IntermediateMappingsProvider intermediateMappingsProvider) { + this.intermediateMappingsProvider.set(intermediateMappingsProvider); + } + + @Override + public void setIntermediateMappingsProvider(Class clazz, Action action) { + T provider = getProject().getObjects().newInstance(clazz); + configureIntermediateMappingsProviderInternal(provider); + action.execute(provider); + intermediateMappingsProvider.set(provider); + } + + protected abstract void configureIntermediateMappingsProviderInternal(T provider); + @Override public void disableDeprecatedPomGeneration(MavenPublication publication) { net.fabricmc.loom.configuration.MavenPublication.excludePublication(publication); @@ -256,6 +281,11 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA throw new RuntimeException("Yeah... something is really wrong"); } + @Override + protected void configureIntermediateMappingsProviderInternal(T provider) { + throw new RuntimeException("Yeah... something is really wrong"); + } + @Override public MixinExtension getMixin() { throw new RuntimeException("Yeah... something is really wrong"); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index d805dcb8..b1871906 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -42,11 +42,13 @@ import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; 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.InstallerData; import net.fabricmc.loom.configuration.LoomDependencyManager; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; import net.fabricmc.loom.configuration.processors.JarProcessorManager; +import net.fabricmc.loom.configuration.providers.mappings.IntermediaryMappingsProvider; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; @@ -78,6 +80,13 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen this.mixinApExtension = project.getObjects().newInstance(MixinExtensionImpl.class, project); this.loomFiles = files; this.unmappedMods = project.files(); + + // Setup the default intermediate mappings provider. + setIntermediateMappingsProvider(IntermediaryMappingsProvider.class, provider -> { + provider.getIntermediaryUrl() + .convention(getIntermediaryUrl()) + .finalizeValueOnRead(); + }); } @Override @@ -226,4 +235,10 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen public void addTransitiveAccessWideners(List accessWidenerFiles) { transitiveAccessWideners.addAll(accessWidenerFiles); } + + @Override + protected void configureIntermediateMappingsProviderInternal(T provider) { + provider.getMinecraftVersion().set(getProject().provider(() -> getMinecraftProvider().minecraftVersion())); + provider.getMinecraftVersion().disallowChanges(); + } } diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/LegacyProjectTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/LegacyProjectTest.groovy index 7996292a..97bdb50e 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/LegacyProjectTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/LegacyProjectTest.groovy @@ -32,7 +32,6 @@ import static net.fabricmc.loom.test.LoomTestConstants.PRE_RELEASE_GRADLE import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS import static org.gradle.testkit.runner.TaskOutcome.SUCCESS -// This test uses gradle 4.9 and 1.14.4 v1 mappings class LegacyProjectTest extends Specification implements GradleProjectTestTrait { @Unroll def "legacy build (gradle #version)"() { @@ -55,7 +54,7 @@ class LegacyProjectTest extends Specification implements GradleProjectTestTrait def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE) gradle.buildGradle << """ loom { - intermediaryUrl = 'https://s.modm.us/intermediary-empty-v2.jar' + noIntermediateMappings() } dependencies { @@ -91,7 +90,7 @@ class LegacyProjectTest extends Specification implements GradleProjectTestTrait def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE) gradle.buildGradle << """ loom { - intermediaryUrl = 'https://s.modm.us/intermediary-empty-v2.jar' + noIntermediateMappings() clientOnlyMinecraftJar() } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy new file mode 100644 index 00000000..1586abdb --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/LoomMocks.groovy @@ -0,0 +1,45 @@ +/* + * 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.test.unit + +import net.fabricmc.loom.configuration.providers.mappings.IntermediaryMappingsProvider +import net.fabricmc.loom.test.util.GradleTestUtil + +import static org.mockito.Mockito.spy +import static org.mockito.Mockito.when + +class LoomMocks { + static IntermediaryMappingsProvider intermediaryMappingsProviderMock(String minecraftVersion, String intermediaryUrl) { + def minecraftVersionProperty = GradleTestUtil.mockProperty(minecraftVersion) + def intermediaryUrlProperty = GradleTestUtil.mockProperty(intermediaryUrl) + + Objects.requireNonNull(minecraftVersionProperty.get()) + + def mock = spy(IntermediaryMappingsProvider.class) + when(mock.getMinecraftVersion()).thenReturn(minecraftVersionProperty) + when(mock.getIntermediaryUrl()).thenReturn(intermediaryUrlProperty) + return mock + } +} 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 e0ce582b..3e226906 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 @@ -28,10 +28,11 @@ import net.fabricmc.loom.api.mappings.layered.MappingContext import net.fabricmc.loom.api.mappings.layered.MappingLayer import net.fabricmc.loom.api.mappings.layered.MappingsNamespace import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec -import net.fabricmc.loom.configuration.providers.mappings.IntermediaryService +import net.fabricmc.loom.configuration.providers.mappings.IntermediateMappingsService import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider +import net.fabricmc.loom.test.unit.LoomMocks import net.fabricmc.mappingio.adapter.MappingDstNsReorder import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch import net.fabricmc.mappingio.format.Tiny2Writer @@ -122,7 +123,7 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay @Override Supplier intermediaryTree() { return { - IntermediaryService.create(intermediaryUrl, minecraftProvider()).memoryMappingTree + IntermediateMappingsService.create(LoomMocks.intermediaryMappingsProviderMock("test", intermediaryUrl), minecraftProvider()).memoryMappingTree } } diff --git a/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy b/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy new file mode 100644 index 00000000..e19660c1 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/util/GradleTestUtil.groovy @@ -0,0 +1,38 @@ +/* + * 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.test.util + +import org.gradle.api.provider.Property + +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.when + +class GradleTestUtil { + static Property mockProperty(T value) { + def mock = mock(Property.class) + when(mock.get()).thenReturn(Objects.requireNonNull(value)) + return mock + } +}