diff --git a/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java b/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java index 27712c3..4fc8de8 100644 --- a/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java +++ b/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java @@ -25,13 +25,21 @@ package net.fabricmc.loom.build; import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.Path; +import java.util.Collection; import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import org.gradle.api.Project; +import org.jetbrains.annotations.NotNull; import org.zeroturnaround.zip.ZipUtil; import org.zeroturnaround.zip.transform.StringZipEntryTransformer; import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; @@ -43,29 +51,72 @@ import net.fabricmc.loom.extension.MixinApExtension; public final class MixinRefmapHelper { private MixinRefmapHelper() { } + private static final String FABRIC_MOD_JSON = "fabric.mod.json"; + public static boolean addRefmapName(Project project, Path outputPath) { - MixinApExtension mixin = LoomGradleExtension.get(project).getMixin(); - File output = outputPath.toFile(); + try { + MixinApExtension mixin = LoomGradleExtension.get(project).getMixin(); + File output = outputPath.toFile(); - return mixin.getMixinSourceSetsStream().map(sourceSet -> { - MixinApExtension.MixinInformationContainer container = Objects.requireNonNull( - MixinApExtension.getMixinInformationContainer(sourceSet) - ); - Stream mixinJsonNames = container.getMixinJsonNames(); - String refmapName = container.getRefmapName(); + Collection allMixinConfigs = getMixinConfigurationFiles(readFabricModJson(output)); - return ZipUtil.transformEntries(output, mixinJsonNames.map(f -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { - @Override - protected String transform(ZipEntry zipEntry, String input) { - JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class); + return mixin.getMixinSourceSetsStream().map(sourceSet -> { + MixinApExtension.MixinInformationContainer container = Objects.requireNonNull( + MixinApExtension.getMixinInformationContainer(sourceSet) + ); - if (!json.has("refmap")) { - json.addProperty("refmap", refmapName); + Stream mixinConfigs = sourceSet.getResources() + .matching(container.mixinConfigPattern()) + .getFiles() + .stream() + .map(File::getName) + .filter(allMixinConfigs::contains); + + String refmapName = container.refmapNameProvider().get(); + + return ZipUtil.transformEntries(output, mixinConfigs.map(f -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { + @Override + protected String transform(ZipEntry zipEntry, String input) { + JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class); + + if (!json.has("refmap")) { + json.addProperty("refmap", refmapName); + } + + return LoomGradlePlugin.GSON.toJson(json); } + })).toArray(ZipEntryTransformerEntry[]::new)); + }).reduce(false, Boolean::logicalOr); + } catch (Exception e) { + project.getLogger().error(e.getMessage()); + return false; + } + } - return LoomGradlePlugin.GSON.toJson(json); - } - })).toArray(ZipEntryTransformerEntry[]::new)); - }).reduce(false, Boolean::logicalOr); + @NotNull + private static JsonObject readFabricModJson(File output) { + try (ZipFile zip = new ZipFile(output)) { + ZipEntry entry = zip.getEntry(FABRIC_MOD_JSON); + + try (InputStreamReader reader = new InputStreamReader(zip.getInputStream(entry))) { + return LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class); + } + } catch (IOException e) { + throw new RuntimeException("Cannot read file fabric.mod.json in the output jar.", e); + } + } + + @NotNull + private static Collection getMixinConfigurationFiles(JsonObject fabricModJson) { + return StreamSupport.stream(fabricModJson.getAsJsonArray("mixins").spliterator(), false) + .map(e -> { + if (e instanceof JsonPrimitive str) { + return str.getAsString(); + } else if (e instanceof JsonObject obj) { + return obj.get("config").getAsString(); + } else { + throw new RuntimeException("Incorrect fabric.mod.json format"); + } + }).collect(Collectors.toSet()); } } diff --git a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java index 4022185..83ebadf 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -80,7 +80,7 @@ public abstract class AnnotationProcessorInvoker { private void passMixinArguments(T task, SourceSet sourceSet) { try { LoomGradleExtension loom = LoomGradleExtension.get(project); - String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).getRefmapName(); + String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).refmapNameProvider().get(); Map args = new HashMap<>() {{ put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.getCanonicalPath()); put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, loom.getNextMixinMappings().getCanonicalPath()); diff --git a/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java index 04b00c6..d49a473 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java @@ -82,7 +82,7 @@ public class KaptApInvoker extends AnnotationProcessorInvoker { SourceSet sourceSet = entry.getKey(); task.doLast(t -> { try { - String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).getRefmapName(); + String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).refmapNameProvider().get(); Path src = Paths.get(getRefmapDestination(task, refmapName)); Path dest = Paths.get(task.getDestinationDir().toString(), refmapName); diff --git a/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java b/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java index 28f64c3..73e7885 100644 --- a/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java +++ b/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java @@ -26,7 +26,6 @@ package net.fabricmc.loom.extension; import java.util.Collection; import java.util.Map; -import java.util.Objects; import java.util.function.Function; import java.util.stream.Stream; @@ -56,42 +55,7 @@ public interface MixinApExtension extends MixinApExtensionAPI { * for configuring the mixin annotation processor. It's stored * in [SourceSet].ext.mixin. */ - final class MixinInformationContainer { - private final SourceSet sourceSet; - private final Provider refmapName; - private Stream mixinJsonNames; - - final PatternSet mixinJsonPattern; - - public MixinInformationContainer(@NotNull SourceSet sourceSet, - @NotNull Provider refmapName, - @NotNull PatternSet mixinJsonPattern) { - this.sourceSet = sourceSet; - this.refmapName = refmapName; - this.mixinJsonPattern = mixinJsonPattern; - } - - void setMixinJsonNames(@NotNull Stream mixinJsonNames) { - if (this.mixinJsonNames == null) { - this.mixinJsonNames = mixinJsonNames; - } - } - - @NotNull - public Stream getMixinJsonNames() { - return Objects.requireNonNull(mixinJsonNames); - } - - @NotNull - public SourceSet getSourceSet() { - return sourceSet; - } - - @NotNull - public String getRefmapName() { - return refmapName.get(); - } - } + record MixinInformationContainer(SourceSet sourceSet, Provider refmapNameProvider, PatternSet mixinConfigPattern) { } @Nullable static MixinInformationContainer getMixinInformationContainer(SourceSet sourceSet) { diff --git a/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java index bdd306c..3602e75 100644 --- a/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java @@ -24,7 +24,6 @@ package net.fabricmc.loom.extension; -import java.io.File; import java.util.AbstractMap; import java.util.Collection; import java.util.Collections; @@ -79,7 +78,7 @@ public class MixinApExtensionImpl extends MixinApExtensionApiImpl implements Mix @Override protected PatternSet add0(SourceSet sourceSet, Provider refmapName) { - PatternSet pattern = new PatternSet().setIncludes(Collections.singletonList("*.mixins.json")); + PatternSet pattern = new PatternSet().setIncludes(Collections.singletonList("*.json")); MixinApExtension.setMixinInformationContainer(sourceSet, new MixinApExtension.MixinInformationContainer(sourceSet, refmapName, pattern)); isDefault = false; @@ -91,19 +90,7 @@ public class MixinApExtensionImpl extends MixinApExtensionApiImpl implements Mix @NotNull public Stream getMixinSourceSetsStream() { return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().stream() - .filter(sourceSet -> { - MixinApExtension.MixinInformationContainer container = MixinApExtension.getMixinInformationContainer(sourceSet); - - if (container != null) { - PatternSet pattern = container.mixinJsonPattern; - Stream mixinJsonNames = sourceSet.getResources() - .matching(pattern).getFiles().stream().map(File::getName); - container.setMixinJsonNames(mixinJsonNames); - return true; - } - - return false; - }); + .filter(sourceSet -> MixinApExtension.getMixinInformationContainer(sourceSet) != null); } @Override diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy index 80ed7c8..acd16c5 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy @@ -56,7 +56,7 @@ class MixinApAutoRefmapTest extends Specification implements ProjectTestTrait { def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json")))) j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json" - def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m0.mixins.json")))) + def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("blabla.json")))) j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json" def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json")))) @@ -65,6 +65,9 @@ class MixinApAutoRefmapTest extends Specification implements ProjectTestTrait { def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json")))) !j4.asJsonObject.has("refmap") + def j5 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("irrelevant.mixins.json")))) + !j5.asJsonObject.has("refmap") + where: gradle | _ DEFAULT_GRADLE | _ diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json index c8aeaef..62efe82 100644 --- a/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json +++ b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json @@ -23,6 +23,13 @@ ] }, "mixins": [ + "main.mixins.json", + { + "config": "blabla.json", + "environment": "client" + }, + "m1_1.mixins.json", + "m1_2.mixins.json" ], "depends": { diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/m0.mixins.json b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/blabla.json similarity index 100% rename from src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/m0.mixins.json rename to src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/blabla.json diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/irrelevant.mixins.json b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/irrelevant.mixins.json new file mode 100644 index 0000000..e2c4148 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/irrelevant.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin0" + ], + "injectors": { + "defaultRequire": 1 + } +}