From 5d59759a89aa3f817816977e403207cf5065429d Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:55:07 +0200 Subject: [PATCH 1/2] AbstractRemapJarTask: Fix manifests not being inherited (#1421) * AbstractRemapJarTask: Fix manifests not being inherited * Copy manifest before applying manifest service This matches the original ordering of the manifest creation, and fixes the override functionality in the service. * Test merging named sections --- .../loom/task/AbstractRemapJarTask.java | 36 +++++++++++++++++++ .../integration/RemapJarContentsTest.groovy | 4 +++ .../projects/remapJarContents/build.gradle | 10 ++++++ 3 files changed, 50 insertions(+) diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java index 4bea2333..4ec34c31 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.jar.Attributes; import java.util.jar.Manifest; import javax.inject.Inject; @@ -74,6 +75,12 @@ import net.fabricmc.loom.util.gradle.SourceSetHelper; import net.fabricmc.loom.util.service.ScopedServiceFactory; public abstract class AbstractRemapJarTask extends Jar { + /** + * The main input jar to remap. + * Other contents can be added to this task, but this jar must always be present. + * + *

The input file's manifest will be copied into the remapped jar. + */ @InputFile public abstract RegularFileProperty getInputFile(); @@ -143,6 +150,7 @@ public abstract class AbstractRemapJarTask extends Jar { final WorkQueue workQueue = getWorkerExecutor().noIsolation(); workQueue.submit(workAction, params -> { + params.getInputFile().set(getInputFile()); params.getArchiveFile().set(getArchiveFile()); params.getSourceNamespace().set(getSourceNamespace()); @@ -181,6 +189,7 @@ public abstract class AbstractRemapJarTask extends Jar { protected abstract Provider getClientOnlyEntriesOptionsProvider(SourceSet clientSourceSet); public interface AbstractRemapParams extends WorkParameters { + RegularFileProperty getInputFile(); RegularFileProperty getArchiveFile(); Property getSourceNamespace(); @@ -242,11 +251,20 @@ public abstract class AbstractRemapJarTask extends Jar { } } + // Note: the inputFile parameter is the remapping input file. + // The main input jar is available in the parameters, but should not be used + // for remapping as it might be missing some files added manually to this task. protected abstract void execute(Path inputFile) throws IOException; protected void modifyJarManifest() throws IOException { int count = ZipUtils.transform(outputFile, Map.of(Constants.Manifest.PATH, bytes -> { var manifest = new Manifest(new ByteArrayInputStream(bytes)); + byte[] sourceManifestBytes = ZipUtils.unpackNullable(getParameters().getInputFile().get().getAsFile().toPath(), Constants.Manifest.PATH); + + if (sourceManifestBytes != null) { + var sourceManifest = new Manifest(new ByteArrayInputStream(sourceManifestBytes)); + mergeManifests(manifest, sourceManifest); + } getParameters().getJarManifestService().get().apply(manifest, getParameters().getManifestAttributes().get()); manifest.getMainAttributes().putValue(Constants.Manifest.MAPPING_NAMESPACE, getParameters().getTargetNamespace().get()); @@ -268,6 +286,24 @@ public abstract class AbstractRemapJarTask extends Jar { ZipReprocessorUtil.reprocessZip(outputFile, isReproducibleFileOrder, isPreserveFileTimestamps, compression); } } + + private static void mergeManifests(Manifest target, Manifest source) { + mergeAttributes(target.getMainAttributes(), source.getMainAttributes()); + + source.getEntries().forEach((name, sourceAttributes) -> { + final Attributes targetAttributes = target.getAttributes(name); + + if (targetAttributes != null) { + mergeAttributes(targetAttributes, sourceAttributes); + } else { + target.getEntries().put(name, sourceAttributes); + } + }); + } + + private static void mergeAttributes(Attributes target, Attributes source) { + source.forEach(target::putIfAbsent); + } } @Deprecated diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/RemapJarContentsTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/RemapJarContentsTest.groovy index fdf556b5..85bb2e46 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/RemapJarContentsTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/RemapJarContentsTest.groovy @@ -51,6 +51,10 @@ class RemapJarContentsTest extends Specification implements GradleProjectTestTra ZipUtils.contains(gradle.getOutputFile('fabric-example-mod-1.0.0-sources.jar').toPath(), 'test_src_file.txt') def manifest = readManifest(gradle.getOutputFile('fabric-example-mod-1.0.0.jar')) manifest.mainAttributes.getValue('Hello-World') == 'test' + manifest.mainAttributes.getValue('Inherited-In-Remap-Jar') == '1234' + manifest.getAttributes('fabric.mod.json').getValue('Inherited-In-Remap-Jar') == '5678' + manifest.getAttributes('modid.mixins.json').getValue('Hello-World') == 'another test' + manifest.getAttributes('modid.mixins.json').getValue('Inherited-In-Remap-Jar') == '9' where: version << STANDARD_TEST_VERSIONS diff --git a/src/test/resources/projects/remapJarContents/build.gradle b/src/test/resources/projects/remapJarContents/build.gradle index cd411be5..69cfe78c 100644 --- a/src/test/resources/projects/remapJarContents/build.gradle +++ b/src/test/resources/projects/remapJarContents/build.gradle @@ -78,11 +78,21 @@ publishing { } } +jar { + manifest { + attributes 'Inherited-In-Remap-Jar': '1234' + attributes(['Inherited-In-Remap-Jar': '5678'], 'fabric.mod.json') // category not present in remapJar + attributes(['Inherited-In-Remap-Jar': '9'], 'modid.mixins.json') // category present in remapJar + attributes 'Hello-World': 'shadowed in remapJar' + } +} + remapJar { from 'test_file.txt' manifest { attributes 'Hello-World': 'test' + attributes(['Hello-World': 'another test'], 'modid.mixins.json') } } From 43023dc3b885d8c7d1f7be0ce7110179cfd566a8 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 3 Nov 2025 15:09:49 +0000 Subject: [PATCH 2/2] Update unpick --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b71ddb67..571ecdc3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ lorenz-tiny = "4.0.2" mercury = "0.4.3" mercury-mixin = "0.2.2" loom-native = "0.2.0" -unpick = "3.0.0-beta.9" +unpick = "3.0.0-beta.13" # Plugins spotless = "7.2.1"