From 910963a81c6ecfaf98fa97ed036d7ef21907e81d Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:20:10 -0700 Subject: [PATCH] Download intermediary using Gradle (#1042) * Download intermediary using Gradle * address review * Remove ApiWrapper * Use detached configuration --- .../IntermediaryMappingsProvider.java | 56 ++++++++++++++++--- .../IntermediateMappingsProviderInternal.java | 44 +++++++++++++++ .../mappings/IntermediateMappingsService.java | 10 +++- .../extension/LoomGradleExtensionApiImpl.java | 3 +- .../LayeredMappingsSpecification.groovy | 2 +- 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsProviderInternal.java 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 index b56d93e8..bf56a959 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryMappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediaryMappingsProvider.java @@ -27,25 +27,42 @@ package net.fabricmc.loom.configuration.providers.mappings; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +import javax.inject.Inject; import com.google.common.net.UrlEscapers; +import org.gradle.api.Action; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.DependencyArtifact; +import org.gradle.api.artifacts.ModuleDependency; +import org.gradle.api.artifacts.dsl.DependencyFactory; import org.gradle.api.provider.Property; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; +import net.fabricmc.loom.extension.LoomGradleExtensionApiImpl; -public abstract class IntermediaryMappingsProvider extends IntermediateMappingsProvider { +@ApiStatus.Internal +public abstract class IntermediaryMappingsProvider extends IntermediateMappingsProviderInternal { public static final String NAME = "intermediary-v2"; + private static final String FABRIC_INTERMEDIARY_GROUP_NAME = "net.fabricmc:intermediary"; private static final Logger LOGGER = LoggerFactory.getLogger(IntermediateMappingsProvider.class); public abstract Property getIntermediaryUrl(); public abstract Property getRefreshDeps(); + @Inject + public abstract DependencyFactory getDependencyFactory(); + @Override - public void provide(Path tinyMappings) throws IOException { + public void provide(Path tinyMappings, @Nullable Project project) throws IOException { if (Files.exists(tinyMappings) && !getRefreshDeps().get()) { return; } @@ -53,16 +70,37 @@ public abstract class IntermediaryMappingsProvider extends IntermediateMappingsP // Download and extract intermediary final Path intermediaryJarPath = Files.createTempFile(getName(), ".jar"); final String encodedMcVersion = UrlEscapers.urlFragmentEscaper().escape(getMinecraftVersion().get()); - final String url = getIntermediaryUrl().get().formatted(encodedMcVersion); + final String urlRaw = getIntermediaryUrl().get(); - LOGGER.info("Downloading intermediary from {}", url); + if (project != null && urlRaw.equals(LoomGradleExtensionApiImpl.DEFAULT_INTERMEDIARY_URL)) { + final ModuleDependency intermediaryDep = getDependencyFactory() + .create(FABRIC_INTERMEDIARY_GROUP_NAME + ':' + encodedMcVersion); + intermediaryDep.artifact(new Action() { + @Override + public void execute(final DependencyArtifact dependencyArtifact) { + dependencyArtifact.setClassifier("v2"); + } + }); + final Configuration config = project.getConfigurations().detachedConfiguration(intermediaryDep); - Files.deleteIfExists(tinyMappings); - Files.deleteIfExists(intermediaryJarPath); + Files.copy( + config.getSingleFile().toPath(), + intermediaryJarPath, + StandardCopyOption.REPLACE_EXISTING + ); + Files.deleteIfExists(tinyMappings); + } else { + final String url = urlRaw.formatted(encodedMcVersion); - getDownloader().get().apply(url) - .defaultCache() - .downloadPath(intermediaryJarPath); + LOGGER.info("Downloading intermediary from {}", url); + + Files.deleteIfExists(tinyMappings); + Files.deleteIfExists(intermediaryJarPath); + + getDownloader().get().apply(url) + .defaultCache() + .downloadPath(intermediaryJarPath); + } MappingConfiguration.extractMappings(intermediaryJarPath, tinyMappings); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsProviderInternal.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsProviderInternal.java new file mode 100644 index 00000000..8a52448a --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/IntermediateMappingsProviderInternal.java @@ -0,0 +1,44 @@ +/* + * 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.configuration.providers.mappings; + +import java.io.IOException; +import java.nio.file.Path; + +import org.gradle.api.Project; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; + +@ApiStatus.Internal +public abstract class IntermediateMappingsProviderInternal extends IntermediateMappingsProvider { + public abstract void provide(Path tinyMappings, @Nullable Project project) throws IOException; + + @Override + public void provide(Path tinyMappings) throws IOException { + this.provide(tinyMappings, null); + } +} 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 80171fa1..75af308c 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 @@ -61,15 +61,19 @@ public final class IntermediateMappingsService implements SharedService { final IntermediateMappingsProvider intermediateProvider = extension.getIntermediateMappingsProvider(); final String id = "IntermediateMappingsService:%s:%s".formatted(intermediateProvider.getName(), intermediateProvider.getMinecraftVersion().get()); - return sharedServiceManager.getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider)); + return sharedServiceManager.getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider, project)); } @VisibleForTesting - public static IntermediateMappingsService create(IntermediateMappingsProvider intermediateMappingsProvider, MinecraftProvider minecraftProvider) { + public static IntermediateMappingsService create(IntermediateMappingsProvider intermediateMappingsProvider, MinecraftProvider minecraftProvider, Project project) { final Path intermediaryTiny = minecraftProvider.file(intermediateMappingsProvider.getName() + ".tiny").toPath(); try { - intermediateMappingsProvider.provide(intermediaryTiny); + if (intermediateMappingsProvider instanceof IntermediateMappingsProviderInternal internal) { + internal.provide(intermediaryTiny, project); + } else { + intermediateMappingsProvider.provide(intermediaryTiny); + } } catch (IOException e) { try { Files.deleteIfExists(intermediaryTiny); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 56d28ee6..30c63cc9 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -102,6 +102,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA // A common mistake with layered mappings is to call the wrong `officialMojangMappings` method, use this to keep track of when we are building a layered mapping spec. protected final ThreadLocal layeredSpecBuilderScope = ThreadLocal.withInitial(() -> false); + public static final String DEFAULT_INTERMEDIARY_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/%1$s/intermediary-%1$s-v2.jar"; protected boolean hasEvaluatedLayeredMappings = false; protected final Map layeredMappingsDependencyMap = new HashMap<>(); @@ -125,7 +126,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA .convention(true); this.modProvidedJavadoc.finalizeValueOnRead(); this.intermediary = project.getObjects().property(String.class) - .convention("https://maven.fabricmc.net/net/fabricmc/intermediary/%1$s/intermediary-%1$s-v2.jar"); + .convention(DEFAULT_INTERMEDIARY_URL); this.intermediateMappingsProvider = project.getObjects().property(IntermediateMappingsProvider.class); this.intermediateMappingsProvider.finalizeValueOnRead(); 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 629167e9..ff2dd138 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 @@ -141,7 +141,7 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay @Override Supplier intermediaryTree() { return { - IntermediateMappingsService.create(LoomMocks.intermediaryMappingsProviderMock("test", intermediaryUrl), minecraftProvider()).memoryMappingTree + IntermediateMappingsService.create(LoomMocks.intermediaryMappingsProviderMock("test", intermediaryUrl), minecraftProvider(), null).memoryMappingTree } }