From 7c83033d94e220dfd2bc0c28c8c3f7a83683f2ec Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Sun, 19 Feb 2023 03:16:56 +0200 Subject: [PATCH] Make access transformer spec hash code consistent Fixes #119. --- .../AccessTransformerEntry.java | 65 +++++++++++++++++++ .../AccessTransformerJarProcessor.java | 35 ++++------ .../AccessTransformerJarProcessorTest.groovy | 61 +++++++++++++++++ 3 files changed, 137 insertions(+), 24 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerEntry.java create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/forge/AccessTransformerJarProcessorTest.groovy diff --git a/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerEntry.java b/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerEntry.java new file mode 100644 index 00000000..f8d4942a --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerEntry.java @@ -0,0 +1,65 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2023 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.accesstransformer; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.fmj.FabricModJson; + +public interface AccessTransformerEntry { + Reader openReader() throws IOException; + + record Standalone(Path path, String hash) implements AccessTransformerEntry { + @Override + public Reader openReader() throws IOException { + return Files.newBufferedReader(path); + } + + @Override + public String toString() { + return path.toString(); + } + } + + record Mod(FabricModJson fmj, String hash) implements AccessTransformerEntry { + @Override + public Reader openReader() throws IOException { + final byte[] bytes = fmj.getSource().read(Constants.Forge.ACCESS_TRANSFORMER_PATH); + return new InputStreamReader(new ByteArrayInputStream(bytes), StandardCharsets.UTF_8); + } + + @Override + public String toString() { + return fmj.toString(); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java index 0bf2962b..3371820f 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java @@ -27,6 +27,7 @@ package net.fabricmc.loom.configuration.accesstransformer; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.Reader; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; @@ -43,7 +44,6 @@ import dev.architectury.loom.util.TempFiles; import org.cadixdev.at.AccessTransformSet; import org.cadixdev.at.io.AccessTransformFormats; import org.gradle.api.Project; -import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; @@ -65,11 +65,10 @@ public class AccessTransformerJarProcessor implements MinecraftJarProcessor localAccessTransformers; @Inject - public AccessTransformerJarProcessor(String name, Project project, ConfigurableFileCollection localAccessTransformers) { + public AccessTransformerJarProcessor(String name, Project project, Iterable localAccessTransformers) { this.name = name; this.project = project; this.localAccessTransformers = localAccessTransformers; @@ -89,7 +88,7 @@ public class AccessTransformerJarProcessor implements MinecraftJarProcessor { args.add("--atFile"); @@ -136,14 +126,14 @@ public class AccessTransformerJarProcessor implements MinecraftJarProcessor accessTransformers) throws IOException { + private Path mergeAndRemapAccessTransformers(ProcessorContext context, List accessTransformers, TempFiles tempFiles) throws IOException { AccessTransformSet accessTransformSet = AccessTransformSet.create(); for (AccessTransformerEntry entry : accessTransformers) { - try { - accessTransformSet.merge(AccessTransformFormats.FML.read(entry.path())); + try (Reader reader = entry.openReader()) { + accessTransformSet.merge(AccessTransformFormats.FML.read(reader)); } catch (IOException e) { - throw new IOException("Could not read access transformer " + entry.path(), e); + throw new IOException("Could not read access transformer " + entry, e); } } @@ -193,7 +183,4 @@ public class AccessTransformerJarProcessor implements MinecraftJarProcessor accessTransformers) implements MinecraftJarProcessor.Spec { } - - private record AccessTransformerEntry(Path path, String hash) { - } } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/forge/AccessTransformerJarProcessorTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/forge/AccessTransformerJarProcessorTest.groovy new file mode 100644 index 00000000..5529d4dd --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/forge/AccessTransformerJarProcessorTest.groovy @@ -0,0 +1,61 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2023 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.forge + +import net.fabricmc.loom.api.processor.SpecContext +import net.fabricmc.loom.configuration.accesstransformer.AccessTransformerJarProcessor +import net.fabricmc.loom.util.fmj.FabricModJsonFactory +import org.gradle.api.Project +import spock.lang.Specification +import spock.lang.TempDir + +import java.nio.file.Files +import java.nio.file.Path + +class AccessTransformerJarProcessorTest extends Specification { + private static final String TEST_ACCESS_TRANSFORMER = 'public-f net.minecraft.world.level.block.IronBarsBlock m_54217_(Lnet/minecraft/world/level/block/state/BlockState;Z)Z' + + @TempDir + Path tempDir + + def "consistent spec hash"() { + given: + // Set up mods.toml and access transformer + def metaInf = tempDir.resolve('META-INF') + Files.createDirectory(metaInf) + metaInf.resolve('accesstransformer.cfg').text = TEST_ACCESS_TRANSFORMER + metaInf.resolve('mods.toml').text = '[[mods]]\nmodId="hello"' + + // Create processor and context + def processor = new AccessTransformerJarProcessor('at', Mock(Project), []) + def modJson = FabricModJsonFactory.createFromDirectory(tempDir) + def context = Mock(SpecContext) + context.localMods() >> [modJson] + when: + def spec = processor.buildSpec(context) + then: + spec.hashCode() == 1575235360 + } +}