From 4165168558f5503653154ff5a98c700366e327d7 Mon Sep 17 00:00:00 2001 From: modmuss Date: Mon, 7 Apr 2025 21:01:45 +0100 Subject: [PATCH] Resolve libraries for all platforms when generating verification metadata. (#1286) * Resolve libraries for all platforms when generating verification metadata. * Fix build --- .../fabricmc/loom/LoomGradleExtension.java | 5 ++ .../minecraft/MinecraftLibraryProvider.java | 21 ++++++ .../library/MinecraftLibraryHelper.java | 30 +++++++++ .../extension/LoomGradleExtensionImpl.java | 7 ++ .../test/integration/SignedProjectTest.groovy | 66 +++++++++++++++++++ .../library/MinecraftLibraryHelperTest.groovy | 9 +++ 6 files changed, 138 insertions(+) diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 6d44f4e4..073fb794 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -123,4 +123,9 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { boolean isConfigurationCacheActive(); boolean isProjectIsolationActive(); + + /** + * @return true when '--write-verification-metadata` is set + */ + boolean isCollectingDependencyVerificationMetadata(); } 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 1f6c8404..69eeea53 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 @@ -31,6 +31,7 @@ import java.util.List; import org.gradle.api.JavaVersion; import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.ExternalModuleDependency; import org.gradle.api.artifacts.ModuleDependency; @@ -94,6 +95,10 @@ public class MinecraftLibraryProvider { if (provideServer) { provideServerLibraries(); } + + if (extension.isCollectingDependencyVerificationMetadata()) { + resolveAllLibraries(); + } } private void provideClientLibraries() { @@ -114,6 +119,22 @@ public class MinecraftLibraryProvider { processLibraries.forEach(this::applyServerLibrary); } + /** + * When Gradle is writing dependency verification metadata, we need to resolve all libraries across all platforms, + * to ensure that they are captured. + */ + private void resolveAllLibraries() { + project.getLogger().info("Resolving all libraries for dependency verification metadata generation"); + + final List libraries = MinecraftLibraryHelper.getAllLibraries(minecraftProvider.getVersionInfo()); + Configuration detachedConfiguration = project.getConfigurations().detachedConfiguration( + libraries.stream() + .map(library -> project.getDependencies().create(library.mavenNotation())) + .toArray(Dependency[]::new) + ); + detachedConfiguration.getFiles(); + } + private List processLibraries(List libraries) { final LibraryContext libraryContext = new LibraryContext(minecraftProvider.getVersionInfo(), getTargetRuntimeJavaVersion()); return processorManager.processLibraries(libraries, libraryContext); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/MinecraftLibraryHelper.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/MinecraftLibraryHelper.java index d17e213d..cb9d44f6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/MinecraftLibraryHelper.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/MinecraftLibraryHelper.java @@ -27,6 +27,7 @@ package net.fabricmc.loom.configuration.providers.minecraft.library; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -72,6 +73,35 @@ public class MinecraftLibraryHelper { return Collections.unmodifiableList(libraries); } + public static List getAllLibraries(MinecraftVersionMeta versionMeta) { + var libraries = new ArrayList(); + + for (MinecraftVersionMeta.Library library : versionMeta.libraries()) { + if (library.artifact() != null) { + Library mavenLib = Library.fromMaven(library.name(), Library.Target.COMPILE); + + // Versions that have the natives on the classpath, attempt to target them as natives. + if (mavenLib.classifier() != null && mavenLib.classifier().startsWith("natives-")) { + mavenLib = mavenLib.withTarget(Library.Target.NATIVES); + } + + libraries.add(mavenLib); + } + + Map classifiers = library.downloads().classifiers(); + + if (classifiers == null) { + continue; + } + + for (MinecraftVersionMeta.Download download : classifiers.values()) { + libraries.add(downloadToLibrary(download)); + } + } + + return Collections.unmodifiableList(libraries); + } + private static Library downloadToLibrary(MinecraftVersionMeta.Download download) { final String path = download.path(); final Matcher matcher = NATIVES_PATTERN.matcher(path); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index 6f4b6c64..8ec88fb0 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -77,6 +77,7 @@ public abstract class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl private final ListProperty libraryProcessorFactories; private final boolean configurationCacheActive; private final boolean isolatedProjectsActive; + private final boolean isCollectingDependencyVerificationMetadata; @Inject protected abstract BuildFeatures getBuildFeatures(); @@ -106,6 +107,7 @@ public abstract class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl configurationCacheActive = getBuildFeatures().getConfigurationCache().getActive().get(); isolatedProjectsActive = getBuildFeatures().getIsolatedProjects().getActive().get(); + isCollectingDependencyVerificationMetadata = !project.getGradle().getStartParameter().getWriteDependencyVerifications().isEmpty(); if (refreshDeps) { project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower."); @@ -306,4 +308,9 @@ public abstract class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl public boolean isProjectIsolationActive() { return isolatedProjectsActive; } + + @Override + public boolean isCollectingDependencyVerificationMetadata() { + return isCollectingDependencyVerificationMetadata; + } } diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy index b87f846f..02d857d0 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy @@ -24,6 +24,7 @@ package net.fabricmc.loom.test.integration +import org.intellij.lang.annotations.Language import spock.lang.Specification import spock.lang.Stepwise import spock.lang.Unroll @@ -58,6 +59,71 @@ class SignedProjectTest extends Specification implements MockMavenServerTrait, G version << STANDARD_TEST_VERSIONS } + @Unroll + def "dependency verification #version"() { + setup: + def gradle = gradleProject(project: "minimalBase", version: version) + gradle.buildGradle << """ + dependencies { + minecraft 'com.mojang:minecraft:1.21.5' + mappings 'net.fabricmc:yarn:1.21.5+build.1:v2' + modImplementation 'net.fabricmc:fabric-loader:0.16.12' + modImplementation 'net.fabricmc.fabric-api:fabric-api:0.119.9+1.21.5' + } + """ + + def gradleDir = new File(gradle.projectDir, "gradle") + def verificationMetadata = new File(gradleDir, "verification-metadata.xml") + gradleDir.mkdirs() + verificationMetadata.text = METADATA_TEMPLATE + + when: + def setupResult = gradle.run(tasks: [ + "--write-verification-metadata", + "pgp,sha256", + "dependencies", + "--refresh-keys" + ]) + def checkResult = gradle.run(tasks: ["dependencies"]) + + def result = verificationMetadata.text + println(result) + + then: + setupResult.task(":dependencies").outcome == SUCCESS + checkResult.task(":dependencies").outcome == SUCCESS + + // A quick test to make sure that natives for all platforms are included in the verification metadata + result.contains("jtracy-1.0.29-natives-linux") + result.contains("jtracy-1.0.29-natives-macos") + result.contains("jtracy-1.0.29-natives-windows") + + // Test that the Fabric PGP key is included in the verification metadata + result.contains("9E2B2198D20DC6E4B02C703111B891CFE51C003E") + + where: + version << STANDARD_TEST_VERSIONS + } + + @Language("xml") + static final String METADATA_TEMPLATE = """ + + + + true + true + + + + + + + + + + +""".trim() + static final String PRIVATE_KEY = """ -----BEGIN PGP PRIVATE KEY BLOCK----- diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/library/MinecraftLibraryHelperTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/library/MinecraftLibraryHelperTest.groovy index 30e39051..b2d78552 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/library/MinecraftLibraryHelperTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/library/MinecraftLibraryHelperTest.groovy @@ -76,4 +76,13 @@ class MinecraftLibraryHelperTest extends Specification { then: libraries.find { it.is("ca.weblite:java-objc-bridge") && it.target() == Library.Target.NATIVES } == null } + + def "get all libraries"() { + when: + def meta = MinecraftTestUtils.getVersionMeta("1.21.5") + def libraries = MinecraftLibraryHelper.getAllLibraries(meta) + + then: + libraries.size() > 0 + } }