From 514dd24e9e2c2a205f506f9d934de634e1bd4bcc Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sat, 1 Oct 2022 08:59:39 +0100 Subject: [PATCH 01/13] Initial support for fabric.mod.json V2 --- .../build/nesting/IncludedJarFactory.java | 4 +- .../loom/build/nesting/JarNester.java | 6 +- .../InterfaceInjectionProcessor.java | 49 ++---- .../mods/AccessWidenerUtils.java | 24 +-- .../mods/ModConfigurationRemapper.java | 4 +- .../processors/ModJavadocProcessor.java | 22 ++- .../net/fabricmc/loom/task/RemapJarTask.java | 14 +- .../fmj/FabricModJson.java} | 66 ++++---- .../loom/util/fmj/FabricModJsonFactory.java | 116 ++++++++++++++ .../loom/util/fmj/FabricModJsonSource.java | 71 +++++++++ .../loom/util/fmj/FabricModJsonUtils.java | 73 +++++++++ .../loom/util/fmj/FabricModJsonV0.java | 89 +++++++++++ .../loom/util/fmj/FabricModJsonV1.java | 101 +++++++++++++ .../loom/util/fmj/FabricModJsonV2.java | 133 ++++++++++++++++ .../ModEnvironment.java} | 38 ++--- .../loom/util/gradle/SourceSetHelper.java | 12 ++ .../test/unit/fmj/FabricModJsonV0Test.groovy | 105 +++++++++++++ .../test/unit/fmj/FabricModJsonV1Test.groovy | 110 ++++++++++++++ .../test/unit/fmj/FabricModJsonV2Test.groovy | 142 ++++++++++++++++++ 19 files changed, 1046 insertions(+), 133 deletions(-) rename src/main/java/net/fabricmc/loom/{build/MixinRefmapHelper.java => util/fmj/FabricModJson.java} (53%) create mode 100644 src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java create mode 100644 src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java create mode 100644 src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonUtils.java create mode 100644 src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV0.java create mode 100644 src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV1.java create mode 100644 src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV2.java rename src/main/java/net/fabricmc/loom/util/{ModUtils.java => fmj/ModEnvironment.java} (60%) create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV0Test.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV1Test.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV2Test.groovy diff --git a/src/main/java/net/fabricmc/loom/build/nesting/IncludedJarFactory.java b/src/main/java/net/fabricmc/loom/build/nesting/IncludedJarFactory.java index 1a833a761..288f1d0bc 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/IncludedJarFactory.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/IncludedJarFactory.java @@ -53,8 +53,8 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.task.RemapTaskConfiguration; -import net.fabricmc.loom.util.ModUtils; import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; public final class IncludedJarFactory { private final Project project; @@ -143,7 +143,7 @@ private ConfigurableFileCollection getProjectDeps(Configuration configuration, S } private File getNestableJar(final File input, final Metadata metadata) { - if (ModUtils.isMod(input)) { + if (FabricModJsonFactory.isModJar(input)) { // Input is a mod, nothing needs to be done. return input; } diff --git a/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java b/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java index 06bf4b576..e495d6a83 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java @@ -38,9 +38,9 @@ import org.gradle.api.UncheckedIOException; import org.slf4j.Logger; -import net.fabricmc.loom.util.ModUtils; import net.fabricmc.loom.util.Pair; import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; public class JarNester { public static void nestJars(Collection jars, File modJar, Logger logger) { @@ -49,7 +49,7 @@ public static void nestJars(Collection jars, File modJar, Logger logger) { return; } - Preconditions.checkArgument(ModUtils.isMod(modJar), "Cannot nest jars into none mod jar " + modJar.getName()); + Preconditions.checkArgument(FabricModJsonFactory.isModJar(modJar), "Cannot nest jars into none mod jar " + modJar.getName()); try { ZipUtils.add(modJar.toPath(), jars.stream().map(file -> { @@ -69,7 +69,7 @@ public static void nestJars(Collection jars, File modJar, Logger logger) { for (File file : jars) { String nestedJarPath = "META-INF/jars/" + file.getName(); - Preconditions.checkArgument(ModUtils.isMod(file), "Cannot nest none mod jar: " + file.getName()); + Preconditions.checkArgument(FabricModJsonFactory.isModJar(file), "Cannot nest none mod jar: " + file.getName()); for (JsonElement nestedJar : nestedJars) { JsonObject jsonObject = nestedJar.getAsJsonObject(); diff --git a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java index 033211390..3ef529abf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; @@ -55,7 +54,6 @@ import org.objectweb.asm.commons.Remapper; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.api.InterfaceInjectionExtensionAPI; import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; @@ -63,10 +61,11 @@ import net.fabricmc.loom.task.GenerateSourcesTask; import net.fabricmc.loom.util.Checksum; import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.ModUtils; import net.fabricmc.loom.util.Pair; import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.fmj.FabricModJson; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.tinyremapper.TinyRemapper; @@ -198,28 +197,15 @@ private List getDependencyInjectedInterfaces() { } private List getSourceInjectedInterface(SourceSet sourceSet) { - final File fabricModJson; + final FabricModJson fabricModJson; try { - fabricModJson = sourceSet.getResources() - .matching(patternFilterable -> patternFilterable.include("fabric.mod.json")) - .getSingleFile(); - } catch (IllegalStateException e) { - // File not found - return Collections.emptyList(); - } - - final String jsonString; - - try { - jsonString = Files.readString(fabricModJson.toPath(), StandardCharsets.UTF_8); + fabricModJson = FabricModJsonFactory.createFromSourceSetNullable(sourceSet); } catch (IOException e) { - throw new UncheckedIOException("Failed to read fabric.mod.json", e); + throw new UncheckedIOException(e); } - final JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(jsonString, JsonObject.class); - - return InjectedInterface.fromJson(jsonObject); + return InjectedInterface.fromFabricModJson(fabricModJson); } @Override @@ -271,29 +257,18 @@ private record InjectedInterface(String modId, String className, String ifaceNam * Reads the injected interfaces contained in a mod jar, or returns empty if there is none. */ public static List fromModJar(Path modJarPath) { - final JsonObject jsonObject = ModUtils.getFabricModJson(modJarPath); - - if (jsonObject == null) { - return Collections.emptyList(); - } - - return fromJson(jsonObject); + return fromFabricModJson(FabricModJsonFactory.createFromZip(modJarPath)); } - public static List fromJson(JsonObject jsonObject) { - final String modId = jsonObject.get("id").getAsString(); - - if (!jsonObject.has("custom")) { - return Collections.emptyList(); - } - - final JsonObject custom = jsonObject.getAsJsonObject("custom"); + public static List fromFabricModJson(FabricModJson fabricModJson) { + final String modId = fabricModJson.getId(); + final JsonElement jsonElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE); - if (!custom.has(Constants.CustomModJsonKeys.INJECTED_INTERFACE)) { + if (jsonElement == null) { return Collections.emptyList(); } - final JsonObject addedIfaces = custom.getAsJsonObject(Constants.CustomModJsonKeys.INJECTED_INTERFACE); + final JsonObject addedIfaces = jsonElement.getAsJsonObject(); final List result = new ArrayList<>(); diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java b/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java index 3f463919b..c2a7e917e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/AccessWidenerUtils.java @@ -25,18 +25,18 @@ package net.fabricmc.loom.configuration.mods; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.util.List; -import com.google.gson.JsonObject; import org.objectweb.asm.commons.Remapper; import net.fabricmc.accesswidener.AccessWidenerReader; import net.fabricmc.accesswidener.AccessWidenerRemapper; import net.fabricmc.accesswidener.AccessWidenerWriter; -import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.fmj.FabricModJson; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; +import net.fabricmc.loom.util.fmj.ModEnvironment; public class AccessWidenerUtils { /** @@ -58,16 +58,20 @@ public static byte[] remapAccessWidener(byte[] input, Remapper remapper) { } public static AccessWidenerData readAccessWidenerData(Path inputJar) throws IOException { - byte[] modJsonBytes = ZipUtils.unpack(inputJar, "fabric.mod.json"); - JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(new String(modJsonBytes, StandardCharsets.UTF_8), JsonObject.class); + final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(inputJar); + final List classTweakers = fabricModJson.getClassTweakers(ModEnvironment.UNIVERSAL); - if (!jsonObject.has("accessWidener")) { + if (classTweakers.isEmpty()) { return null; } - String accessWidenerPath = jsonObject.get("accessWidener").getAsString(); - byte[] accessWidener = ZipUtils.unpack(inputJar, accessWidenerPath); - AccessWidenerReader.Header header = AccessWidenerReader.readHeader(accessWidener); + if (classTweakers.size() != 1) { + throw new UnsupportedOperationException("TODO: support multiple class tweakers"); + } + + final String accessWidenerPath = classTweakers.get(0); + final byte[] accessWidener = fabricModJson.getSource().read(accessWidenerPath); + final AccessWidenerReader.Header header = AccessWidenerReader.readHeader(accessWidener); return new AccessWidenerData(accessWidenerPath, header, accessWidener); } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java index 3f9f8bceb..d29c4c66b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java @@ -55,9 +55,9 @@ import net.fabricmc.loom.configuration.mods.dependency.ModDependencyFactory; import net.fabricmc.loom.util.Checksum; import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.ModUtils; import net.fabricmc.loom.util.OperatingSystem; import net.fabricmc.loom.util.SourceRemapper; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; @SuppressWarnings("UnstableApiUsage") public class ModConfigurationRemapper { @@ -88,7 +88,7 @@ public static void supplyModConfigurations(Project project, String mappingsSuffi final List modDependencies = new ArrayList<>(); for (ArtifactRef artifact : resolveArtifacts(project, sourceConfig)) { - if (!ModUtils.isMod(artifact.path())) { + if (!FabricModJsonFactory.isModJar(artifact.path())) { artifact.applyToConfiguration(project, targetConfig); continue; } diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java b/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java index b06447fe6..e7fc7ecec 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java @@ -35,7 +35,7 @@ import java.util.List; import java.util.Set; -import com.google.gson.JsonObject; +import com.google.gson.JsonElement; import org.gradle.api.Project; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -46,8 +46,9 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.task.GenerateSourcesTask; import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.ModUtils; import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.fmj.FabricModJson; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -70,7 +71,7 @@ public static ModJavadocProcessor create(Project project) { final Set artifacts = entry.getSourceConfiguration().get().resolve(); for (File artifact : artifacts) { - if (!ModUtils.isMod(artifact.toPath())) { + if (!FabricModJsonFactory.isModJar(artifact.toPath())) { continue; } @@ -121,20 +122,15 @@ public void process(File file) { public record ModJavadoc(String modId, MemoryMappingTree mappingTree) { @Nullable public static ModJavadoc fromModJar(Path path) throws IOException { - JsonObject jsonObject = ModUtils.getFabricModJson(path); + final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(path); + final String modId = fabricModJson.getId(); + final JsonElement customElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.PROVIDED_JAVADOC); - if (jsonObject == null || !jsonObject.has("custom")) { + if (customElement == null) { return null; } - final String modId = jsonObject.get("id").getAsString(); - final JsonObject custom = jsonObject.getAsJsonObject("custom"); - - if (!custom.has(Constants.CustomModJsonKeys.PROVIDED_JAVADOC)) { - return null; - } - - final String javaDocPath = custom.getAsJsonPrimitive(Constants.CustomModJsonKeys.PROVIDED_JAVADOC).getAsString(); + final String javaDocPath = customElement.getAsString(); final byte[] data = ZipUtils.unpack(path, javaDocPath); final MemoryMappingTree mappings = new MemoryMappingTree(); diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index 5fc7a01f2..8938f8324 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -58,7 +58,6 @@ import net.fabricmc.accesswidener.AccessWidenerRemapper; import net.fabricmc.accesswidener.AccessWidenerWriter; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.build.MixinRefmapHelper; import net.fabricmc.loom.build.nesting.IncludedJarFactory; import net.fabricmc.loom.build.nesting.JarNester; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; @@ -67,10 +66,11 @@ import net.fabricmc.loom.task.service.TinyRemapperService; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.ExceptionUtil; -import net.fabricmc.loom.util.ModUtils; import net.fabricmc.loom.util.Pair; import net.fabricmc.loom.util.SidedClassVisitor; import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.fmj.FabricModJson; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; @@ -138,14 +138,8 @@ private void setupLegacyMixinRefmapRemapping(RemapParams params) { final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); final MixinExtension mixinExtension = extension.getMixin(); - final JsonObject fabricModJson = ModUtils.getFabricModJson(getInputFile().getAsFile().get().toPath()); - - if (fabricModJson == null) { - getProject().getLogger().warn("Could not find fabric.mod.json file in: " + getInputFile().getAsFile().get().getName()); - return; - } - - final Collection allMixinConfigs = MixinRefmapHelper.getMixinConfigurationFiles(fabricModJson); + final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(getInputFile().getAsFile().get().toPath()); + final Collection allMixinConfigs = fabricModJson.getMixinConfigurations(); for (SourceSet sourceSet : mixinExtension.getMixinSourceSets()) { MixinExtension.MixinInformationContainer container = Objects.requireNonNull( diff --git a/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJson.java similarity index 53% rename from src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java rename to src/main/java/net/fabricmc/loom/util/fmj/FabricModJson.java index 69a246259..50635a52f 100644 --- a/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJson.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2018-2022 FabricMC + * Copyright (c) 2022 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 @@ -22,40 +22,40 @@ * SOFTWARE. */ -package net.fabricmc.loom.build; +package net.fabricmc.loom.util.fmj; -import java.util.Collection; -import java.util.Collections; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; +import static net.fabricmc.loom.util.fmj.FabricModJsonUtils.readString; -import com.google.gson.JsonArray; +import java.util.List; +import java.util.Objects; + +import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import org.jetbrains.annotations.NotNull; - -public final class MixinRefmapHelper { - private MixinRefmapHelper() { } - - private static final String FABRIC_MOD_JSON = "fabric.mod.json"; - - @NotNull - public static Collection getMixinConfigurationFiles(JsonObject fabricModJson) { - JsonArray mixins = fabricModJson.getAsJsonArray("mixins"); - - if (mixins == null) { - return Collections.emptyList(); - } - - return StreamSupport.stream(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()); +import org.jetbrains.annotations.Nullable; + +public abstract sealed class FabricModJson permits FabricModJsonV0, FabricModJsonV1, FabricModJsonV2 { + protected final JsonObject jsonObject; + private final FabricModJsonSource source; + + protected FabricModJson(JsonObject jsonObject, FabricModJsonSource source) { + this.jsonObject = Objects.requireNonNull(jsonObject); + this.source = Objects.requireNonNull(source); + } + + public abstract int getVersion(); + + public String getId() { + return readString(jsonObject, "id"); + } + + @Nullable + public abstract JsonElement getCustom(String key); + + public abstract List getMixinConfigurations(); + + public abstract List getClassTweakers(ModEnvironment modEnvironment); + + public final FabricModJsonSource getSource() { + return source; } } diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java new file mode 100644 index 000000000..390537540 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java @@ -0,0 +1,116 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.fmj; + +import static net.fabricmc.loom.util.fmj.FabricModJsonUtils.readInt; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import com.google.gson.JsonObject; +import org.gradle.api.tasks.SourceSet; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.VisibleForTesting; + +import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.gradle.SourceSetHelper; + +public final class FabricModJsonFactory { + private static final String FABRIC_MOD_JSON = "fabric.mod.json"; + + private FabricModJsonFactory() { + } + + @VisibleForTesting + public static FabricModJson create(JsonObject jsonObject, FabricModJsonSource source) { + int schemaVersion = 0; + + if (jsonObject.has("schemaVersion")) { + // V0 had no schemaVersion key. + schemaVersion = readInt(jsonObject, "schemaVersion"); + } + + return switch (schemaVersion) { + case 0 -> new FabricModJsonV0(jsonObject, source); + case 1 -> new FabricModJsonV1(jsonObject, source); + case 2 -> new FabricModJsonV2(jsonObject, source); + default -> throw new UnsupportedOperationException(String.format("This version of fabric-loom doesn't support the newer fabric.mod.json schema version of (%s) Please update fabric-loom to be able to read this.", schemaVersion)); + }; + } + + public static FabricModJson createFromZip(Path zipPath) { + try { + return create(ZipUtils.unpackGson(zipPath, FABRIC_MOD_JSON, JsonObject.class), new FabricModJsonSource.ZipSource(zipPath)); + } catch (IOException e) { + throw new UncheckedIOException("Failed to read fabric.mod.json file in zip: " + zipPath, e); + } + } + + @Nullable + public static FabricModJson createFromZipNullable(Path zipPath) throws IOException { + JsonObject jsonObject = ZipUtils.unpackGsonNullable(zipPath, FABRIC_MOD_JSON, JsonObject.class); + + if (jsonObject == null) { + return null; + } + + return create(jsonObject, new FabricModJsonSource.ZipSource(zipPath)); + } + + public static FabricModJson createFromDirectory(Path directory) throws IOException { + final Path path = directory.resolve(FABRIC_MOD_JSON); + + try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + return create(LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class), new FabricModJsonSource.DirectorySource(directory)); + } + } + + @Nullable + public static FabricModJson createFromSourceSetNullable(SourceSet sourceSet) throws IOException { + final File file = SourceSetHelper.findFileInResource(sourceSet, FABRIC_MOD_JSON); + + if (file == null) { + return null; + } + + try (Reader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) { + return create(LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class), new FabricModJsonSource.SourceSetSource(sourceSet)); + } + } + + public static boolean isModJar(File file) { + return isModJar(file.toPath()); + } + + public static boolean isModJar(Path input) { + return ZipUtils.contains(input, FABRIC_MOD_JSON); + } +} diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java new file mode 100644 index 000000000..b803add01 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java @@ -0,0 +1,71 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.fmj; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.gradle.api.tasks.SourceSet; + +import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.gradle.SourceSetHelper; + +/** + * A mod may be a zip, directory or Gradle {@link SourceSet} + * This abstraction allows easily reading a contained file from the mod. + */ +public interface FabricModJsonSource { + byte[] read(String path) throws IOException; + + record ZipSource(Path zipPath) implements FabricModJsonSource { + @Override + public byte[] read(String path) throws IOException { + return ZipUtils.unpack(zipPath, path); + } + } + + record DirectorySource(Path directoryPath) implements FabricModJsonSource { + @Override + public byte[] read(String path) throws IOException { + return Files.readAllBytes(directoryPath.resolve(path)); + } + } + + record SourceSetSource(SourceSet sourceSet) implements FabricModJsonSource { + @Override + public byte[] read(String path) throws IOException { + final File file = SourceSetHelper.findFileInResource(sourceSet, path); + + if (file == null) { + throw new FileNotFoundException("Could not find: " + path); + } + + return Files.readAllBytes(file.toPath()); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonUtils.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonUtils.java new file mode 100644 index 000000000..78b94032d --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonUtils.java @@ -0,0 +1,73 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.fmj; + +import java.util.Locale; +import java.util.function.Predicate; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +final class FabricModJsonUtils { + private FabricModJsonUtils() { + } + + public static String readString(JsonObject jsonObject, String key) { + final JsonElement element = getElement(jsonObject, key); + ensurePrimitive(element, JsonPrimitive::isString, key); + + return element.getAsString(); + } + + public static int readInt(JsonObject jsonObject, String key) { + final JsonElement element = getElement(jsonObject, key); + ensurePrimitive(element, JsonPrimitive::isNumber, key); + + return element.getAsInt(); + } + + private static JsonElement getElement(JsonObject jsonObject, String key) { + final JsonElement element = jsonObject.get(key); + + if (element == null) { + throw new ParseException("Unable to find json element for key (%s)", key); + } + + return element; + } + + private static void ensurePrimitive(JsonElement jsonElement, Predicate predicate, String key) { + if (!jsonElement.isJsonPrimitive() || !predicate.test(jsonElement.getAsJsonPrimitive())) { + throw new ParseException("Unexpected primitive type for key (%s)", key); + } + } + + static class ParseException extends RuntimeException { + ParseException(String message, Object... args) { + super(String.format(Locale.ROOT, message, args)); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV0.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV0.java new file mode 100644 index 000000000..ff3adaea3 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV0.java @@ -0,0 +1,89 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.fmj; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import org.jetbrains.annotations.Nullable; + +@Deprecated +public final class FabricModJsonV0 extends FabricModJson { + FabricModJsonV0(JsonObject jsonObject, FabricModJsonSource source) { + super(jsonObject, source); + } + + @Override + public int getVersion() { + return 0; + } + + @Override + @Nullable + public JsonElement getCustom(String key) { + return null; + } + + @Override + public List getMixinConfigurations() { + final JsonObject mixinsObject = jsonObject.getAsJsonObject("mixins"); + + if (mixinsObject == null) { + return Collections.emptyList(); + } + + final List mixins = new ArrayList<>(); + + for (String key : mixinsObject.keySet()) { + final JsonElement jsonElement = mixinsObject.get(key); + + if (jsonElement instanceof JsonArray jsonArray) { + for (JsonElement arrayElement : jsonArray) { + if (arrayElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) { + mixins.add(jsonPrimitive.getAsString()); + } else { + throw new FabricModJsonUtils.ParseException("Expected entries in mixin %s to be an array of strings", key); + } + } + } else if (jsonElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) { + mixins.add(jsonPrimitive.getAsString()); + } else { + throw new FabricModJsonUtils.ParseException("Expected mixin %s to be a string or an array of strings", key); + } + } + + return Collections.unmodifiableList(mixins); + } + + @Override + public List getClassTweakers(ModEnvironment modEnvironment) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV1.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV1.java new file mode 100644 index 000000000..78ea2e6bf --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV1.java @@ -0,0 +1,101 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.fmj; + +import static net.fabricmc.loom.util.fmj.FabricModJsonUtils.readString; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import org.jetbrains.annotations.Nullable; + +public final class FabricModJsonV1 extends FabricModJson { + FabricModJsonV1(JsonObject jsonObject, FabricModJsonSource source) { + super(jsonObject, source); + } + + @Override + public int getVersion() { + return 1; + } + + @Override + @Nullable + public JsonElement getCustom(String key) { + return getCustom(jsonObject, key); + } + + static JsonElement getCustom(JsonObject jsonObject, String key) { + if (!jsonObject.has("custom")) { + return null; + } + + final JsonObject custom = jsonObject.getAsJsonObject("custom"); + + if (!custom.has(key)) { + return null; + } + + return custom.get(key); + } + + @Override + public List getMixinConfigurations() { + final JsonArray mixinArray = jsonObject.getAsJsonArray("mixins"); + + if (mixinArray == null) { + return Collections.emptyList(); + } + + return StreamSupport.stream(mixinArray.spliterator(), false) + .map(FabricModJsonV1::readMixinElement) + .collect(Collectors.toList()); + } + + private static String readMixinElement(JsonElement jsonElement) { + if (jsonElement instanceof JsonPrimitive str) { + return str.getAsString(); + } else if (jsonElement instanceof JsonObject obj) { + return obj.get("config").getAsString(); + } else { + throw new FabricModJsonUtils.ParseException("Expected mixin element to be an object or string"); + } + } + + @Override + public List getClassTweakers(ModEnvironment modEnvironment) { + if (!jsonObject.has("accessWidener")) { + return Collections.emptyList(); + } + + return List.of(readString(jsonObject, "accessWidener")); + } +} diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV2.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV2.java new file mode 100644 index 000000000..029269b11 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV2.java @@ -0,0 +1,133 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.fmj; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +@ApiStatus.Experimental +public final class FabricModJsonV2 extends FabricModJson { + FabricModJsonV2(JsonObject jsonObject, FabricModJsonSource source) { + super(jsonObject, source); + } + + @Override + public int getVersion() { + return 2; + } + + @Override + @Nullable + public JsonElement getCustom(String key) { + return FabricModJsonV1.getCustom(jsonObject, key); + } + + @Override + public List getMixinConfigurations() { + if (!jsonObject.has("mixins")) { + return Collections.emptyList(); + } + + return getConditionalConfigs(jsonObject.get("mixins"), ModEnvironment.UNIVERSAL); + } + + @Override + public List getClassTweakers(ModEnvironment modEnvironment) { + if (!jsonObject.has("classTweakers")) { + return Collections.emptyList(); + } + + return getConditionalConfigs(jsonObject.get("classTweakers"), modEnvironment); + } + + private List getConditionalConfigs(JsonElement jsonElement, ModEnvironment modEnvironment) { + final List values = new ArrayList<>(); + + if (jsonElement instanceof JsonArray jsonArray) { + for (JsonElement arrayElement : jsonArray) { + final String value = readConditionalConfig(arrayElement, modEnvironment); + + if (value != null) { + values.add(value); + } + } + } else if (jsonElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) { + final String value = readConditionalConfig(jsonPrimitive, modEnvironment); + + if (value != null) { + values.add(value); + } + } else { + throw new FabricModJsonUtils.ParseException("Must be a string or array of strings"); + } + + return values; + } + + @Nullable + private String readConditionalConfig(JsonElement jsonElement, ModEnvironment modEnvironment) { + if (jsonElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) { + return jsonElement.getAsString(); + } else if (jsonElement instanceof JsonObject jsonObject) { + final String config = FabricModJsonUtils.readString(jsonObject, "config"); + + if (!validForEnvironment(jsonObject, modEnvironment)) { + return null; + } + + return config; + } else { + throw new FabricModJsonUtils.ParseException("Must be a string or an object"); + } + } + + private boolean validForEnvironment(JsonObject jsonObject, ModEnvironment modEnvironment) { + if (!jsonObject.has("environment")) { + // Default enabled for all envs. + return true; + } + + if (!(jsonObject.get("environment") instanceof JsonPrimitive jsonPrimitive) || !jsonPrimitive.isString()) { + throw new FabricModJsonUtils.ParseException("Environment must be a string"); + } + + final String environment = jsonPrimitive.getAsString(); + + return switch (environment) { + case "*" -> true; + case "client" -> modEnvironment.isClient(); + case "server" -> modEnvironment.isServer(); + default -> throw new FabricModJsonUtils.ParseException("Invalid environment type: " + environment); + }; + } +} diff --git a/src/main/java/net/fabricmc/loom/util/ModUtils.java b/src/main/java/net/fabricmc/loom/util/fmj/ModEnvironment.java similarity index 60% rename from src/main/java/net/fabricmc/loom/util/ModUtils.java rename to src/main/java/net/fabricmc/loom/util/fmj/ModEnvironment.java index 31298d953..b96687ad3 100644 --- a/src/main/java/net/fabricmc/loom/util/ModUtils.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/ModEnvironment.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2016-2022 FabricMC + * Copyright (c) 2022 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 @@ -22,34 +22,26 @@ * SOFTWARE. */ -package net.fabricmc.loom.util; +package net.fabricmc.loom.util.fmj; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Path; +public enum ModEnvironment { + UNIVERSAL(true, true), + CLIENT(true, false), + SERVER(false, true); -import com.google.gson.JsonObject; -import org.jetbrains.annotations.Nullable; + private final boolean client; + private final boolean server; -public final class ModUtils { - private ModUtils() { + ModEnvironment(boolean client, boolean server) { + this.client = client; + this.server = server; } - public static boolean isMod(File file) { - return isMod(file.toPath()); + public boolean isClient() { + return client; } - public static boolean isMod(Path input) { - return ZipUtils.contains(input, "fabric.mod.json"); - } - - @Nullable - public static JsonObject getFabricModJson(Path path) { - try { - return ZipUtils.unpackGsonNullable(path, "fabric.mod.json", JsonObject.class); - } catch (IOException e) { - throw new UncheckedIOException("Failed to extract fabric.mod.json from " + path, e); - } + public boolean isServer() { + return server; } } diff --git a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java index aec6bc633..ff108c38f 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java @@ -272,4 +272,16 @@ private static List getBinDirClasspath(File projectDir, SourceSetReference return Collections.singletonList(new File(binDir, reference.sourceSet().getName())); } + + @Nullable + public static File findFileInResource(SourceSet sourceSet, String path) { + try { + return sourceSet.getResources() + .matching(patternFilterable -> patternFilterable.include(path)) + .getSingleFile(); + } catch (IllegalStateException e) { + // File not found + return null; + } + } } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV0Test.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV0Test.groovy new file mode 100644 index 000000000..e8555d5fe --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV0Test.groovy @@ -0,0 +1,105 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.fmj + +import com.google.gson.Gson +import com.google.gson.JsonObject +import net.fabricmc.loom.util.Constants +import net.fabricmc.loom.util.fmj.FabricModJsonFactory +import net.fabricmc.loom.util.fmj.FabricModJsonSource +import net.fabricmc.loom.util.fmj.ModEnvironment +import org.intellij.lang.annotations.Language +import spock.lang.Specification + +class FabricModJsonV0Test extends Specification { + // I think this is the old v0 format ¯\_(ツ)_/¯ + @Language("json") + static String JSON = """ +{ + "id": "example-mod-id", + "name": "Example mod name for testing", + "version": "1.0.0", + "side": "universal", + "initializers": [ + ], + "mixins": { + "client": "mixins.client.json", + "common": [ + "mixins.common.json" + ] + } +} +""" + + static JsonObject JSON_OBJECT = new Gson().fromJson(JSON, JsonObject.class) + + def "version"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.version == 0 + } + + def "id"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.id == "example-mod-id" + } + + def "mixins"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.mixinConfigurations == ["mixins.client.json", "mixins.common.json"] + } + + // Not supported in this version + def "injected interfaces"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE) + then: + jsonObject == null + } + + // Not supported in this version + def "class tweaker"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.getClassTweakers(ModEnvironment.UNIVERSAL) == [] + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV1Test.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV1Test.groovy new file mode 100644 index 000000000..25fa12093 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV1Test.groovy @@ -0,0 +1,110 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.fmj + +import com.google.gson.Gson +import com.google.gson.JsonObject +import net.fabricmc.loom.util.Constants +import net.fabricmc.loom.util.fmj.FabricModJsonFactory +import net.fabricmc.loom.util.fmj.FabricModJsonSource +import net.fabricmc.loom.util.fmj.ModEnvironment +import org.intellij.lang.annotations.Language +import spock.lang.Specification + +class FabricModJsonV1Test extends Specification { + @Language("json") + static String JSON = """ +{ + "schemaVersion": 1, + "id": "example-mod-id", + "name": "Example mod name for testing", + "version": "1.0.0", + "environment": "client", + "license": "Apache-2.0", + "mixins": [ + { + "config": "test.client.mixins.json", + "environment": "client" + }, + "test.mixins.json" + ], + "accessWidener" : "modid.accesswidener", + "custom": { + "loom:injected_interfaces": { + "net/minecraft/class_123": ["net/test/TestClass"] + } + } +} +""" + + static JsonObject JSON_OBJECT = new Gson().fromJson(JSON, JsonObject.class) + + def "version"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.version == 1 + } + + def "id"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.id == "example-mod-id" + } + + def "mixins"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.mixinConfigurations == ["test.client.mixins.json", "test.mixins.json"] + } + + def "injected interfaces"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE) + then: + jsonObject instanceof JsonObject + jsonObject.has("net/minecraft/class_123") + } + + def "access widener"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.getClassTweakers(ModEnvironment.SERVER) == ["modid.accesswidener"] + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV2Test.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV2Test.groovy new file mode 100644 index 000000000..63009e859 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/fmj/FabricModJsonV2Test.groovy @@ -0,0 +1,142 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.fmj + +import com.google.gson.Gson +import com.google.gson.JsonObject +import net.fabricmc.loom.util.Constants +import net.fabricmc.loom.util.fmj.FabricModJsonFactory +import net.fabricmc.loom.util.fmj.FabricModJsonSource +import net.fabricmc.loom.util.fmj.ModEnvironment +import org.intellij.lang.annotations.Language +import spock.lang.Specification + +class FabricModJsonV2Test extends Specification { + @Language("json") + static String JSON = """ +{ + "schemaVersion": 2, + "id": "example-mod-id", + "name": "Example mod name for testing", + "version": "1.0.0", + "environment": "client", + "license": "Apache-2.0", + "mixins": [ + { + "config": "test.client.mixins.json", + "environment": "client" + }, + { + "config": "test.server.mixins.json", + "environment": "server" + }, + "test.mixins.json" + ], + "classTweakers": [ + { + "config": "client.ct", + "environment": "client" + }, + { + "config": "server.ct", + "environment": "server" + }, + "universal.ct" + ], + "custom": { + "loom:injected_interfaces": { + "net/minecraft/class_123": ["net/test/TestClass"] + } + } +} +""" + + static JsonObject JSON_OBJECT = new Gson().fromJson(JSON, JsonObject.class) + + def "version"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.version == 2 + } + + def "id"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.id == "example-mod-id" + } + + def "mixins"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.mixinConfigurations == ["test.client.mixins.json", "test.server.mixins.json", "test.mixins.json"] + } + + def "injected interfaces"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + def jsonObject = fmj.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE) + then: + jsonObject instanceof JsonObject + jsonObject.has("net/minecraft/class_123") + } + + def "universal class tweakers"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.getClassTweakers(ModEnvironment.UNIVERSAL) == ["client.ct", "server.ct", "universal.ct"] + } + + def "client class tweakers"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.getClassTweakers(ModEnvironment.CLIENT) == ["client.ct", "universal.ct"] + } + + def "server class tweakers"() { + given: + def mockSource = Mock(FabricModJsonSource) + when: + def fmj = FabricModJsonFactory.create(JSON_OBJECT, mockSource) + then: + fmj.getClassTweakers(ModEnvironment.SERVER) == ["server.ct", "universal.ct"] + } +} From c9356349de8ebc988b8cffcf4da661c927b9971e Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sat, 1 Oct 2022 09:19:20 +0100 Subject: [PATCH 02/13] Fix crash --- .../ifaceinject/InterfaceInjectionProcessor.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java index 3ef529abf..85c0f83dd 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java @@ -205,6 +205,10 @@ private List getSourceInjectedInterface(SourceSet sourceSet) throw new UncheckedIOException(e); } + if (fabricModJson == null) { + return Collections.emptyList(); + } + return InjectedInterface.fromFabricModJson(fabricModJson); } From ab4234330ee208d97a08991ed77f607cd1365828 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 3 Oct 2022 22:00:07 +0100 Subject: [PATCH 03/13] First look at MinecraftJarProcessor API --- .../fabricmc/loom/LoomGradleExtension.java | 9 +- .../loom/api/LoomGradleExtensionAPI.java | 9 +- .../api/processor/MinecraftJarProcessor.java | 53 +++++++ .../loom/api/processor/ProcessorContext.java | 37 +++++ .../loom/api/processor/SpecContext.java | 35 +++++ .../configuration/CompileConfiguration.java | 18 +-- .../SingleJarDecompileConfiguration.java | 2 +- .../processors/JarProcessor.java | 1 + .../processors/JarProcessorManager.java | 129 ---------------- .../processors/LegacyJarProcessorWrapper.java | 65 ++++++++ .../MinecraftJarProcessorManager.java | 145 ++++++++++++++++++ .../processors/ProcessorContextImpl.java | 58 +++++++ .../processors/SpecContextImpl.java | 44 ++++++ .../providers/minecraft/MinecraftJar.java | 80 ++++++++++ .../minecraft/MinecraftJarConfiguration.java | 10 +- .../providers/minecraft/SingleJarEnvType.java | 43 ++++++ .../minecraft/SingleJarMinecraftProvider.java | 14 +- .../mapped/IntermediaryMinecraftProvider.java | 11 +- .../mapped/MappedMinecraftProvider.java | 23 ++- .../mapped/NamedMinecraftProvider.java | 11 +- .../ProcessedNamedMinecraftProvider.java | 91 ++++++----- .../extension/LoomGradleExtensionApiImpl.java | 19 +++ .../extension/LoomGradleExtensionImpl.java | 12 -- .../fabricmc/loom/util/DeprecationHelper.java | 4 +- 24 files changed, 688 insertions(+), 235 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java create mode 100644 src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java create mode 100644 src/main/java/net/fabricmc/loom/api/processor/SpecContext.java delete mode 100644 src/main/java/net/fabricmc/loom/configuration/processors/JarProcessorManager.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarEnvType.java diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 72546cdb6..33a1282f1 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -39,7 +39,6 @@ import net.fabricmc.loom.configuration.InstallerData; import net.fabricmc.loom.configuration.LoomDependencyManager; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; -import net.fabricmc.loom.configuration.processors.JarProcessorManager; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; @@ -69,10 +68,6 @@ static LoomGradleExtension get(Project project) { LoomDependencyManager getDependencyManager(); - void setJarProcessorManager(JarProcessorManager jarProcessorManager); - - JarProcessorManager getJarProcessorManager(); - MinecraftProvider getMinecraftProvider(); void setMinecraftProvider(MinecraftProvider minecraftProvider); @@ -91,8 +86,8 @@ static LoomGradleExtension get(Project project) { default List getMinecraftJars(MappingsNamespace mappingsNamespace) { return switch (mappingsNamespace) { - case NAMED -> getNamedMinecraftProvider().getMinecraftJars(); - case INTERMEDIARY -> getIntermediaryMinecraftProvider().getMinecraftJars(); + case NAMED -> getNamedMinecraftProvider().getMinecraftJarPaths(); + case INTERMEDIARY -> getIntermediaryMinecraftProvider().getMinecraftJarPaths(); case OFFICIAL -> getMinecraftProvider().getMinecraftJars(); }; } diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java index 693f1d55b..006a0c601 100644 --- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java @@ -42,6 +42,7 @@ import net.fabricmc.loom.api.decompilers.DecompilerOptions; import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; +import net.fabricmc.loom.api.processor.MinecraftJarProcessor; import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.processors.JarProcessor; import net.fabricmc.loom.configuration.providers.mappings.NoOpIntermediateMappingsProvider; @@ -62,11 +63,13 @@ public interface LoomGradleExtensionAPI { void decompilers(Action> action); + @Deprecated(forRemoval = true) ListProperty getGameJarProcessors(); - default void addJarProcessor(JarProcessor processor) { - getGameJarProcessors().add(processor); - } + @Deprecated(forRemoval = true) + void addJarProcessor(JarProcessor processor); + + ListProperty> getMinecraftJarProcessors(); ConfigurableFileCollection getLog4jConfigs(); diff --git a/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java b/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java new file mode 100644 index 000000000..0a43306f6 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java @@ -0,0 +1,53 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.api.processor; + +import java.io.IOException; +import java.nio.file.Path; + +import org.gradle.api.Named; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +public interface MinecraftJarProcessor extends Named { + @Nullable + S buildSpec(SpecContext context); + + void processJar(Path jar, S spec, ProcessorContext context) throws IOException; + + @Nullable + default MappingsProcessor processMappings() { + return null; + } + + interface Spec { + String cacheValue(); + } + + interface MappingsProcessor { + boolean transform(MemoryMappingTree mappings, S spec, ProcessorContext context); + } +} diff --git a/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java b/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java new file mode 100644 index 000000000..9444e58bc --- /dev/null +++ b/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java @@ -0,0 +1,37 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.api.processor; + +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; + +public interface ProcessorContext { + MinecraftJarConfiguration getJarConfiguration(); + + boolean isMerged(); + + boolean includesClient(); + + boolean includesServer(); +} diff --git a/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java b/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java new file mode 100644 index 000000000..b803114c2 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java @@ -0,0 +1,35 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.api.processor; + +import java.util.List; + +import net.fabricmc.loom.util.fmj.FabricModJson; + +public interface SpecContext { + List getModDependencies(); + + List getMods(); +} diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index e54194cd7..2bc79be04 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -49,8 +49,9 @@ import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerJarProcessor; import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; -import net.fabricmc.loom.configuration.processors.JarProcessorManager; +import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.processors.ModJavadocProcessor; +import net.fabricmc.loom.configuration.processors.SpecContextImpl; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; @@ -196,11 +197,12 @@ private static synchronized void setupMinecraft(Project project) throws Exceptio final IntermediaryMinecraftProvider intermediaryMinecraftProvider = jarConfiguration.getIntermediaryMinecraftProviderBiFunction().apply(project, minecraftProvider); NamedMinecraftProvider namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(project, minecraftProvider); - final JarProcessorManager jarProcessorManager = createJarProcessorManager(project); + registerGameProcessors(project); + MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(extension.getMinecraftJarProcessors().get(), new SpecContextImpl()); - if (jarProcessorManager.active()) { + if (minecraftJarProcessorManager != null) { // Wrap the named MC provider for one that will provide the processed jars - namedMinecraftProvider = jarConfiguration.getProcessedNamedMinecraftProviderBiFunction().apply(namedMinecraftProvider, jarProcessorManager); + namedMinecraftProvider = jarConfiguration.getProcessedNamedMinecraftProviderBiFunction().apply(namedMinecraftProvider, minecraftJarProcessorManager); } extension.setIntermediaryMinecraftProvider(intermediaryMinecraftProvider); @@ -210,7 +212,7 @@ private static synchronized void setupMinecraft(Project project) throws Exceptio namedMinecraftProvider.provide(true); } - private static JarProcessorManager createJarProcessorManager(Project project) { + private static void registerGameProcessors(Project project) { final LoomGradleExtension extension = LoomGradleExtension.get(project); if (extension.getAccessWidenerPath().isPresent()) { @@ -241,12 +243,6 @@ private static JarProcessorManager createJarProcessorManager(Project project) { extension.getGameJarProcessors().add(javadocProcessor); } } - - JarProcessorManager processorManager = new JarProcessorManager(extension.getGameJarProcessors().get()); - extension.setJarProcessorManager(processorManager); - processorManager.setupProcessors(); - - return processorManager; } private static void setupMixinAp(Project project, MixinExtension mixin) { diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java index 782da7096..b5f2dc323 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java @@ -42,7 +42,7 @@ public SingleJarDecompileConfiguration(Project project, MappedMinecraftProvider @Override public final void afterEvaluation() { - List minecraftJars = minecraftProvider.getMinecraftJars(); + List minecraftJars = minecraftProvider.getMinecraftJarPaths(); assert minecraftJars.size() == 1; final File namedJar = minecraftJars.get(0).toFile(); diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java index b1cf4299e..34833a929 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java @@ -26,6 +26,7 @@ import java.io.File; +@Deprecated(forRemoval = true) public interface JarProcessor { /** * Returns a unique ID for this jar processor, containing all configuration details. diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessorManager.java b/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessorManager.java deleted file mode 100644 index 1d602c309..000000000 --- a/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessorManager.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2016-2020 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.processors; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.util.stream.Collectors; - -import com.google.common.base.Preconditions; -import com.google.common.hash.Hashing; -import com.google.common.io.CharSource; - -import net.fabricmc.loom.util.ZipUtils; - -public class JarProcessorManager { - private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF"; - private static final String JAR_PROCESSOR_HASH_ATTRIBUTE = "Loom-Jar-Processor-Hash"; - private final List jarProcessors; - - public JarProcessorManager(List jarProcessors) { - this.jarProcessors = jarProcessors; - } - - public void setupProcessors() { - jarProcessors.forEach(JarProcessor::setup); - } - - public boolean active() { - return !jarProcessors.isEmpty(); - } - - public boolean isInvalid(File file) { - if (!file.exists()) { - return true; - } - - String jarProcessorHash = getJarProcessorHash(); - - try (JarFile jar = new JarFile(file)) { - Manifest manifest = jar.getManifest(); - - if (manifest == null) { - return false; - } - - Attributes attributes = manifest.getMainAttributes(); - - if (!jarProcessorHash.equals(attributes.getValue(JAR_PROCESSOR_HASH_ATTRIBUTE))) { - return true; - } - } catch (IOException e) { - throw new UncheckedIOException("Could not check jar manifest of " + file, e); - } - - return false; - } - - private String getJarProcessorHash() { - String jarProcessorIds = jarProcessors.stream() - .map(JarProcessor::getId) - .sorted() - .collect(Collectors.joining(";")); - - try { - return CharSource.wrap(jarProcessorIds) - .asByteSource(StandardCharsets.UTF_8) - .hash(Hashing.sha256()) - .toString(); - } catch (IOException e) { - throw new UncheckedIOException("Could not hash jar processor IDs", e); - } - } - - public void process(File file) { - for (JarProcessor jarProcessor : jarProcessors) { - jarProcessor.process(file); - } - - try { - int count = ZipUtils.transform(file.toPath(), Map.of(MANIFEST_PATH, bytes -> { - Manifest manifest = new Manifest(new ByteArrayInputStream(bytes)); - manifest.getMainAttributes().putValue(JAR_PROCESSOR_HASH_ATTRIBUTE, getJarProcessorHash()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - manifest.write(out); - return out.toByteArray(); - })); - - Preconditions.checkState(count > 0, "Did not add data to jar manifest in " + file); - } catch (IOException e) { - throw new UncheckedIOException("Could not add data to jar manifest in " + file, e); - } - } - - public T getByType(Class tClass) { - //noinspection unchecked - return (T) jarProcessors.stream().filter(jarProcessor -> jarProcessor.getClass().equals(tClass)).findFirst().orElse(null); - } -} diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java b/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java new file mode 100644 index 000000000..98ab20333 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java @@ -0,0 +1,65 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.processors; + +import java.io.IOException; +import java.nio.file.Path; + +import javax.inject.Inject; + +import org.gradle.api.Project; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.loom.api.processor.MinecraftJarProcessor; +import net.fabricmc.loom.api.processor.ProcessorContext; +import net.fabricmc.loom.api.processor.SpecContext; + +/** + * Wrapper around the deprecated API. + */ +public abstract class LegacyJarProcessorWrapper implements MinecraftJarProcessor { + private final JarProcessor delegate; + + @Inject + public LegacyJarProcessorWrapper(JarProcessor delegate) { + this.delegate = delegate; + } + + public abstract Project getProject(); + + @Override + public @Nullable LegacyJarProcessorWrapper.Spec buildSpec(SpecContext context) { + delegate.setup(); + return new Spec(delegate.getId()); + } + + @Override + public void processJar(Path jar, Spec spec, ProcessorContext context) throws IOException { + delegate.process(jar.toFile()); + } + + public record Spec(String cacheValue) implements MinecraftJarProcessor.Spec { + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java new file mode 100644 index 000000000..aed0d22cb --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java @@ -0,0 +1,145 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.processors; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.loom.api.processor.MinecraftJarProcessor; +import net.fabricmc.loom.api.processor.ProcessorContext; +import net.fabricmc.loom.api.processor.SpecContext; +import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +public final class MinecraftJarProcessorManager { + private static final String CACHE_VALUE_FILE_PATH = "META-INF/Loom-Jar-Processor-Cache"; + + private final List> jarProcessors; + + private MinecraftJarProcessorManager(List> jarProcessors) { + this.jarProcessors = Collections.unmodifiableList(jarProcessors); + } + + @Nullable + public static MinecraftJarProcessorManager create(List> processors, SpecContext context) { + List> entries = new ArrayList<>(); + + for (MinecraftJarProcessor processor : processors) { + MinecraftJarProcessor.Spec spec = processor.buildSpec(context); + + if (spec != null) { + entries.add(new ProcessorEntry<>(processor, spec)); + } + } + + if (entries.isEmpty()) { + return null; + } + + return new MinecraftJarProcessorManager(entries); + } + + private String getCacheValue() { + return jarProcessors.stream() + .sorted(Comparator.comparing(ProcessorEntry::name)) + .map(ProcessorEntry::cacheValue) + .collect(Collectors.joining("::")); + } + + public boolean requiresProcessingJar(Path jar) { + Objects.requireNonNull(jar); + + if (Files.notExists(jar)) { + return true; + } + + byte[] existingCache; + + try { + existingCache = ZipUtils.unpackNullable(jar, CACHE_VALUE_FILE_PATH); + } catch (IOException e) { + throw new UncheckedIOException("Failed to unpack jar: " + jar, e); + } + + if (existingCache == null) { + return true; + } + + final String existingCacheValue = new String(existingCache, StandardCharsets.UTF_8); + return !existingCacheValue.equals(getCacheValue()); + } + + public void processJar(Path jar, ProcessorContext context) throws IOException { + for (ProcessorEntry entry : jarProcessors) { + try { + entry.processJar(jar, context); + } catch (IOException e) { + throw new IOException("Failed to process jar when running jar processor: %s".formatted(entry.name()), e); + } + } + + ZipUtils.add(jar, CACHE_VALUE_FILE_PATH, getCacheValue()); + } + + public void processMappings(MemoryMappingTree mappings, ProcessorContext context) { + for (ProcessorEntry entry : jarProcessors) { + entry.processMappings(mappings, context); + } + } + + record ProcessorEntry(S spec, MinecraftJarProcessor processor, @Nullable MinecraftJarProcessor.MappingsProcessor mappingsProcessor) { + @SuppressWarnings("unchecked") + ProcessorEntry(MinecraftJarProcessor processor, MinecraftJarProcessor.Spec spec) { + this((S) Objects.requireNonNull(spec), (MinecraftJarProcessor) processor, (MinecraftJarProcessor.MappingsProcessor) processor.processMappings()); + } + + private void processJar(Path jar, ProcessorContext context) throws IOException { + processor().processJar(jar, spec, context); + } + + private void processMappings(MemoryMappingTree mappings, ProcessorContext context) { + mappingsProcessor().transform(mappings, spec, context); + } + + private String name() { + return processor.getName(); + } + + private String cacheValue() { + return processor.getName() + ":" + spec.cacheValue(); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java new file mode 100644 index 000000000..382a54c93 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java @@ -0,0 +1,58 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.processors; + +import org.gradle.api.Project; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.api.processor.ProcessorContext; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJar; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; + +public record ProcessorContextImpl(MinecraftJarConfiguration jarConfiguration, MinecraftJar minecraftJar) implements ProcessorContext { + public static ProcessorContext create(Project project, MinecraftJar minecraftJar) { + return new ProcessorContextImpl(LoomGradleExtension.get(project).getMinecraftJarConfiguration().get(), minecraftJar); + } + + @Override + public MinecraftJarConfiguration getJarConfiguration() { + return jarConfiguration; + } + + @Override + public boolean isMerged() { + return minecraftJar.isMerged(); + } + + @Override + public boolean includesClient() { + return minecraftJar.includesClient(); + } + + @Override + public boolean includesServer() { + return minecraftJar.includesServer(); + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java new file mode 100644 index 000000000..f487a8143 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java @@ -0,0 +1,44 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.processors; + +import java.util.List; + +import net.fabricmc.loom.api.processor.SpecContext; +import net.fabricmc.loom.util.fmj.FabricModJson; + +public class SpecContextImpl implements SpecContext { + @Override + public List getModDependencies() { + // TODO + return null; + } + + @Override + public List getMods() { + // TODO + return null; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java new file mode 100644 index 000000000..4e18410fd --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java @@ -0,0 +1,80 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.minecraft; + +import java.nio.file.Path; +import java.util.Objects; + +public abstract sealed class MinecraftJar permits MinecraftJar.Merged, MinecraftJar.Common, MinecraftJar.ServerOnly, MinecraftJar.ClientOnly { + private final Path path; + private final boolean merged, client, server; + + protected MinecraftJar(Path path, boolean merged, boolean client, boolean server) { + this.path = Objects.requireNonNull(path); + this.merged = merged; + this.client = client; + this.server = server; + } + + public Path getPath() { + return path; + } + + public boolean isMerged() { + return merged; + } + + public boolean includesClient() { + return client; + } + + public boolean includesServer() { + return server; + } + + public static final class Merged extends MinecraftJar { + public Merged(Path path) { + super(path, true, true, true); + } + } + + public static final class Common extends MinecraftJar { + public Common(Path path) { + super(path, false, false, true); + } + } + + public static final class ServerOnly extends MinecraftJar { + public ServerOnly(Path path) { + super(path, false, false, true); + } + } + + public static final class ClientOnly extends MinecraftJar { + public ClientOnly(Path path) { + super(path, false, true, false); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java index 48a4ca9cf..c48102b20 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java @@ -33,7 +33,7 @@ import net.fabricmc.loom.configuration.decompile.DecompileConfiguration; import net.fabricmc.loom.configuration.decompile.SingleJarDecompileConfiguration; import net.fabricmc.loom.configuration.decompile.SplitDecompileConfiguration; -import net.fabricmc.loom.configuration.processors.JarProcessorManager; +import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; @@ -76,7 +76,7 @@ public enum MinecraftJarConfiguration { private final Function minecraftProviderFunction; private final BiFunction> intermediaryMinecraftProviderBiFunction; private final BiFunction> namedMinecraftProviderBiFunction; - private final BiFunction, JarProcessorManager, ProcessedNamedMinecraftProvider> processedNamedMinecraftProviderBiFunction; + private final BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider> processedNamedMinecraftProviderBiFunction; private final BiFunction> decompileConfigurationBiFunction; private final List supportedEnvironments; @@ -85,14 +85,14 @@ , Q extends Map Function minecraftProviderFunction, BiFunction> intermediaryMinecraftProviderBiFunction, BiFunction namedMinecraftProviderBiFunction, - BiFunction> processedNamedMinecraftProviderBiFunction, + BiFunction> processedNamedMinecraftProviderBiFunction, BiFunction> decompileConfigurationBiFunction, List supportedEnvironments ) { this.minecraftProviderFunction = (Function) minecraftProviderFunction; this.intermediaryMinecraftProviderBiFunction = (BiFunction>) (Object) intermediaryMinecraftProviderBiFunction; this.namedMinecraftProviderBiFunction = (BiFunction>) namedMinecraftProviderBiFunction; - this.processedNamedMinecraftProviderBiFunction = (BiFunction, JarProcessorManager, ProcessedNamedMinecraftProvider>) (Object) processedNamedMinecraftProviderBiFunction; + this.processedNamedMinecraftProviderBiFunction = (BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider>) (Object) processedNamedMinecraftProviderBiFunction; this.decompileConfigurationBiFunction = (BiFunction>) decompileConfigurationBiFunction; this.supportedEnvironments = supportedEnvironments; } @@ -109,7 +109,7 @@ public BiFunction> getName return namedMinecraftProviderBiFunction; } - public BiFunction, JarProcessorManager, ProcessedNamedMinecraftProvider> getProcessedNamedMinecraftProviderBiFunction() { + public BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider> getProcessedNamedMinecraftProviderBiFunction() { return processedNamedMinecraftProviderBiFunction; } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarEnvType.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarEnvType.java new file mode 100644 index 000000000..7063c166b --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarEnvType.java @@ -0,0 +1,43 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.minecraft; + +import java.nio.file.Path; +import java.util.function.Function; + +public enum SingleJarEnvType { + CLIENT(MinecraftJar.ClientOnly::new), + SERVER(MinecraftJar.ServerOnly::new); + + private final Function jarFunction; + + SingleJarEnvType(Function jarFunction) { + this.jarFunction = jarFunction; + } + + public Function getJar() { + return jarFunction; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java index 9baafd93b..83743035b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java @@ -57,7 +57,7 @@ public static SingleJarMinecraftProvider client(Project project) { protected void initFiles() { super.initFiles(); - minecraftEnvOnlyJar = path("minecraft-%s-only.jar".formatted(environment.name())); + minecraftEnvOnlyJar = path("minecraft-%s-only.jar".formatted(environment.type())); } @Override @@ -92,7 +92,7 @@ public void provide() throws Exception { } } catch (Exception e) { Files.deleteIfExists(minecraftEnvOnlyJar); - throw new RuntimeException("Failed to process %s only jar".formatted(environment.name()), e); + throw new RuntimeException("Failed to process %s only jar".formatted(environment.type()), e); } finally { if (remapper != null) { remapper.finish(); @@ -115,15 +115,15 @@ public Path getMinecraftEnvOnlyJar() { } private interface Environment { - String name(); + SingleJarEnvType type(); Path getInputJar(SingleJarMinecraftProvider provider) throws Exception; } private static final class Server implements Environment { @Override - public String name() { - return "server"; + public SingleJarEnvType type() { + return SingleJarEnvType.SERVER; } @Override @@ -141,8 +141,8 @@ public Path getInputJar(SingleJarMinecraftProvider provider) throws Exception { private static final class Client implements Environment { @Override - public String name() { - return "client"; + public SingleJarEnvType type() { + return SingleJarEnvType.CLIENT; } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java index b6a56ee4a..5dd9cbdb7 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java @@ -32,6 +32,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; +import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType; import net.fabricmc.loom.configuration.providers.minecraft.SingleJarMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; import net.fabricmc.loom.util.SidedClassVisitor; @@ -87,19 +88,19 @@ protected void configureRemapper(RemappedJars remappedJars, TinyRemapper.Builder } public static final class SingleJarImpl extends IntermediaryMinecraftProvider implements SingleJar { - private final String env; + private final SingleJarEnvType env; - private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, String env) { + private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { super(project, minecraftProvider); this.env = env; } public static SingleJarImpl server(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, "server"); + return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.SERVER); } public static SingleJarImpl client(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, "client"); + return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.CLIENT); } @Override @@ -110,7 +111,7 @@ public List getRemappedJars() { } @Override - public String env() { + public SingleJarEnvType env() { return env; } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java index 6ec0f6c03..73b0caa93 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java @@ -27,8 +27,15 @@ import java.nio.file.Path; import java.util.List; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJar; +import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType; + public interface MappedMinecraftProvider { - List getMinecraftJars(); + default List getMinecraftJarPaths() { + return getMinecraftJars().stream().map(MinecraftJar::getPath).toList(); + } + + List getMinecraftJars(); interface ProviderImpl extends MappedMinecraftProvider { Path getJar(String name); @@ -42,8 +49,8 @@ default Path getMergedJar() { } @Override - default List getMinecraftJars() { - return List.of(getMergedJar()); + default List getMinecraftJars() { + return List.of(new MinecraftJar.Merged(getMergedJar())); } } @@ -60,13 +67,13 @@ default Path getClientOnlyJar() { } @Override - default List getMinecraftJars() { - return List.of(getCommonJar(), getClientOnlyJar()); + default List getMinecraftJars() { + return List.of(new MinecraftJar.Common(getCommonJar()), new MinecraftJar.ClientOnly(getClientOnlyJar())); } } interface SingleJar extends ProviderImpl { - String env(); + SingleJarEnvType env(); default String envName() { return "%sOnly".formatted(env()); @@ -77,8 +84,8 @@ default Path getEnvOnlyJar() { } @Override - default List getMinecraftJars() { - return List.of(getEnvOnlyJar()); + default List getMinecraftJars() { + return List.of(env().getJar().apply(getEnvOnlyJar())); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java index 9c9cdff77..a9643debf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java @@ -32,6 +32,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; +import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType; import net.fabricmc.loom.configuration.providers.minecraft.SingleJarMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; import net.fabricmc.loom.util.SidedClassVisitor; @@ -97,19 +98,19 @@ public List getDependencyTargets() { } public static final class SingleJarImpl extends NamedMinecraftProvider implements SingleJar { - private final String env; + private final SingleJarEnvType env; - private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, String env) { + private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { super(project, minecraftProvider); this.env = env; } public static SingleJarImpl server(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, "server"); + return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.SERVER); } public static SingleJarImpl client(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, "client"); + return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.CLIENT); } @Override @@ -125,7 +126,7 @@ public List getDependencyTargets() { } @Override - public String env() { + public SingleJarEnvType env() { return env; } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java index 579081ff9..4e479b428 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java @@ -30,25 +30,29 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.List; +import java.util.Objects; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.processors.JarProcessorManager; +import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; +import net.fabricmc.loom.configuration.processors.ProcessorContextImpl; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJar; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; +import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType; import net.fabricmc.loom.configuration.providers.minecraft.SingleJarMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; public abstract class ProcessedNamedMinecraftProvider> extends NamedMinecraftProvider { private final P parentMinecraftProvider; - private final JarProcessorManager jarProcessorManager; + private final MinecraftJarProcessorManager jarProcessorManager; private final String projectMappedName; private final Path projectMappedDir; - public ProcessedNamedMinecraftProvider(P parentMinecraftProvide, JarProcessorManager jarProcessorManager) { + public ProcessedNamedMinecraftProvider(P parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { super(parentMinecraftProvide.getProject(), parentMinecraftProvide.getMinecraftProvider()); this.parentMinecraftProvider = parentMinecraftProvide; - this.jarProcessorManager = jarProcessorManager; + this.jarProcessorManager = Objects.requireNonNull(jarProcessorManager); this.projectMappedName = "minecraft-project-%s-".formatted(getProject().getPath().replace(':', '@')); @@ -62,42 +66,49 @@ public ProcessedNamedMinecraftProvider(P parentMinecraftProvide, JarProcessorMan public void provide(boolean applyDependencies) throws Exception { parentMinecraftProvider.provide(false); - final List inputJars = parentMinecraftProvider.getMinecraftJars(); - boolean requiresProcessing = extension.refreshDeps() || inputJars.stream() - .map(this::getProcessedPath) - .map(Path::toFile) - .anyMatch(jarProcessorManager::isInvalid); + boolean requiresProcessing = parentMinecraftProvider.getMinecraftJarPaths().stream() + .anyMatch(jarProcessorManager::requiresProcessingJar); if (requiresProcessing) { - try { - Files.createDirectories(projectMappedDir); - } catch (IOException e) { - throw new UncheckedIOException("Failed to create project mapped dir", e); - } + processJars(); + } - for (Path inputJar : inputJars) { - final Path outputJar = getProcessedPath(inputJar); - deleteSimilarJars(outputJar); + if (applyDependencies) { + applyDependencies(); + } + } - Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING); - jarProcessorManager.process(outputJar.toFile()); - } + private void processJars() throws IOException { + try { + Files.createDirectories(projectMappedDir); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create project mapped dir", e); } - if (applyDependencies) { - final List dependencyTargets = parentMinecraftProvider.getDependencyTargets(); + for (MinecraftJar minecraftJar : parentMinecraftProvider.getMinecraftJars()) { + Path inputJar = minecraftJar.getPath(); + final Path outputJar = getProcessedPath(inputJar); + deleteSimilarJars(outputJar); - if (dependencyTargets.isEmpty()) { - return; - } + Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING); - MinecraftSourceSets.get(getProject()).applyDependencies( - (configuration, name) -> getProject().getDependencies().add(configuration, getDependencyNotation(name)), - dependencyTargets - ); + jarProcessorManager.processJar(outputJar, ProcessorContextImpl.create(getProject(), minecraftJar)); } } + private void applyDependencies() { + final List dependencyTargets = parentMinecraftProvider.getDependencyTargets(); + + if (dependencyTargets.isEmpty()) { + return; + } + + MinecraftSourceSets.get(getProject()).applyDependencies( + (configuration, name) -> getProject().getDependencies().add(configuration, getDependencyNotation(name)), + dependencyTargets + ); + } + private void deleteSimilarJars(Path jar) throws IOException { Files.deleteIfExists(jar); @@ -124,8 +135,8 @@ public List getRemappedJars() { } @Override - public List getMinecraftJars() { - return getParentMinecraftProvider().getMinecraftJars().stream() + public List getMinecraftJarPaths() { + return getParentMinecraftProvider().getMinecraftJarPaths().stream() .map(this::getProcessedPath) .toList(); } @@ -139,7 +150,7 @@ public Path getProcessedPath(Path input) { } public static final class MergedImpl extends ProcessedNamedMinecraftProvider implements Merged { - public MergedImpl(NamedMinecraftProvider.MergedImpl parentMinecraftProvide, JarProcessorManager jarProcessorManager) { + public MergedImpl(NamedMinecraftProvider.MergedImpl parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { super(parentMinecraftProvide, jarProcessorManager); } @@ -150,7 +161,7 @@ public Path getMergedJar() { } public static final class SplitImpl extends ProcessedNamedMinecraftProvider implements Split { - public SplitImpl(NamedMinecraftProvider.SplitImpl parentMinecraftProvide, JarProcessorManager jarProcessorManager) { + public SplitImpl(NamedMinecraftProvider.SplitImpl parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { super(parentMinecraftProvide, jarProcessorManager); } @@ -166,19 +177,19 @@ public Path getClientOnlyJar() { } public static final class SingleJarImpl extends ProcessedNamedMinecraftProvider implements SingleJar { - private final String env; + private final SingleJarEnvType env; - private SingleJarImpl(NamedMinecraftProvider.SingleJarImpl parentMinecraftProvide, JarProcessorManager jarProcessorManager, String env) { + private SingleJarImpl(NamedMinecraftProvider.SingleJarImpl parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager, SingleJarEnvType env) { super(parentMinecraftProvide, jarProcessorManager); this.env = env; } - public static ProcessedNamedMinecraftProvider.SingleJarImpl server(NamedMinecraftProvider.SingleJarImpl parentMinecraftProvide, JarProcessorManager jarProcessorManager) { - return new ProcessedNamedMinecraftProvider.SingleJarImpl(parentMinecraftProvide, jarProcessorManager, "server"); + public static ProcessedNamedMinecraftProvider.SingleJarImpl server(NamedMinecraftProvider.SingleJarImpl parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { + return new ProcessedNamedMinecraftProvider.SingleJarImpl(parentMinecraftProvide, jarProcessorManager, SingleJarEnvType.SERVER); } - public static ProcessedNamedMinecraftProvider.SingleJarImpl client(NamedMinecraftProvider.SingleJarImpl parentMinecraftProvide, JarProcessorManager jarProcessorManager) { - return new ProcessedNamedMinecraftProvider.SingleJarImpl(parentMinecraftProvide, jarProcessorManager, "client"); + public static ProcessedNamedMinecraftProvider.SingleJarImpl client(NamedMinecraftProvider.SingleJarImpl parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { + return new ProcessedNamedMinecraftProvider.SingleJarImpl(parentMinecraftProvide, jarProcessorManager, SingleJarEnvType.CLIENT); } @Override @@ -187,7 +198,7 @@ public Path getEnvOnlyJar() { } @Override - public String env() { + public SingleJarEnvType env() { return env; } } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index af111e9fd..788569806 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -47,9 +47,11 @@ import net.fabricmc.loom.api.decompilers.DecompilerOptions; import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; +import net.fabricmc.loom.api.processor.MinecraftJarProcessor; import net.fabricmc.loom.configuration.RemapConfigurations; import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.processors.JarProcessor; +import net.fabricmc.loom.configuration.processors.LegacyJarProcessorWrapper; import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl; @@ -65,6 +67,7 @@ */ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionAPI { protected final DeprecationHelper deprecationHelper; + @Deprecated(forRemoval = true) protected final ListProperty jarProcessors; protected final ConfigurableFileCollection log4jConfigs; protected final RegularFileProperty accessWidener; @@ -85,6 +88,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA private final NamedDomainObjectContainer decompilers; private final NamedDomainObjectContainer mods; private final NamedDomainObjectList remapConfigurations; + private final ListProperty> minecraftJarProcessors; // 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); @@ -116,6 +120,9 @@ protected LoomGradleExtensionApiImpl(Project project, LoomFiles directories) { this.decompilers = project.getObjects().domainObjectContainer(DecompilerOptions.class); this.mods = project.getObjects().domainObjectContainer(ModSettings.class); this.remapConfigurations = project.getObjects().namedDomainObjectList(RemapConfigurationSettings.class); + //noinspection unchecked + this.minecraftJarProcessors = (ListProperty>) (Object) project.getObjects().listProperty(MinecraftJarProcessor.class); + this.minecraftJarProcessors.finalizeValueOnRead(); this.minecraftJarConfiguration = project.getObjects().property(MinecraftJarConfiguration.class).convention(MinecraftJarConfiguration.MERGED); this.minecraftJarConfiguration.finalizeValueOnRead(); @@ -166,9 +173,21 @@ public void decompilers(Action> ac @Override public ListProperty getGameJarProcessors() { + getDeprecationHelper().replaceWithInLoom2_0("getGameJarProcessors", "getMinecraftJarProcessors"); return jarProcessors; } + @Override + public void addJarProcessor(JarProcessor processor) { + getDeprecationHelper().replaceWithInLoom2_0("addJarProcessor", "getMinecraftJarProcessors"); + getMinecraftJarProcessors().add(getProject().getObjects().newInstance(LegacyJarProcessorWrapper.class, processor)); + } + + @Override + public ListProperty> getMinecraftJarProcessors() { + return minecraftJarProcessors; + } + @Override public Dependency officialMojangMappings() { if (layeredSpecBuilderScope.get()) { diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index a81a6d29c..a54882a6d 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -43,7 +43,6 @@ import net.fabricmc.loom.configuration.InstallerData; import net.fabricmc.loom.configuration.LoomDependencyManager; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; -import net.fabricmc.loom.configuration.processors.JarProcessorManager; import net.fabricmc.loom.configuration.providers.mappings.IntermediaryMappingsProvider; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; @@ -63,7 +62,6 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen private final List transitiveAccessWideners = new ArrayList<>(); private LoomDependencyManager dependencyManager; - private JarProcessorManager jarProcessorManager; private MinecraftProvider minecraftProvider; private MappingsProviderImpl mappingsProvider; private NamedMinecraftProvider namedMinecraftProvider; @@ -115,16 +113,6 @@ public LoomDependencyManager getDependencyManager() { return Objects.requireNonNull(dependencyManager, "Cannot get LoomDependencyManager before it has been setup"); } - @Override - public void setJarProcessorManager(JarProcessorManager jarProcessorManager) { - this.jarProcessorManager = jarProcessorManager; - } - - @Override - public JarProcessorManager getJarProcessorManager() { - return Objects.requireNonNull(jarProcessorManager, "Cannot get JarProcessorManager before it has been setup"); - } - @Override public MinecraftProvider getMinecraftProvider() { return Objects.requireNonNull(minecraftProvider, "Cannot get MinecraftProvider before it has been setup"); diff --git a/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java b/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java index d7b693db9..cce8773da 100644 --- a/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java +++ b/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java @@ -31,8 +31,8 @@ import org.gradle.api.logging.configuration.WarningMode; public interface DeprecationHelper { - default void replaceWithInLoom0_12(String currentName, String newName) { - toBeRemovedIn(currentName, newName, "Loom 0.12"); + default void replaceWithInLoom2_0(String currentName, String newName) { + toBeRemovedIn(currentName, newName, "Loom 2.0"); } default void toBeRemovedIn(String currentName, String newName, String removalVersion) { From 24b727c84ca0d963d4b8331223eef321aac30288 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Tue, 4 Oct 2022 20:46:46 +0100 Subject: [PATCH 04/13] More changes --- .../loom/api/LoomGradleExtensionAPI.java | 2 + .../processor/MappingProcessorContext.java | 28 ++++++ .../api/processor/MinecraftJarProcessor.java | 4 +- .../loom/api/processor/SpecContext.java | 9 +- .../configuration/CompileConfiguration.java | 12 +-- .../InterfaceInjectionProcessor.java | 5 +- .../MinecraftJarProcessorManager.java | 25 ++++- .../processors/ModJavadocProcessor.java | 98 +++++++++---------- .../processors/SpecContextImpl.java | 82 ++++++++++++++-- .../extension/LoomGradleExtensionApiImpl.java | 6 +- .../loom/task/GenerateSourcesTask.java | 12 ++- .../loom/util/fmj/FabricModJsonFactory.java | 6 +- .../loom/util/fmj/FabricModJsonSource.java | 4 +- .../loom/util/gradle/SourceSetHelper.java | 17 ++++ 14 files changed, 219 insertions(+), 91 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/api/processor/MappingProcessorContext.java diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java index 006a0c601..07a205902 100644 --- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java @@ -71,6 +71,8 @@ public interface LoomGradleExtensionAPI { ListProperty> getMinecraftJarProcessors(); + void addMinecraftJarProcessor(Class> clazz, Object... parameters); + ConfigurableFileCollection getLog4jConfigs(); Dependency officialMojangMappings(); diff --git a/src/main/java/net/fabricmc/loom/api/processor/MappingProcessorContext.java b/src/main/java/net/fabricmc/loom/api/processor/MappingProcessorContext.java new file mode 100644 index 000000000..3c4aad66b --- /dev/null +++ b/src/main/java/net/fabricmc/loom/api/processor/MappingProcessorContext.java @@ -0,0 +1,28 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.api.processor; + +public interface MappingProcessorContext { +} diff --git a/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java b/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java index 0a43306f6..a47d2520f 100644 --- a/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/api/processor/MinecraftJarProcessor.java @@ -44,10 +44,10 @@ default MappingsProcessor processMappings() { } interface Spec { - String cacheValue(); + // Must make sure hashCode is correctly implemented. } interface MappingsProcessor { - boolean transform(MemoryMappingTree mappings, S spec, ProcessorContext context); + boolean transform(MemoryMappingTree mappings, S spec, MappingProcessorContext context); } } diff --git a/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java b/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java index b803114c2..3370ae71c 100644 --- a/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java +++ b/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java @@ -25,11 +25,16 @@ package net.fabricmc.loom.api.processor; import java.util.List; +import java.util.stream.Stream; import net.fabricmc.loom.util.fmj.FabricModJson; public interface SpecContext { - List getModDependencies(); + List modDependencies(); - List getMods(); + List localMods(); + + default List allMods() { + return Stream.concat(modDependencies().stream(), localMods().stream()).toList(); + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 2bc79be04..09afc19a0 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -51,7 +51,6 @@ import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.processors.ModJavadocProcessor; -import net.fabricmc.loom.configuration.processors.SpecContextImpl; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; @@ -198,7 +197,7 @@ private static synchronized void setupMinecraft(Project project) throws Exceptio NamedMinecraftProvider namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(project, minecraftProvider); registerGameProcessors(project); - MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(extension.getMinecraftJarProcessors().get(), new SpecContextImpl()); + MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(project); if (minecraftJarProcessorManager != null) { // Wrap the named MC provider for one that will provide the processed jars @@ -235,14 +234,7 @@ private static void registerGameProcessors(Project project) { } } - if (extension.getEnableModProvidedJavadoc().get()) { - // This doesn't do any processing on the compiled jar, but it does have an effect on the generated sources. - final ModJavadocProcessor javadocProcessor = ModJavadocProcessor.create(project); - - if (javadocProcessor != null) { - extension.getGameJarProcessors().add(javadocProcessor); - } - } + extension.addMinecraftJarProcessor(ModJavadocProcessor.class, "fabric-loom:mod-javadoc"); } private static void setupMixinAp(Project project, MixinExtension mixin) { diff --git a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java index 85c0f83dd..9a28819c2 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java @@ -71,9 +71,6 @@ import net.fabricmc.tinyremapper.TinyRemapper; public class InterfaceInjectionProcessor implements JarProcessor, GenerateSourcesTask.MappingsProcessor { - // Filename used to store hash of injected interfaces in processed jar file - private static final String HASH_FILENAME = "injected_interfaces.sha256"; - private final Map> injectedInterfaces; private final Project project; private final LoomGradleExtension extension; @@ -200,7 +197,7 @@ private List getSourceInjectedInterface(SourceSet sourceSet) final FabricModJson fabricModJson; try { - fabricModJson = FabricModJsonFactory.createFromSourceSetNullable(sourceSet); + fabricModJson = FabricModJsonFactory.createFromSourceSetsNullable(sourceSet); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java index aed0d22cb..aa2027d1b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java @@ -36,8 +36,11 @@ import java.util.Objects; import java.util.stream.Collectors; +import org.gradle.api.Project; import org.jetbrains.annotations.Nullable; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.api.processor.MappingProcessorContext; import net.fabricmc.loom.api.processor.MinecraftJarProcessor; import net.fabricmc.loom.api.processor.ProcessorContext; import net.fabricmc.loom.api.processor.SpecContext; @@ -53,6 +56,12 @@ private MinecraftJarProcessorManager(List> jarProcessors) { this.jarProcessors = Collections.unmodifiableList(jarProcessors); } + @Nullable + public static MinecraftJarProcessorManager create(Project project) { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + return MinecraftJarProcessorManager.create(extension.getMinecraftJarProcessors().get(), SpecContextImpl.create(project)); + } + @Nullable public static MinecraftJarProcessorManager create(List> processors, SpecContext context) { List> entries = new ArrayList<>(); @@ -114,10 +123,16 @@ public void processJar(Path jar, ProcessorContext context) throws IOException { ZipUtils.add(jar, CACHE_VALUE_FILE_PATH, getCacheValue()); } - public void processMappings(MemoryMappingTree mappings, ProcessorContext context) { + public boolean processMappings(MemoryMappingTree mappings, MappingProcessorContext context) { + boolean transformed = false; + for (ProcessorEntry entry : jarProcessors) { - entry.processMappings(mappings, context); + if (entry.processMappings(mappings, context)) { + transformed = true; + } } + + return transformed; } record ProcessorEntry(S spec, MinecraftJarProcessor processor, @Nullable MinecraftJarProcessor.MappingsProcessor mappingsProcessor) { @@ -130,8 +145,8 @@ private void processJar(Path jar, ProcessorContext context) throws IOException { processor().processJar(jar, spec, context); } - private void processMappings(MemoryMappingTree mappings, ProcessorContext context) { - mappingsProcessor().transform(mappings, spec, context); + private boolean processMappings(MemoryMappingTree mappings, MappingProcessorContext context) { + return mappingsProcessor().transform(mappings, spec, context); } private String name() { @@ -139,7 +154,7 @@ private String name() { } private String cacheValue() { - return processor.getName() + ":" + spec.cacheValue(); + return processor.getName() + ":" + spec.hashCode(); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java b/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java index e7fc7ecec..cf9cdc4e1 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java @@ -25,15 +25,16 @@ package net.fabricmc.loom.configuration.processors; import java.io.ByteArrayInputStream; -import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.UncheckedIOException; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Set; + +import javax.inject.Inject; import com.google.gson.JsonElement; import org.gradle.api.Project; @@ -42,50 +43,49 @@ import org.slf4j.LoggerFactory; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.task.GenerateSourcesTask; +import net.fabricmc.loom.api.processor.MinecraftJarProcessor; +import net.fabricmc.loom.api.processor.ProcessorContext; +import net.fabricmc.loom.api.processor.SpecContext; import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.fmj.FabricModJson; -import net.fabricmc.loom.util.fmj.FabricModJsonFactory; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; -public final class ModJavadocProcessor implements JarProcessor, GenerateSourcesTask.MappingsProcessor { +public abstract class ModJavadocProcessor implements MinecraftJarProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(ModJavadocProcessor.class); - private final List javadocs; + @Inject + public abstract Project getProject(); + + private final String name; - private ModJavadocProcessor(List javadocs) { - this.javadocs = javadocs; + @Inject + public ModJavadocProcessor(String name) { + this.name = name; } - @Nullable - public static ModJavadocProcessor create(Project project) { - final LoomGradleExtension extension = LoomGradleExtension.get(project); - final List javadocs = new ArrayList<>(); + @Override + public String getName() { + return name; + } - for (RemapConfigurationSettings entry : extension.getRemapConfigurations()) { - final Set artifacts = entry.getSourceConfiguration().get().resolve(); + @Override + public @Nullable ModJavadocProcessor.Spec buildSpec(SpecContext context) { + final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); - for (File artifact : artifacts) { - if (!FabricModJsonFactory.isModJar(artifact.toPath())) { - continue; - } + if (!extension.getEnableModProvidedJavadoc().get()) { + return null; + } - final ModJavadoc modJavadoc; + List javadocs = new ArrayList<>(); - try { - modJavadoc = ModJavadoc.fromModJar(artifact.toPath()); - } catch (IOException e) { - throw new UncheckedIOException("Failed to read mod jar (%s)".formatted(artifact), e); - } + for (FabricModJson fabricModJson : context.allMods()) { + ModJavadoc javadoc = ModJavadoc.create(fabricModJson); - if (modJavadoc != null) { - javadocs.add(modJavadoc); - } + if (javadoc != null) { + javadocs.add(javadoc); } } @@ -93,36 +93,31 @@ public static ModJavadocProcessor create(Project project) { return null; } - return new ModJavadocProcessor(javadocs); + return new Spec(Collections.unmodifiableList(javadocs)); } - @Override - public boolean transform(MemoryMappingTree mappings) { - for (ModJavadoc javadoc : javadocs) { - javadoc.apply(mappings); - } - - return true; + public record Spec(List javadocs) implements MinecraftJarProcessor.Spec { } @Override - public String getId() { - return "loom:interface_injection:" + javadocs.hashCode(); + public void processJar(Path jar, Spec spec, ProcessorContext context) { + // Nothing to do for the jar } @Override - public void setup() { - } + public @Nullable MappingsProcessor processMappings() { + return (mappings, spec, context) -> { + for (ModJavadoc javadoc : spec.javadocs()) { + javadoc.apply(mappings); + } - @Override - public void process(File file) { - // No need to actually process anything, we need to be a JarProcessor to ensure that the jar is cached correctly. + return true; + }; } public record ModJavadoc(String modId, MemoryMappingTree mappingTree) { @Nullable - public static ModJavadoc fromModJar(Path path) throws IOException { - final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(path); + public static ModJavadoc create(FabricModJson fabricModJson) { final String modId = fabricModJson.getId(); final JsonElement customElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.PROVIDED_JAVADOC); @@ -131,11 +126,16 @@ public static ModJavadoc fromModJar(Path path) throws IOException { } final String javaDocPath = customElement.getAsString(); - final byte[] data = ZipUtils.unpack(path, javaDocPath); final MemoryMappingTree mappings = new MemoryMappingTree(); - try (Reader reader = new InputStreamReader(new ByteArrayInputStream(data))) { - MappingReader.read(reader, mappings); + try { + final byte[] data = fabricModJson.getSource().read(javaDocPath); + + try (Reader reader = new InputStreamReader(new ByteArrayInputStream(data))) { + MappingReader.read(reader, mappings); + } + } catch (IOException e) { + throw new UncheckedIOException("Failed to read javadoc from mod: " + modId, e); } if (!mappings.getSrcNamespace().equals(MappingsNamespace.INTERMEDIARY.toString())) { diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java index f487a8143..384bdf979 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java @@ -24,21 +24,85 @@ package net.fabricmc.loom.configuration.processors; +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Set; +import org.gradle.api.Project; +import org.gradle.api.tasks.SourceSet; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.processor.SpecContext; import net.fabricmc.loom.util.fmj.FabricModJson; +import net.fabricmc.loom.util.fmj.FabricModJsonFactory; +import net.fabricmc.loom.util.gradle.SourceSetHelper; + +/** + * @param modDependencies External mods that are depended on + * @param localMods The main mod being built. In the future this may also include other mods. + */ +public record SpecContextImpl(List modDependencies, List localMods) implements SpecContext { + public static SpecContextImpl create(Project project) { + return new SpecContextImpl(getDependentMods(project), getMods(project)); + } + + private static List getDependentMods(Project project) { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + var mods = new ArrayList(); + + for (RemapConfigurationSettings entry : extension.getRemapConfigurations()) { + final Set artifacts = entry.getSourceConfiguration().get().resolve(); + + for (File artifact : artifacts) { + final FabricModJson fabricModJson; + + try { + fabricModJson = FabricModJsonFactory.createFromZipNullable(artifact.toPath()); + } catch (IOException e) { + throw new UncheckedIOException("Failed to read dependent mod jar: " + artifact, e); + } + + if (fabricModJson != null) { + mods.add(fabricModJson); + } + } + } + + // TODO supporting projects here should magically allow TAWs and what not to work across project deps :) + + return sorted(mods); + } + + private static List getMods(Project project) { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + var sourceSets = new ArrayList(); + sourceSets.add(SourceSetHelper.getMainSourceSet(project)); + + if (extension.areEnvironmentSourceSetsSplit()) { + sourceSets.add(SourceSetHelper.getSourceSetByName("client", project)); + } + + try { + final FabricModJson fabricModJson = FabricModJsonFactory.createFromSourceSetsNullable(sourceSets.toArray(SourceSet[]::new)); + + if (fabricModJson != null) { + return List.of(fabricModJson); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } -public class SpecContextImpl implements SpecContext { - @Override - public List getModDependencies() { - // TODO - return null; + return Collections.emptyList(); } - @Override - public List getMods() { - // TODO - return null; + // Sort to ensure stable caching + private static List sorted(List mods) { + return mods.stream().sorted(Comparator.comparing(FabricModJson::getId)).toList(); } } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 788569806..4705ca9bf 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -173,7 +173,6 @@ public void decompilers(Action> ac @Override public ListProperty getGameJarProcessors() { - getDeprecationHelper().replaceWithInLoom2_0("getGameJarProcessors", "getMinecraftJarProcessors"); return jarProcessors; } @@ -188,6 +187,11 @@ public ListProperty> getMinecraftJarProcessors() { return minecraftJarProcessors; } + @Override + public void addMinecraftJarProcessor(Class> clazz, Object... parameters) { + getMinecraftJarProcessors().add(getProject().getObjects().newInstance(clazz, parameters)); + } + @Override public Dependency officialMojangMappings() { if (layeredSpecBuilderScope.get()) { diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index 2031892d7..b2c1fe428 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -64,9 +64,10 @@ import net.fabricmc.loom.api.decompilers.DecompilerOptions; import net.fabricmc.loom.api.decompilers.LoomDecompiler; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.api.processor.MappingProcessorContext; import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerMappingsProcessor; import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; -import net.fabricmc.loom.configuration.processors.ModJavadocProcessor; +import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.decompilers.LineNumberRemapper; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.FileSystemUtil; @@ -338,10 +339,10 @@ private Path getMappings() { mappingsProcessors.add(new InterfaceInjectionProcessor(getProject())); } - final ModJavadocProcessor javadocProcessor = ModJavadocProcessor.create(getProject()); + MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(getProject()); - if (javadocProcessor != null) { - mappingsProcessors.add(javadocProcessor); + if (minecraftJarProcessorManager != null) { + mappingsProcessors.add(mappings -> minecraftJarProcessorManager.processMappings(mappings, new MappingProcessorContextImpl())); } if (mappingsProcessors.isEmpty()) { @@ -392,4 +393,7 @@ private static Constructor getDecompilerConstructor(String clazz throw new RuntimeException(e); } } + + private static class MappingProcessorContextImpl implements MappingProcessorContext { + } } diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java index 390537540..4ebb95bc2 100644 --- a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java @@ -94,15 +94,15 @@ public static FabricModJson createFromDirectory(Path directory) throws IOExcepti } @Nullable - public static FabricModJson createFromSourceSetNullable(SourceSet sourceSet) throws IOException { - final File file = SourceSetHelper.findFileInResource(sourceSet, FABRIC_MOD_JSON); + public static FabricModJson createFromSourceSetsNullable(SourceSet... sourceSets) throws IOException { + final File file = SourceSetHelper.findFirstFileInResource(FABRIC_MOD_JSON, sourceSets); if (file == null) { return null; } try (Reader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) { - return create(LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class), new FabricModJsonSource.SourceSetSource(sourceSet)); + return create(LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class), new FabricModJsonSource.SourceSetSource(sourceSets)); } } diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java index b803add01..0da5fe98a 100644 --- a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonSource.java @@ -56,10 +56,10 @@ public byte[] read(String path) throws IOException { } } - record SourceSetSource(SourceSet sourceSet) implements FabricModJsonSource { + record SourceSetSource(SourceSet... sourceSets) implements FabricModJsonSource { @Override public byte[] read(String path) throws IOException { - final File file = SourceSetHelper.findFileInResource(sourceSet, path); + final File file = SourceSetHelper.findFirstFileInResource(path, sourceSets); if (file == null) { throw new FileNotFoundException("Could not find: " + path); diff --git a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java index ff108c38f..832c4f86b 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpressionException; @@ -275,6 +276,9 @@ private static List getBinDirClasspath(File projectDir, SourceSetReference @Nullable public static File findFileInResource(SourceSet sourceSet, String path) { + Objects.requireNonNull(sourceSet); + Objects.requireNonNull(path); + try { return sourceSet.getResources() .matching(patternFilterable -> patternFilterable.include(path)) @@ -284,4 +288,17 @@ public static File findFileInResource(SourceSet sourceSet, String path) { return null; } } + + @Nullable + public static File findFirstFileInResource(String path, SourceSet... sourceSets) { + for (SourceSet sourceSet : sourceSets) { + File file = findFileInResource(sourceSet, path); + + if (file != null) { + return file; + } + } + + return null; + } } From cc43cfc1dcc933c1ff5619299bc965afbcbc2e99 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Thu, 6 Oct 2022 21:42:45 +0100 Subject: [PATCH 05/13] Major steps towards config caching support :) --- .../mixin/AnnotationProcessorInvoker.java | 18 +++- .../configuration/CompileConfiguration.java | 21 +++-- .../configuration/LoomDependencyManager.java | 5 +- .../mods/ModConfigurationRemapper.java | 5 +- .../loom/configuration/mods/ModProcessor.java | 7 +- .../mappings/GradleMappingContext.java | 7 +- .../mappings/IntermediateMappingsService.java | 4 +- .../mappings/MappingsProviderImpl.java | 6 +- .../loom/task/AbstractRemapJarTask.java | 12 ++- .../loom/task/PrepareJarRemapTask.java | 2 +- .../net/fabricmc/loom/task/RemapJarTask.java | 24 +++-- .../loom/task/RemapSourcesJarTask.java | 7 +- .../loom/task/service/JarManifestService.java | 47 +++++----- .../loom/task/service/MappingsService.java | 8 +- .../task/service/MixinMappingsService.java | 70 --------------- .../task/service/SourceRemapperService.java | 7 +- .../task/service/TinyRemapperService.java | 32 +++++-- .../fabricmc/loom/util/DeprecationHelper.java | 7 -- .../loom/util/gradle/GradleUtils.java | 11 +++ .../loom/util/gradle/SourceSetHelper.java | 15 ++-- .../util/kotlin/KotlinClasspathService.java | 7 +- .../service/BuildSharedServiceManager.java | 90 +++++++++++++++++++ .../service/ScopedSharedServiceManager.java | 35 ++++++++ .../util/service/SharedServiceManager.java | 28 ++---- .../util/service/UnsafeWorkQueueHelper.java | 5 +- 25 files changed, 297 insertions(+), 183 deletions(-) delete mode 100644 src/main/java/net/fabricmc/loom/task/service/MixinMappingsService.java create mode 100644 src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java create mode 100644 src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java 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 0a79dab80..3415f7bda 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -45,7 +45,7 @@ import net.fabricmc.loom.configuration.ide.idea.IdeaUtils; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; import net.fabricmc.loom.extension.MixinExtension; -import net.fabricmc.loom.task.service.MixinMappingsService; +import net.fabricmc.loom.task.PrepareJarRemapTask; import net.fabricmc.loom.util.Constants; /** @@ -94,7 +94,7 @@ private void passMixinArguments(T task, SourceSet sourceSet) { String refmapName = Objects.requireNonNull(MixinExtension.getMixinInformationContainer(sourceSet)).refmapNameProvider().get(); Map args = new HashMap<>() {{ put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.toFile().getCanonicalPath()); - put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, MixinMappingsService.getMixinMappingFile(project, sourceSet).getCanonicalPath()); + put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, getMixinMappingsForSourceSet(project, sourceSet).getCanonicalPath()); put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName)); put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:" + loom.getMixin().getRefmapTargetNamespace().get()); put(Constants.MixinArguments.QUIET, "true"); @@ -111,6 +111,9 @@ private void passMixinArguments(T task, SourceSet sourceSet) { args.put("AMSG_" + key, value); }); + // Ensure that all of the mixin mappings have been generated before we create the mixin mappings. + runBeforePrepare(project, task); + project.getLogger().debug("Outputting refmap to dir: " + getRefmapDestinationDir(task) + " for compile task: " + task); args.forEach((k, v) -> passArgument(task, k, v)); } catch (IOException e) { @@ -143,6 +146,12 @@ public void configureMixin() { } } + private void runBeforePrepare(Project project, Task compileTask) { + project.getGradle().allprojects(otherProject -> { + otherProject.getTasks().withType(PrepareJarRemapTask.class, prepareRemapTask -> prepareRemapTask.mustRunAfter(compileTask)); + }); + } + private static void checkPattern(String input, Pattern pattern) { final Matcher matcher = pattern.matcher(input); @@ -150,4 +159,9 @@ private static void checkPattern(String input, Pattern pattern) { throw new IllegalArgumentException("Mixin argument (%s) does not match pattern (%s)".formatted(input, pattern.toString())); } } + + public static File getMixinMappingsForSourceSet(Project project, SourceSet sourceSet) { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + return new File(extension.getFiles().getProjectBuildCache(), "mixin-map-" + extension.getMappingsProvider().mappingsIdentifier() + "." + sourceSet.getName() + ".tiny"); + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 09afc19a0..b4fc5ff22 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -30,6 +30,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.function.Consumer; import org.gradle.api.NamedDomainObjectProvider; import org.gradle.api.Project; @@ -63,6 +64,8 @@ import net.fabricmc.loom.util.ExceptionUtil; import net.fabricmc.loom.util.gradle.GradleUtils; import net.fabricmc.loom.util.gradle.SourceSetHelper; +import net.fabricmc.loom.util.service.ScopedSharedServiceManager; +import net.fabricmc.loom.util.service.SharedServiceManager; public final class CompileConfiguration { private CompileConfiguration() { @@ -126,7 +129,7 @@ public static void configureCompile(Project project) { javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); }); - GradleUtils.afterSuccessfulEvaluation(project, () -> { + afterEvaluationWithService(project, (serviceManager) -> { MinecraftSourceSets.get(project).afterEvaluate(project); final boolean previousRefreshDeps = extension.refreshDeps(); @@ -137,14 +140,14 @@ public static void configureCompile(Project project) { } try { - setupMinecraft(project); + setupMinecraft(project, serviceManager); } catch (Exception e) { throw ExceptionUtil.createDescriptiveWrapper(RuntimeException::new, "Failed to setup Minecraft", e); } LoomDependencyManager dependencyManager = new LoomDependencyManager(); extension.setDependencyManager(dependencyManager); - dependencyManager.handleDependencies(project); + dependencyManager.handleDependencies(project, serviceManager); releaseLock(project); extension.setRefreshDeps(previousRefreshDeps); @@ -178,7 +181,7 @@ public static void configureCompile(Project project) { } // This is not thread safe across projects synchronize it here just to be sure, might be possible to move this further down, but for now this will do. - private static synchronized void setupMinecraft(Project project) throws Exception { + private static synchronized void setupMinecraft(Project project, SharedServiceManager serviceManager) throws Exception { final LoomGradleExtension extension = LoomGradleExtension.get(project); final MinecraftJarConfiguration jarConfiguration = extension.getMinecraftJarConfiguration().get(); @@ -188,7 +191,7 @@ private static synchronized void setupMinecraft(Project project) throws Exceptio minecraftProvider.provide(); final DependencyInfo mappingsDep = DependencyInfo.create(project, Constants.Configurations.MAPPINGS); - final MappingsProviderImpl mappingsProvider = MappingsProviderImpl.getInstance(project, mappingsDep, minecraftProvider); + final MappingsProviderImpl mappingsProvider = MappingsProviderImpl.getInstance(serviceManager, project, mappingsDep, minecraftProvider); extension.setMappingsProvider(mappingsProvider); mappingsProvider.applyToProject(project, mappingsDep); @@ -331,4 +334,12 @@ public static void extendsFrom(String a, String b, Project project) { private static void finalizedBy(Project project, String a, String b) { project.getTasks().named(a).configure(task -> task.finalizedBy(project.getTasks().named(b))); } + + private static void afterEvaluationWithService(Project project, Consumer consumer) { + GradleUtils.afterSuccessfulEvaluation(project, () -> { + try (var serviceManager = new ScopedSharedServiceManager()) { + consumer.accept(serviceManager); + } + }); + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index 22ce5a3ca..3ce043aec 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -44,9 +44,10 @@ import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.SourceRemapper; import net.fabricmc.loom.util.ZipUtils; +import net.fabricmc.loom.util.service.SharedServiceManager; public class LoomDependencyManager { - public void handleDependencies(Project project) { + public void handleDependencies(Project project, SharedServiceManager serviceManager) { List afterTasks = new ArrayList<>(); project.getLogger().info(":setting up loom dependencies"); @@ -78,7 +79,7 @@ public void handleDependencies(Project project) { SourceRemapper sourceRemapper = new SourceRemapper(project, true); String mappingsIdentifier = extension.getMappingsProvider().mappingsIdentifier(); - ModConfigurationRemapper.supplyModConfigurations(project, mappingsIdentifier, extension, sourceRemapper); + ModConfigurationRemapper.supplyModConfigurations(project, serviceManager, mappingsIdentifier, extension, sourceRemapper); sourceRemapper.remapAll(); diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java index d29c4c66b..e25f7c795 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java @@ -58,6 +58,7 @@ import net.fabricmc.loom.util.OperatingSystem; import net.fabricmc.loom.util.SourceRemapper; import net.fabricmc.loom.util.fmj.FabricModJsonFactory; +import net.fabricmc.loom.util.service.SharedServiceManager; @SuppressWarnings("UnstableApiUsage") public class ModConfigurationRemapper { @@ -65,7 +66,7 @@ public class ModConfigurationRemapper { // This can happen when the dependency is a FileCollectionDependency or from a flatDir repository. public static final String MISSING_GROUP = "unspecified"; - public static void supplyModConfigurations(Project project, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) { + public static void supplyModConfigurations(Project project, SharedServiceManager serviceManager, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) { final DependencyHandler dependencies = project.getDependencies(); for (RemapConfigurationSettings entry : extension.getRemapConfigurations()) { @@ -110,7 +111,7 @@ public static void supplyModConfigurations(Project project, String mappingsSuffi if (!toRemap.isEmpty()) { try { - new ModProcessor(project, sourceConfig).processMods(toRemap); + new ModProcessor(project, sourceConfig, serviceManager).processMods(toRemap); } catch (IOException e) { throw new UncheckedIOException("Failed to remap mods", e); } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index a5998ff8c..f79d8553b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -53,6 +53,7 @@ import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.kotlin.KotlinClasspathService; import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader; +import net.fabricmc.loom.util.service.SharedServiceManager; import net.fabricmc.tinyremapper.InputTag; import net.fabricmc.tinyremapper.NonClassCopyMode; import net.fabricmc.tinyremapper.OutputConsumerPath; @@ -64,10 +65,12 @@ public class ModProcessor { private final Project project; private final Configuration sourceConfiguration; + private final SharedServiceManager serviceManager; - public ModProcessor(Project project, Configuration sourceConfiguration) { + public ModProcessor(Project project, Configuration sourceConfiguration, SharedServiceManager serviceManager) { this.project = project; this.sourceConfiguration = sourceConfiguration; + this.serviceManager = serviceManager; } public void processMods(List remapList) throws IOException { @@ -101,7 +104,7 @@ private void remapJars(List remapList) throws IOException { .withMappings(TinyRemapperHelper.create(mappingsProvider.getMappings(), fromM, toM, false)) .renameInvalidLocals(false); - final KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(project); + final KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project); KotlinRemapperClassloader kotlinRemapperClassloader = null; if (kotlinClasspathService != null) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java index fdbd27d04..88ede35cd 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java @@ -38,6 +38,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingContext; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.util.download.DownloadBuilder; +import net.fabricmc.loom.util.service.ScopedSharedServiceManager; import net.fabricmc.mappingio.tree.MemoryMappingTree; public class GradleMappingContext implements MappingContext { @@ -66,7 +67,11 @@ public Path resolveMavenDependency(String mavenNotation) { @Override public Supplier intermediaryTree() { - return () -> IntermediateMappingsService.getInstance(project, minecraftProvider()).getMemoryMappingTree(); + return () -> { + try (var serviceManager = new ScopedSharedServiceManager()) { + return IntermediateMappingsService.getInstance(serviceManager, project, minecraftProvider()).getMemoryMappingTree(); + } + }; } @Override 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 13b1427cc..d605ea27c 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 @@ -56,12 +56,12 @@ private IntermediateMappingsService(Path intermediaryTiny) { this.intermediaryTiny = intermediaryTiny; } - public static synchronized IntermediateMappingsService getInstance(Project project, MinecraftProvider minecraftProvider) { + public static synchronized IntermediateMappingsService getInstance(SharedServiceManager sharedServiceManager, Project project, MinecraftProvider minecraftProvider) { final LoomGradleExtension extension = LoomGradleExtension.get(project); final IntermediateMappingsProvider intermediateProvider = extension.getIntermediateMappingsProvider(); final String id = "IntermediateMappingsService:%s:%s".formatted(intermediateProvider.getName(), intermediateProvider.getMinecraftVersion().get()); - return SharedServiceManager.get(project).getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider)); + return sharedServiceManager.getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider)); } @VisibleForTesting diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index c780a8cc6..11966c237 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -98,9 +98,9 @@ private MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, this.intermediaryService = intermediaryService; } - public static synchronized MappingsProviderImpl getInstance(Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) { - return SharedServiceManager.get(project).getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> { - Supplier intermediaryService = Suppliers.memoize(() -> IntermediateMappingsService.getInstance(project, minecraftProvider)); + public static synchronized MappingsProviderImpl getInstance(SharedServiceManager sharedServiceManager, Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) { + return sharedServiceManager.getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> { + Supplier intermediaryService = Suppliers.memoize(() -> IntermediateMappingsService.getInstance(sharedServiceManager, project, minecraftProvider)); return create(dependency, minecraftProvider, intermediaryService); }); } diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java index 053d8ec54..57f7dcdc2 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java @@ -45,10 +45,12 @@ import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; +import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; +import org.gradle.build.event.BuildEventsListenerRegistry; import org.gradle.jvm.tasks.Jar; import org.gradle.workers.WorkAction; import org.gradle.workers.WorkParameters; @@ -89,15 +91,23 @@ public abstract class AbstractRemapJarTask extends Jar { @Inject protected abstract WorkerExecutor getWorkerExecutor(); + @Inject + protected abstract BuildEventsListenerRegistry getBuildEventsListenerRegistry(); + @Input public abstract Property getIncludesClientOnlyClasses(); + private final Provider jarManifestServiceProvider; + @Inject public AbstractRemapJarTask() { getSourceNamespace().convention(MappingsNamespace.NAMED.toString()).finalizeValueOnRead(); getTargetNamespace().convention(MappingsNamespace.INTERMEDIARY.toString()).finalizeValueOnRead(); getRemapperIsolation().convention(false).finalizeValueOnRead(); getIncludesClientOnlyClasses().convention(false).finalizeValueOnRead(); + + jarManifestServiceProvider = JarManifestService.get(getProject()); + usesService(jarManifestServiceProvider); } public final

void submitWork(Class> workAction, Action

action) { @@ -113,7 +123,7 @@ public final

void submitWork(Class clientOnlyEntries = getClientOnlyEntries(); diff --git a/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java b/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java index f5761d0ae..360f88efc 100644 --- a/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java +++ b/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java @@ -78,7 +78,7 @@ public void run() { final WorkQueue workQueue = getWorkerExecutor().noIsolation(); workQueue.submit(ReadInputsAction.class, params -> { - params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(getProject(), remapJarTask.getTinyRemapperService())); + params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(remapJarTask.getTinyRemapperService())); params.getInputFile().set(getInputFile()); }); } diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index 8938f8324..ada1462a8 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -46,11 +46,13 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; +import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskAction; +import org.jetbrains.annotations.ApiStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,6 +73,7 @@ import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.fmj.FabricModJson; import net.fabricmc.loom.util.fmj.FabricModJsonFactory; +import net.fabricmc.loom.util.service.BuildSharedServiceManager; import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; @@ -82,11 +85,18 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { @Input public abstract Property getAddNestedDependencies(); - private Supplier tinyRemapperService = Suppliers.memoize(() -> TinyRemapperService.getOrCreate(this)); + @Input + @ApiStatus.Internal + public abstract Property getUseMixinAP(); + + private final Provider serviceManagerProvider; + private final Supplier tinyRemapperService; @Inject public RemapJarTask() { super(); + serviceManagerProvider = BuildSharedServiceManager.createForTask(this, getBuildEventsListenerRegistry()); + tinyRemapperService = Suppliers.memoize(() -> TinyRemapperService.getOrCreate(serviceManagerProvider.get().get(), this)); getClasspath().from(getProject().getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)); getAddNestedDependencies().convention(true).finalizeValueOnRead(); @@ -94,6 +104,8 @@ public RemapJarTask() { Configuration includeConfiguration = getProject().getConfigurations().getByName(Constants.Configurations.INCLUDE); getNestedJars().from(new IncludedJarFactory(getProject()).getNestedJars(includeConfiguration)); + getUseMixinAP().set(LoomGradleExtension.get(getProject()).getMixin().getUseLegacyMixinAp()); + setupPreparationTask(); } @@ -115,20 +127,18 @@ private void setupPreparationTask() { @TaskAction public void run() { - final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); - submitWork(RemapAction.class, params -> { if (getAddNestedDependencies().get()) { params.getNestedJars().from(getNestedJars()); } - params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(getProject(), tinyRemapperService.get())); + params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(tinyRemapperService.get())); params.getRemapClasspath().from(getClasspath()); - final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get(); - params.getUseMixinExtension().set(!legacyMixin); + final boolean mixinAp = getUseMixinAP().get(); + params.getUseMixinExtension().set(!mixinAp); - if (legacyMixin) { + if (mixinAp) { setupLegacyMixinRefmapRemapping(params); } }); diff --git a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java index c65b1c547..673196963 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java @@ -32,6 +32,7 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.provider.Property; +import org.gradle.api.provider.Provider; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskAction; import org.slf4j.Logger; @@ -39,12 +40,16 @@ import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; import net.fabricmc.loom.task.service.SourceRemapperService; +import net.fabricmc.loom.util.service.BuildSharedServiceManager; import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper; public abstract class RemapSourcesJarTask extends AbstractRemapJarTask { + private final Provider serviceManagerProvider; + @Inject public RemapSourcesJarTask() { super(); + serviceManagerProvider = BuildSharedServiceManager.createForTask(this, getBuildEventsListenerRegistry()); getClasspath().from(getProject().getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)); } @@ -52,7 +57,7 @@ public RemapSourcesJarTask() { @TaskAction public void run() { submitWork(RemapSourcesAction.class, params -> { - params.getSourcesRemapperServiceUuid().set(UnsafeWorkQueueHelper.create(getProject(), SourceRemapperService.create(this))); + params.getSourcesRemapperServiceUuid().set(UnsafeWorkQueueHelper.create(SourceRemapperService.create(serviceManagerProvider.get().get(), this))); }); } diff --git a/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java b/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java index 117207fad..f1c3d9b24 100644 --- a/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java +++ b/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java @@ -40,6 +40,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.configuration.InstallerData; import net.fabricmc.loom.util.Constants; import net.fabricmc.tinyremapper.TinyRemapper; @@ -63,10 +64,10 @@ public static synchronized Provider get(Project project) { params.getGradleVersion().set(GradleVersion.current().getVersion()); params.getLoomVersion().set(LoomGradlePlugin.LOOM_VERSION); params.getMCEVersion().set(Constants.Dependencies.Versions.MIXIN_COMPILE_EXTENSIONS); - params.getMinecraftVersion().set(extension.getMinecraftProvider().minecraftVersion()); + params.getMinecraftVersion().set(project.provider(() -> extension.getMinecraftProvider().minecraftVersion())); params.getTinyRemapperVersion().set(tinyRemapperVersion.orElse("unknown")); - params.getFabricLoaderVersion().set(getLoaderVersion(project).orElse("unknown")); - params.getMixinVersion().set(getMixinVersion(project).orElse(new MixinVersion("unknown", "unknown"))); + params.getFabricLoaderVersion().set(project.provider(() -> Optional.ofNullable(extension.getInstallerData()).map(InstallerData::version).orElse("unknown"))); + params.getMixinVersion().set(getMixinVersion(project)); }); }); } @@ -98,31 +99,23 @@ public void apply(Manifest manifest, Map extraValues) { } } - private static Optional getLoaderVersion(Project project) { - LoomGradleExtension extension = LoomGradleExtension.get(project); - - if (extension.getInstallerData() == null) { - project.getLogger().warn("Could not determine fabric loader version for jar manifest"); - return Optional.empty(); - } - - return Optional.of(extension.getInstallerData().version()); - } - private record MixinVersion(String group, String version) implements Serializable { } - private static Optional getMixinVersion(Project project) { - // Not super ideal that this uses the mod compile classpath, should prob look into making this not a thing at somepoint - Optional dependency = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES) - .getDependencies() - .stream() - .filter(dep -> "sponge-mixin".equals(dep.getName())) - .findFirst(); - - if (dependency.isEmpty()) { - project.getLogger().warn("Could not determine Mixin version for jar manifest"); - } - - return dependency.map(d -> new MixinVersion(d.getGroup(), d.getVersion())); + private static Provider getMixinVersion(Project project) { + return project.getConfigurations().named(Constants.Configurations.LOADER_DEPENDENCIES).map(configuration -> { + // Not super ideal that this uses the mod compile classpath, should prob look into making this not a thing at somepoint + Optional dependency = configuration + .getDependencies() + .stream() + .filter(dep -> "sponge-mixin".equals(dep.getName())) + .findFirst(); + + if (dependency.isEmpty()) { + project.getLogger().warn("Could not determine Mixin version for jar manifest"); + } + + return dependency.map(d -> new MixinVersion(d.getGroup(), d.getVersion())) + .orElse(new MixinVersion("unknown", "unknown")); + }); } } diff --git a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java index 53e9bec42..16a436bca 100644 --- a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java +++ b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java @@ -42,21 +42,17 @@ public final class MappingsService implements SharedService { private record Options(Path mappingsFile, String from, String to, boolean remapLocals) { } - public static MappingsService create(Project project, String name, Path mappingsFile, String from, String to, boolean remapLocals) { - return create(SharedServiceManager.get(project), name, mappingsFile, from, to, remapLocals); - } - public static synchronized MappingsService create(SharedServiceManager sharedServiceManager, String name, Path mappingsFile, String from, String to, boolean remapLocals) { final Options options = new Options(mappingsFile, from, to, remapLocals); final String id = name + options.hashCode(); return sharedServiceManager.getOrCreateService(id, () -> new MappingsService(options)); } - public static MappingsService createDefault(Project project, String from, String to) { + public static MappingsService createDefault(Project project, SharedServiceManager serviceManager, String from, String to) { final MappingsProviderImpl mappingsProvider = LoomGradleExtension.get(project).getMappingsProvider(); final String name = mappingsProvider.getBuildServiceName("mappingsProvider", from, to); - return MappingsService.create(project, name, mappingsProvider.tinyMappings, from, to, false); + return MappingsService.create(serviceManager, name, mappingsProvider.tinyMappings, from, to, false); } private final Options options; diff --git a/src/main/java/net/fabricmc/loom/task/service/MixinMappingsService.java b/src/main/java/net/fabricmc/loom/task/service/MixinMappingsService.java deleted file mode 100644 index a1a7336f0..000000000 --- a/src/main/java/net/fabricmc/loom/task/service/MixinMappingsService.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2022 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.task.service; - -import java.io.File; -import java.util.HashSet; - -import org.gradle.api.Project; -import org.gradle.api.tasks.SourceSet; - -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; -import net.fabricmc.loom.util.service.SharedService; -import net.fabricmc.loom.util.service.SharedServiceManager; -import net.fabricmc.tinyremapper.IMappingProvider; - -public final class MixinMappingsService implements SharedService { - private final SharedServiceManager sharedServiceManager; - private final HashSet mixinMappings = new HashSet<>(); - - private MixinMappingsService(SharedServiceManager sharedServiceManager) { - this.sharedServiceManager = sharedServiceManager; - } - - public static File getMixinMappingFile(Project project, SourceSet sourceSet) { - final LoomGradleExtension extension = LoomGradleExtension.get(project); - File mixinMapping = new File(extension.getFiles().getProjectBuildCache(), "mixin-map-" + extension.getMappingsProvider().mappingsIdentifier() + "." + sourceSet.getName() + ".tiny"); - - getService(SharedServiceManager.get(project), extension.getMappingsProvider()).mixinMappings.add(mixinMapping); - - return mixinMapping; - } - - static synchronized MixinMappingsService getService(SharedServiceManager sharedServiceManager, MappingsProviderImpl mappingsProvider) { - return sharedServiceManager.getOrCreateService("MixinMappings-" + mappingsProvider.mappingsIdentifier(), () -> new MixinMappingsService(sharedServiceManager)); - } - - IMappingProvider getMappingProvider(String from, String to) { - return out -> { - for (File mixinMapping : mixinMappings) { - if (!mixinMapping.exists()) continue; - - MappingsService service = MappingsService.create(sharedServiceManager, mixinMapping.getAbsolutePath(), mixinMapping.toPath(), from, to, false); - service.getMappingsProvider().load(out); - } - }; - } -} diff --git a/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java index 30b1ea0fb..f33a089a4 100644 --- a/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/SourceRemapperService.java @@ -52,16 +52,15 @@ import net.fabricmc.lorenztiny.TinyMappingsReader; public final class SourceRemapperService implements SharedService { - public static synchronized SourceRemapperService create(RemapSourcesJarTask task) { + public static synchronized SourceRemapperService create(SharedServiceManager serviceManager, RemapSourcesJarTask task) { final Project project = task.getProject(); final String to = task.getTargetNamespace().get(); final String from = task.getSourceNamespace().get(); final LoomGradleExtension extension = LoomGradleExtension.get(project); - final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project); final String id = extension.getMappingsProvider().getBuildServiceName("sourceremapper", from, to); - return sharedServiceManager.getOrCreateService(id, () -> - new SourceRemapperService(MappingsService.createDefault(project, from, to), task.getClasspath() + return serviceManager.getOrCreateService(id, () -> + new SourceRemapperService(MappingsService.createDefault(project, serviceManager, from, to), task.getClasspath() )); } diff --git a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java index cd780ee77..6d29b9d9f 100644 --- a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java @@ -37,10 +37,15 @@ import java.util.StringJoiner; import org.gradle.api.Project; +import org.gradle.api.invocation.Gradle; +import org.gradle.api.tasks.SourceSet; import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.build.mixin.AnnotationProcessorInvoker; import net.fabricmc.loom.task.AbstractRemapJarTask; +import net.fabricmc.loom.util.gradle.GradleUtils; +import net.fabricmc.loom.util.gradle.SourceSetHelper; import net.fabricmc.loom.util.kotlin.KotlinClasspath; import net.fabricmc.loom.util.kotlin.KotlinClasspathService; import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader; @@ -51,14 +56,13 @@ import net.fabricmc.tinyremapper.TinyRemapper; public class TinyRemapperService implements SharedService { - public static synchronized TinyRemapperService getOrCreate(AbstractRemapJarTask remapJarTask) { + public static synchronized TinyRemapperService getOrCreate(SharedServiceManager serviceManager, AbstractRemapJarTask remapJarTask) { final Project project = remapJarTask.getProject(); final String to = remapJarTask.getTargetNamespace().get(); final String from = remapJarTask.getSourceNamespace().get(); final LoomGradleExtension extension = LoomGradleExtension.get(project); - final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project); final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get(); - final @Nullable KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(project); + final @Nullable KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project); // Generates an id that is used to share the remapper across projects. This tasks in the remap jar task name to handle custom remap jar tasks separately. final var joiner = new StringJoiner(":"); @@ -75,12 +79,12 @@ public static synchronized TinyRemapperService getOrCreate(AbstractRemapJarTask final String id = joiner.toString(); - TinyRemapperService service = sharedServiceManager.getOrCreateService(id, () -> { + TinyRemapperService service = serviceManager.getOrCreateService(id, () -> { List mappings = new ArrayList<>(); - mappings.add(MappingsService.createDefault(project, from, to).getMappingsProvider()); + mappings.add(MappingsService.createDefault(project, serviceManager, from, to).getMappingsProvider()); if (legacyMixin) { - mappings.add(MixinMappingsService.getService(SharedServiceManager.get(project), extension.getMappingsProvider()).getMappingProvider(from, to)); + mappings.add(gradleMixinMappingProvider(serviceManager, project.getGradle(), from, to)); } return new TinyRemapperService(mappings, !legacyMixin, kotlinClasspathService); @@ -91,6 +95,22 @@ public static synchronized TinyRemapperService getOrCreate(AbstractRemapJarTask return service; } + // Add all of the mixin mappings from all loom projects. + private static IMappingProvider gradleMixinMappingProvider(SharedServiceManager serviceManager, Gradle gradle, String from, String to) { + return out -> GradleUtils.allLoomProjects(gradle, project -> { + for (SourceSet sourceSet : SourceSetHelper.getSourceSets(project)) { + final File mixinMappings = AnnotationProcessorInvoker.getMixinMappingsForSourceSet(project, sourceSet); + + if (!mixinMappings.exists()) { + continue; + } + + MappingsService service = MappingsService.create(serviceManager, mixinMappings.getAbsolutePath(), mixinMappings.toPath(), from, to, false); + service.getMappingsProvider().load(out); + } + }); + } + private TinyRemapper tinyRemapper; @Nullable private KotlinRemapperClassloader kotlinRemapperClassloader; diff --git a/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java b/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java index cce8773da..9ddbfb699 100644 --- a/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java +++ b/src/main/java/net/fabricmc/loom/util/DeprecationHelper.java @@ -49,13 +49,6 @@ class ProjectBased implements DeprecationHelper { public ProjectBased(Project project) { this.project = project; - - project.getGradle().buildFinished(buildResult -> { - if (usingDeprecatedApi.get()) { - project.getLogger().lifecycle("Deprecated Loom APIs were used in this build, making it incompatible with future versions of Loom. " - + "Use Gradle warning modes to control the verbosity of the warnings."); - } - }); } @Override diff --git a/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java b/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java index 56162a2e1..88accb25a 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java @@ -24,7 +24,10 @@ package net.fabricmc.loom.util.gradle; +import java.util.function.Consumer; + import org.gradle.api.Project; +import org.gradle.api.invocation.Gradle; public final class GradleUtils { private GradleUtils() { @@ -41,4 +44,12 @@ public static void afterSuccessfulEvaluation(Project project, Runnable afterEval afterEvaluate.run(); }); } + + public static void allLoomProjects(Gradle gradle, Consumer consumer) { + gradle.allprojects(project -> { + if (project.getPluginManager().hasPlugin("fabric-loom")) { + consumer.accept(project); + } + }); + } } diff --git a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java index 832c4f86b..4b4938758 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java @@ -45,6 +45,7 @@ import org.gradle.api.internal.tasks.DefaultTaskDependency; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.SourceSetOutput; import org.gradle.api.tasks.TaskProvider; import org.intellij.lang.annotations.Language; @@ -63,20 +64,23 @@ public final class SourceSetHelper { private SourceSetHelper() { } + public static SourceSetContainer getSourceSets(Project project) { + final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class); + return javaExtension.getSourceSets(); + } + /** * Returns true when the provided project contains the {@link SourceSet}. */ public static boolean isSourceSetOfProject(SourceSet sourceSet, Project project) { if (System.getProperty("fabric-loom.unit.testing") != null) return true; - final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class); - return javaExtension.getSourceSets().stream() + return getSourceSets(project).stream() .anyMatch(test -> test == sourceSet); // Ensure we have an identical reference } public static SourceSet getSourceSetByName(String name, Project project) { - final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class); - return javaExtension.getSourceSets().getByName(name); + return getSourceSets(project).getByName(name); } public static SourceSet getMainSourceSet(Project project) { @@ -84,8 +88,7 @@ public static SourceSet getMainSourceSet(Project project) { } public static SourceSet createSourceSet(String name, Project project) { - final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class); - return javaExtension.getSourceSets().create(name); + return getSourceSets(project).create(name); } /** diff --git a/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java b/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java index 05b9cada3..9657413bd 100644 --- a/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java +++ b/src/main/java/net/fabricmc/loom/util/kotlin/KotlinClasspathService.java @@ -39,17 +39,16 @@ public record KotlinClasspathService(Set classpath, String version) implements KotlinClasspath, SharedService { @Nullable - public static KotlinClasspathService getOrCreateIfRequired(Project project) { + public static KotlinClasspathService getOrCreateIfRequired(SharedServiceManager sharedServiceManager, Project project) { if (!KotlinPluginUtils.hasKotlinPlugin(project)) { return null; } - return getOrCreate(project, KotlinPluginUtils.getKotlinPluginVersion(project), KotlinPluginUtils.getKotlinMetadataVersion()); + return getOrCreate(sharedServiceManager, project, KotlinPluginUtils.getKotlinPluginVersion(project), KotlinPluginUtils.getKotlinMetadataVersion()); } - public static synchronized KotlinClasspathService getOrCreate(Project project, String kotlinVersion, String kotlinMetadataVersion) { + public static synchronized KotlinClasspathService getOrCreate(SharedServiceManager sharedServiceManager, Project project, String kotlinVersion, String kotlinMetadataVersion) { final String id = "kotlinclasspath:%s:%s".formatted(kotlinVersion, kotlinMetadataVersion); - final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project); return sharedServiceManager.getOrCreateService(id, () -> create(project, kotlinVersion, kotlinMetadataVersion)); } diff --git a/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java new file mode 100644 index 000000000..bde78bc35 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java @@ -0,0 +1,90 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.service; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; + +import org.gradle.api.Task; +import org.gradle.api.provider.Provider; +import org.gradle.api.services.BuildService; +import org.gradle.api.services.BuildServiceParameters; +import org.gradle.build.event.BuildEventsListenerRegistry; +import org.gradle.tooling.events.OperationCompletionListener; +import org.gradle.tooling.events.task.TaskOperationDescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class BuildSharedServiceManager implements BuildService { + private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class); + private static final String NAME = "loom:sharedServiceManager"; + + private SharedServiceManager sharedServiceManager = new BuildSharedServiceManagerImpl(); + private final AtomicInteger refCount = new AtomicInteger(0); + + public static Provider createForTask(Task task, BuildEventsListenerRegistry buildEventsListenerRegistry) { + Provider provider = task.getProject().getGradle().getSharedServices().registerIfAbsent(NAME, BuildSharedServiceManager.class, spec -> { + }); + task.usesService(provider); + + final BuildSharedServiceManager serviceManager = provider.get(); + buildEventsListenerRegistry.onTaskCompletion(registerTaskCompletion(task, serviceManager::onFinish)); + int count = serviceManager.refCount.incrementAndGet(); + LOGGER.debug("Creating shared service manager provider for task: {} count: {}", task.getName(), count); + + return provider; + } + + public SharedServiceManager get() { + LOGGER.debug("Shared build service get"); + return Objects.requireNonNull(sharedServiceManager); + } + + private void onFinish() { + int count = refCount.decrementAndGet(); + + LOGGER.debug("Build service finish. count: {}", count); + + if (count == 0) { + sharedServiceManager.onFinish(); + sharedServiceManager = null; + } else if (count < 0) { + throw new IllegalStateException(); + } + } + + private static Provider registerTaskCompletion(Task task, Runnable runnable) { + return task.getProject().provider(() -> event -> { + if (event.getDescriptor() instanceof TaskOperationDescriptor taskDescriptor) { + if (taskDescriptor.getTaskPath().equals(task.getPath())) { + runnable.run(); + } + } + }); + } + + private static final class BuildSharedServiceManagerImpl extends SharedServiceManager { + } +} diff --git a/src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java new file mode 100644 index 000000000..8431ac3ab --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/service/ScopedSharedServiceManager.java @@ -0,0 +1,35 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.util.service; + +public final class ScopedSharedServiceManager extends SharedServiceManager implements AutoCloseable { + public ScopedSharedServiceManager() { + } + + @Override + public void close() { + onFinish(); + } +} diff --git a/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java index 62f1e922a..0aa7922a8 100644 --- a/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java +++ b/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java @@ -31,33 +31,21 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; -import org.gradle.BuildResult; -import org.gradle.api.Project; -import org.gradle.api.invocation.Gradle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A simple manager for {@link SharedService} to be used across gradle (sub) projects. * This is a basic replacement for gradle's build service api. */ -public final class SharedServiceManager { - private static final Map SERVICE_FACTORY_MAP = new ConcurrentHashMap<>(); - private final Gradle gradle; - +public abstract class SharedServiceManager { + private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class); private final Map sharedServiceMap = new ConcurrentHashMap<>(); private boolean shutdown = false; - private SharedServiceManager(Gradle gradle) { - this.gradle = gradle; - this.gradle.buildFinished(this::onFinish); - } - - public static SharedServiceManager get(Project project) { - return get(project.getGradle()); - } - - public static SharedServiceManager get(Gradle gradle) { - return SERVICE_FACTORY_MAP.computeIfAbsent(gradle, SharedServiceManager::new); + SharedServiceManager() { + LOGGER.info("Creating new SharedServiceManager({})", hashCode()); } public S getOrCreateService(String id, Supplier function) { @@ -78,12 +66,12 @@ public S getOrCreateService(String id, Supplier fun } } - private void onFinish(BuildResult buildResult) { + protected void onFinish() { synchronized (sharedServiceMap) { shutdown = true; } - SERVICE_FACTORY_MAP.remove(gradle); + LOGGER.info("Closing SharedServiceManager({})", hashCode()); final List exceptionList = new ArrayList<>(); diff --git a/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java b/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java index 62faa2908..13ab18bb6 100644 --- a/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java +++ b/src/main/java/net/fabricmc/loom/util/service/UnsafeWorkQueueHelper.java @@ -28,7 +28,6 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import org.gradle.api.Project; import org.gradle.api.provider.Property; // Massive hack to work around WorkerExecutor.noIsolation() doing isolation checks. @@ -38,12 +37,10 @@ public final class UnsafeWorkQueueHelper { private UnsafeWorkQueueHelper() { } - public static String create(Project project, SharedService service) { + public static String create(SharedService service) { final String uuid = UUID.randomUUID().toString(); SERVICE_MAP.put(uuid, service); - // Ensure we don't make a mess if things go wrong. - project.getGradle().buildFinished(buildResult -> SERVICE_MAP.remove(uuid)); return uuid; } From 0036d81a3aa29ade7db6e01010a924df13fab5f9 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Thu, 6 Oct 2022 22:48:09 +0100 Subject: [PATCH 06/13] Fixes to legacy jar processors. --- .../net/fabricmc/loom/api/LoomGradleExtensionAPI.java | 8 +++++--- .../loom/configuration/processors/JarProcessor.java | 2 +- .../processors/LegacyJarProcessorWrapper.java | 6 ++++++ .../processors/MinecraftJarProcessorManager.java | 8 +++++++- .../loom/configuration/processors/SpecContextImpl.java | 8 +------- .../loom/extension/LoomGradleExtensionApiImpl.java | 9 +-------- src/main/java/net/fabricmc/loom/task/RemapJarTask.java | 7 ++++++- .../fabricmc/loom/util/fmj/FabricModJsonFactory.java | 10 ++++++++-- .../net/fabricmc/loom/test/LoomTestConstants.groovy | 2 +- 9 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java index 07a205902..1b09cdc31 100644 --- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java @@ -63,11 +63,13 @@ public interface LoomGradleExtensionAPI { void decompilers(Action> action); - @Deprecated(forRemoval = true) + @Deprecated() ListProperty getGameJarProcessors(); - @Deprecated(forRemoval = true) - void addJarProcessor(JarProcessor processor); + @Deprecated() + default void addJarProcessor(JarProcessor processor) { + getGameJarProcessors().add(processor); + } ListProperty> getMinecraftJarProcessors(); diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java index 34833a929..72a7c2eaa 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/JarProcessor.java @@ -26,7 +26,7 @@ import java.io.File; -@Deprecated(forRemoval = true) +@Deprecated() public interface JarProcessor { /** * Returns a unique ID for this jar processor, containing all configuration details. diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java b/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java index 98ab20333..847e391c6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/LegacyJarProcessorWrapper.java @@ -47,8 +47,14 @@ public LegacyJarProcessorWrapper(JarProcessor delegate) { this.delegate = delegate; } + @Inject public abstract Project getProject(); + @Override + public String getName() { + return "legacy:" + delegate.getClass().getCanonicalName(); + } + @Override public @Nullable LegacyJarProcessorWrapper.Spec buildSpec(SpecContext context) { delegate.setup(); diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java index aa2027d1b..609045fec 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java @@ -59,7 +59,13 @@ private MinecraftJarProcessorManager(List> jarProcessors) { @Nullable public static MinecraftJarProcessorManager create(Project project) { final LoomGradleExtension extension = LoomGradleExtension.get(project); - return MinecraftJarProcessorManager.create(extension.getMinecraftJarProcessors().get(), SpecContextImpl.create(project)); + List> processors = new ArrayList<>(extension.getMinecraftJarProcessors().get()); + + for (JarProcessor legacyProcessor : extension.getGameJarProcessors().get()) { + processors.add(project.getObjects().newInstance(LegacyJarProcessorWrapper.class, legacyProcessor)); + } + + return MinecraftJarProcessorManager.create(processors, SpecContextImpl.create(project)); } @Nullable diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java index 384bdf979..50567c970 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java @@ -60,13 +60,7 @@ private static List getDependentMods(Project project) { final Set artifacts = entry.getSourceConfiguration().get().resolve(); for (File artifact : artifacts) { - final FabricModJson fabricModJson; - - try { - fabricModJson = FabricModJsonFactory.createFromZipNullable(artifact.toPath()); - } catch (IOException e) { - throw new UncheckedIOException("Failed to read dependent mod jar: " + artifact, e); - } + final FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(artifact.toPath()); if (fabricModJson != null) { mods.add(fabricModJson); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 4705ca9bf..af0254392 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -51,7 +51,6 @@ import net.fabricmc.loom.configuration.RemapConfigurations; import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.processors.JarProcessor; -import net.fabricmc.loom.configuration.processors.LegacyJarProcessorWrapper; import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl; @@ -67,7 +66,7 @@ */ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionAPI { protected final DeprecationHelper deprecationHelper; - @Deprecated(forRemoval = true) + @Deprecated() protected final ListProperty jarProcessors; protected final ConfigurableFileCollection log4jConfigs; protected final RegularFileProperty accessWidener; @@ -176,12 +175,6 @@ public ListProperty getGameJarProcessors() { return jarProcessors; } - @Override - public void addJarProcessor(JarProcessor processor) { - getDeprecationHelper().replaceWithInLoom2_0("addJarProcessor", "getMinecraftJarProcessors"); - getMinecraftJarProcessors().add(getProject().getObjects().newInstance(LegacyJarProcessorWrapper.class, processor)); - } - @Override public ListProperty> getMinecraftJarProcessors() { return minecraftJarProcessors; diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index ada1462a8..7b300db6e 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -148,7 +148,12 @@ private void setupLegacyMixinRefmapRemapping(RemapParams params) { final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); final MixinExtension mixinExtension = extension.getMixin(); - final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(getInputFile().getAsFile().get().toPath()); + final FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(getInputFile().getAsFile().get().toPath()); + + if (fabricModJson == null) { + return; + } + final Collection allMixinConfigs = fabricModJson.getMixinConfigurations(); for (SourceSet sourceSet : mixinExtension.getMixinSourceSets()) { diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java index 4ebb95bc2..812b385f9 100644 --- a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java @@ -75,8 +75,14 @@ public static FabricModJson createFromZip(Path zipPath) { } @Nullable - public static FabricModJson createFromZipNullable(Path zipPath) throws IOException { - JsonObject jsonObject = ZipUtils.unpackGsonNullable(zipPath, FABRIC_MOD_JSON, JsonObject.class); + public static FabricModJson createFromZipNullable(Path zipPath) { + JsonObject jsonObject; + + try { + jsonObject = ZipUtils.unpackGsonNullable(zipPath, FABRIC_MOD_JSON, JsonObject.class); + } catch (IOException e) { + throw new UncheckedIOException("Failed to read zip: " + zipPath, e); + } if (jsonObject == null) { return null; diff --git a/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy b/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy index 448effa90..b08f8b8eb 100644 --- a/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy @@ -27,7 +27,7 @@ package net.fabricmc.loom.test import org.gradle.util.GradleVersion class LoomTestConstants { - private final static String NIGHTLY_VERSION = "8.0-20220911113203+0000" + private final static String NIGHTLY_VERSION = "8.0-20221005221811+0000" private final static boolean NIGHTLY_EXISTS = nightlyExists(NIGHTLY_VERSION) public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion() From 9d7a3eef8f2efea57cfdc293229ac7d7854cb58b Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Fri, 7 Oct 2022 10:28:53 +0100 Subject: [PATCH 07/13] Fix crash. More small fixes. --- .../ifaceinject/InterfaceInjectionProcessor.java | 8 +++++++- .../fabricmc/loom/util/gradle/SourceSetHelper.java | 1 + .../loom/util/service/BuildSharedServiceManager.java | 4 ++++ .../loom/util/service/SharedServiceManager.java | 11 ++++++----- .../loom/test/benchmark/FabricAPIBenchmark.groovy | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java index 9a28819c2..15ea74c8d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java @@ -258,7 +258,13 @@ private record InjectedInterface(String modId, String className, String ifaceNam * Reads the injected interfaces contained in a mod jar, or returns empty if there is none. */ public static List fromModJar(Path modJarPath) { - return fromFabricModJson(FabricModJsonFactory.createFromZip(modJarPath)); + FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(modJarPath); + + if (fabricModJson == null) { + return Collections.emptyList(); + } + + return fromFabricModJson(fabricModJson); } public static List fromFabricModJson(FabricModJson fabricModJson) { diff --git a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java index 50c811bdd..2bdbf2480 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/SourceSetHelper.java @@ -32,6 +32,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Set; import javax.xml.xpath.XPath; diff --git a/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java index bde78bc35..6575611de 100644 --- a/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java +++ b/src/main/java/net/fabricmc/loom/util/service/BuildSharedServiceManager.java @@ -57,6 +57,10 @@ public static Provider createForTask(Task task, Build return provider; } + public BuildSharedServiceManager() { + LOGGER.debug("New BuildSharedServiceManager instance"); + } + public SharedServiceManager get() { LOGGER.debug("Shared build service get"); return Objects.requireNonNull(sharedServiceManager); diff --git a/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java b/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java index 0aa7922a8..fbdc9820a 100644 --- a/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java +++ b/src/main/java/net/fabricmc/loom/util/service/SharedServiceManager.java @@ -26,9 +26,9 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import org.slf4j.Logger; @@ -40,7 +40,7 @@ */ public abstract class SharedServiceManager { private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class); - private final Map sharedServiceMap = new ConcurrentHashMap<>(); + private final Map sharedServiceMap = new HashMap<>(); private boolean shutdown = false; @@ -58,6 +58,7 @@ public S getOrCreateService(String id, Supplier fun S sharedService = (S) sharedServiceMap.get(id); if (sharedService == null) { + LOGGER.debug("Creating service for {}", id); sharedService = function.get(); sharedServiceMap.put(id, sharedService); } @@ -85,14 +86,14 @@ protected void onFinish() { sharedServiceMap.clear(); + // This is required to ensure that mercury releases all of the file handles. + System.gc(); + if (!exceptionList.isEmpty()) { // Done to try and close all the services. RuntimeException exception = new RuntimeException("Failed to close all shared services"); exceptionList.forEach(exception::addSuppressed); throw exception; } - - // This is required to ensure that mercury releases all of the file handles. - System.gc(); } } diff --git a/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy b/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy index a19b35be4..8905380cf 100644 --- a/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/benchmark/FabricAPIBenchmark.groovy @@ -43,7 +43,7 @@ class FabricAPIBenchmark implements GradleProjectTestTrait { allowExistingRepo: true, repo: "https://github.com/FabricMC/fabric.git", - commit: "71b634e5b7845296b11be3fa6545f4fbfacc017f", + commit: "5f243a8b7849eac4b30cd876a22a127797a1c406", patch: "fabric_api" ) From 06074ae73c7c3c2967cdafbd1af542696d6ffe61 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Fri, 7 Oct 2022 21:49:43 +0100 Subject: [PATCH 08/13] Start on improved mappings service --- .../fabricmc/loom/LoomGradleExtension.java | 6 +- .../configuration/CompileConfiguration.java | 9 +-- .../loom/configuration/ConfigContext.java | 10 +++ .../configuration/LoomDependencyManager.java | 4 +- .../decompile/DecompileConfiguration.java | 9 +-- .../SingleJarDecompileConfiguration.java | 6 +- .../SplitDecompileConfiguration.java | 6 +- .../loom/configuration/mods/ModProcessor.java | 6 +- .../IntermediaryMappingsProvider.java | 2 +- ...derImpl.java => MappingConfiguration.java} | 69 +++++-------------- .../providers/mappings/MappingsProvider.java | 34 --------- .../providers/mappings/MappingsService.java | 31 +++++++++ .../minecraft/SignatureFixerApplyVisitor.java | 11 +-- .../AbstractMappedMinecraftProvider.java | 10 +-- .../mapped/NamedMinecraftProvider.java | 2 +- .../ProcessedNamedMinecraftProvider.java | 2 +- .../extension/LoomGradleExtensionApiImpl.java | 2 +- .../extension/LoomGradleExtensionImpl.java | 12 ++-- .../loom/task/GenerateSourcesTask.java | 2 +- .../loom/task/MigrateMappingsTask.java | 9 +-- .../loom/task/service/MappingsService.java | 8 +-- .../fabricmc/loom/util/SourceRemapper.java | 13 ++-- .../loom/util/TinyRemapperHelper.java | 11 +-- 23 files changed, 128 insertions(+), 146 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/ConfigContext.java rename src/main/java/net/fabricmc/loom/configuration/providers/mappings/{MappingsProviderImpl.java => MappingConfiguration.java} (82%) delete mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 33a1282f1..8d93e47bf 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -39,7 +39,7 @@ import net.fabricmc.loom.configuration.InstallerData; import net.fabricmc.loom.configuration.LoomDependencyManager; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; @@ -72,9 +72,9 @@ static LoomGradleExtension get(Project project) { void setMinecraftProvider(MinecraftProvider minecraftProvider); - MappingsProviderImpl getMappingsProvider(); + MappingConfiguration getMappingConfiguration(); - void setMappingsProvider(MappingsProviderImpl mappingsProvider); + void setMappingConfiguration(MappingConfiguration mappingConfiguration); NamedMinecraftProvider getNamedMinecraftProvider(); diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index b4fc5ff22..6e0712bf1 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -32,6 +32,8 @@ import java.util.List; import java.util.function.Consumer; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; + import org.gradle.api.NamedDomainObjectProvider; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; @@ -52,7 +54,6 @@ import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.processors.ModJavadocProcessor; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; @@ -191,9 +192,9 @@ private static synchronized void setupMinecraft(Project project, SharedServiceMa minecraftProvider.provide(); final DependencyInfo mappingsDep = DependencyInfo.create(project, Constants.Configurations.MAPPINGS); - final MappingsProviderImpl mappingsProvider = MappingsProviderImpl.getInstance(serviceManager, project, mappingsDep, minecraftProvider); - extension.setMappingsProvider(mappingsProvider); - mappingsProvider.applyToProject(project, mappingsDep); + final MappingConfiguration mappingConfiguration = MappingConfiguration.create(project, serviceManager, mappingsDep, minecraftProvider); + extension.setMappingConfiguration(mappingConfiguration); + mappingConfiguration.applyToProject(project, mappingsDep); // Provide the remapped mc jars final IntermediaryMinecraftProvider intermediaryMinecraftProvider = jarConfiguration.getIntermediaryMinecraftProviderBiFunction().apply(project, minecraftProvider); diff --git a/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java b/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java new file mode 100644 index 000000000..5c9b9898f --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java @@ -0,0 +1,10 @@ +package net.fabricmc.loom.configuration; + +import net.fabricmc.loom.util.service.SharedServiceManager; + +import org.gradle.api.Project; + +public interface ConfigContext { + Project project(); + SharedServiceManager serviceManager(); +} diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index 3ce043aec..12eec24ed 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -76,8 +76,8 @@ public void handleDependencies(Project project, SharedServiceManager serviceMana } } - SourceRemapper sourceRemapper = new SourceRemapper(project, true); - String mappingsIdentifier = extension.getMappingsProvider().mappingsIdentifier(); + SourceRemapper sourceRemapper = new SourceRemapper(project, serviceManager, true); + String mappingsIdentifier = extension.getMappingConfiguration().mappingsIdentifier(); ModConfigurationRemapper.supplyModConfigurations(project, serviceManager, mappingsIdentifier, extension, sourceRemapper); diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java index 17718e812..645fb5bc5 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java @@ -26,11 +26,12 @@ import java.io.File; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; + import org.gradle.api.Project; import org.gradle.api.tasks.TaskProvider; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.task.UnpickJarTask; @@ -38,20 +39,20 @@ public abstract class DecompileConfiguration protected final Project project; protected final T minecraftProvider; protected final LoomGradleExtension extension; - protected final MappingsProviderImpl mappingsProvider; + protected final MappingConfiguration mappingConfiguration; public DecompileConfiguration(Project project, T minecraftProvider) { this.project = project; this.minecraftProvider = minecraftProvider; this.extension = LoomGradleExtension.get(project); - this.mappingsProvider = extension.getMappingsProvider(); + this.mappingConfiguration = extension.getMappingConfiguration(); } public abstract void afterEvaluation(); protected final TaskProvider createUnpickJarTask(String name, File inputJar, File outputJar) { return project.getTasks().register(name, UnpickJarTask.class, unpickJarTask -> { - unpickJarTask.getUnpickDefinitions().set(mappingsProvider.getUnpickDefinitionsFile()); + unpickJarTask.getUnpickDefinitions().set(mappingConfiguration.getUnpickDefinitionsFile()); unpickJarTask.getInputJar().set(inputJar); unpickJarTask.getOutputJar().set(outputJar); }); diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java index b5f2dc323..07eace63e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java @@ -49,8 +49,8 @@ public final void afterEvaluation() { File mappedJar = namedJar; - if (mappingsProvider.hasUnpickDefinitions()) { - File outputJar = new File(extension.getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-unpicked.jar"); + if (mappingConfiguration.hasUnpickDefinitions()) { + File outputJar = new File(extension.getMappingConfiguration().mappingsWorkingDir().toFile(), "minecraft-unpicked.jar"); createUnpickJarTask("unpickJar", namedJar, outputJar); mappedJar = outputJar; @@ -70,7 +70,7 @@ public final void afterEvaluation() { task.setDescription("Decompile minecraft using %s.".formatted(decompilerName)); task.setGroup(Constants.TaskGroup.FABRIC); - if (mappingsProvider.hasUnpickDefinitions()) { + if (mappingConfiguration.hasUnpickDefinitions()) { task.dependsOn(project.getTasks().named("unpickJar")); } }); diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java index deb2982d3..280db04ba 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java @@ -50,9 +50,9 @@ public void afterEvaluation() { TaskProvider unpickCommonJar = null; TaskProvider unpickClientOnlyJar = null; - if (mappingsProvider.hasUnpickDefinitions()) { - commonJarToDecompile = new File(extension.getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-common-unpicked.jar"); - clientOnlyJarToDecompile = new File(extension.getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-clientonly-unpicked.jar"); + if (mappingConfiguration.hasUnpickDefinitions()) { + commonJarToDecompile = new File(extension.getMappingConfiguration().mappingsWorkingDir().toFile(), "minecraft-common-unpicked.jar"); + clientOnlyJarToDecompile = new File(extension.getMappingConfiguration().mappingsWorkingDir().toFile(), "minecraft-clientonly-unpicked.jar"); unpickCommonJar = createUnpickJarTask("unpickCommonJar", minecraftProvider.getCommonJar().toFile(), commonJarToDecompile); unpickClientOnlyJar = createUnpickJarTask("unpickClientOnlyJar", minecraftProvider.getClientOnlyJar().toFile(), clientOnlyJarToDecompile); diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index f79d8553b..f5fe6fc37 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -45,7 +45,7 @@ import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.mods.dependency.ModDependency; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.task.RemapJarTask; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.Pair; @@ -96,12 +96,12 @@ private void stripNestedJars(Path path) { private void remapJars(List remapList) throws IOException { final LoomGradleExtension extension = LoomGradleExtension.get(project); - final MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); + final MappingConfiguration mappingConfiguration = extension.getMappingConfiguration(); Path[] mcDeps = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES).getFiles() .stream().map(File::toPath).toArray(Path[]::new); TinyRemapper.Builder builder = TinyRemapper.newRemapper() - .withMappings(TinyRemapperHelper.create(mappingsProvider.getMappings(), fromM, toM, false)) + .withMappings(TinyRemapperHelper.create(mappingConfiguration.getMappingsService(serviceManager).getMappingTree(), fromM, toM, false)) .renameInvalidLocals(false); final KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project); 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 d7aeb51f2..53ef5888b 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 @@ -63,7 +63,7 @@ public void provide(Path tinyMappings) throws IOException { .defaultCache() .downloadPath(intermediaryJarPath); - MappingsProviderImpl.extractMappings(intermediaryJarPath, tinyMappings); + MappingConfiguration.extractMappings(intermediaryJarPath, tinyMappings); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java similarity index 82% rename from src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java rename to src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java index 11966c237..aad487646 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java @@ -38,9 +38,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.function.Supplier; -import com.google.common.base.Suppliers; import com.google.gson.JsonObject; import org.apache.tools.ant.util.StringUtils; import org.gradle.api.Project; @@ -58,18 +56,15 @@ import net.fabricmc.loom.util.DeletingFileVisitor; import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.ZipUtils; -import net.fabricmc.loom.util.service.SharedService; import net.fabricmc.loom.util.service.SharedServiceManager; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.format.MappingFormat; -import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.stitch.Command; import net.fabricmc.stitch.commands.CommandProposeFieldNames; -public class MappingsProviderImpl implements MappingsProvider, SharedService { - private static final Logger LOGGER = LoggerFactory.getLogger(MappingsProviderImpl.class); +public class MappingConfiguration { + private static final Logger LOGGER = LoggerFactory.getLogger(MappingConfiguration.class); - private Supplier mappingTree; public final String mappingsIdentifier; private final Path mappingsWorkingDir; @@ -84,9 +79,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { private UnpickMetadata unpickMetadata; private Map signatureFixes; - private final Supplier intermediaryService; - - private MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, Supplier intermediaryService) { + private MappingConfiguration(String mappingsIdentifier, Path mappingsWorkingDir) { this.mappingsIdentifier = mappingsIdentifier; this.mappingsWorkingDir = mappingsWorkingDir; @@ -94,22 +87,9 @@ private MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, this.tinyMappings = mappingsWorkingDir.resolve("mappings.tiny"); this.tinyMappingsJar = mappingsWorkingDir.resolve("mappings.jar"); this.unpickDefinitions = mappingsWorkingDir.resolve("mappings.unpick"); - - this.intermediaryService = intermediaryService; - } - - public static synchronized MappingsProviderImpl getInstance(SharedServiceManager sharedServiceManager, Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) { - return sharedServiceManager.getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> { - Supplier intermediaryService = Suppliers.memoize(() -> IntermediateMappingsService.getInstance(sharedServiceManager, project, minecraftProvider)); - return create(dependency, minecraftProvider, intermediaryService); - }); } - public MemoryMappingTree getMappings() throws IOException { - return Objects.requireNonNull(mappingTree, "Cannot get mappings before they have been read").get(); - } - - private static MappingsProviderImpl create(DependencyInfo dependency, MinecraftProvider minecraftProvider, Supplier intermediaryService) { + public static MappingConfiguration create(Project project, SharedServiceManager serviceManager, DependencyInfo dependency, MinecraftProvider minecraftProvider) { final String version = dependency.getResolvedVersion(); final Path inputJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not resolve mappings: " + dependency)).toPath(); final String mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged"); @@ -124,10 +104,10 @@ private static MappingsProviderImpl create(DependencyInfo dependency, MinecraftP final String mappingsIdentifier = createMappingsIdentifier(mappingsName, version, getMappingsClassifier(dependency, jarInfo.v2()), minecraftProvider.minecraftVersion()); final Path workingDir = minecraftProvider.dir(mappingsIdentifier).toPath(); - var mappingProvider = new MappingsProviderImpl(mappingsIdentifier, workingDir, intermediaryService); + var mappingProvider = new MappingConfiguration(mappingsIdentifier, workingDir); try { - mappingProvider.setup(minecraftProvider, inputJar); + mappingProvider.setup(project, serviceManager, minecraftProvider, inputJar); } catch (IOException e) { cleanWorkingDirectory(workingDir); throw new UncheckedIOException("Failed to setup mappings: " + dependency.getDepString(), e); @@ -136,13 +116,17 @@ private static MappingsProviderImpl create(DependencyInfo dependency, MinecraftP return mappingProvider; } - private void setup(MinecraftProvider minecraftProvider, Path inputJar) throws IOException { + public MappingsService getMappingsService(SharedServiceManager serviceManager) { + return MappingsService.create(serviceManager, Objects.requireNonNull(tinyMappings)); + } + + private void setup(Project project, SharedServiceManager serviceManager, MinecraftProvider minecraftProvider, Path inputJar) throws IOException { if (minecraftProvider.refreshDeps()) { cleanWorkingDirectory(mappingsWorkingDir); } if (Files.notExists(tinyMappings) || minecraftProvider.refreshDeps()) { - storeMappings(minecraftProvider, inputJar); + storeMappings(project, serviceManager, minecraftProvider, inputJar); } else { try (FileSystem fileSystem = FileSystems.newFileSystem(inputJar, (ClassLoader) null)) { extractExtras(fileSystem); @@ -153,8 +137,6 @@ private void setup(MinecraftProvider minecraftProvider, Path inputJar) throws IO Files.deleteIfExists(tinyMappingsJar); ZipUtils.add(tinyMappingsJar, "mappings/mappings.tiny", Files.readAllBytes(tinyMappings)); } - - mappingTree = Suppliers.memoize(this::readMappings); } public void applyToProject(Project project, DependencyInfo dependency) { @@ -182,7 +164,7 @@ private static String getMappingsClassifier(DependencyInfo dependency, boolean i return isV2 ? "-v2" : ""; } - private void storeMappings(MinecraftProvider minecraftProvider, Path inputJar) throws IOException { + private void storeMappings(Project project, SharedServiceManager serviceManager, MinecraftProvider minecraftProvider, Path inputJar) throws IOException { LOGGER.info(":extracting " + inputJar.getFileName()); try (FileSystemUtil.Delegate delegate = FileSystemUtil.getJarFileSystem(inputJar)) { @@ -192,7 +174,9 @@ private void storeMappings(MinecraftProvider minecraftProvider, Path inputJar) t if (areMappingsV2(baseTinyMappings)) { // These are unmerged v2 mappings - MappingsMerger.mergeAndSaveMappings(baseTinyMappings, tinyMappings, intermediaryService.get()); + IntermediateMappingsService intermediateMappingsService = IntermediateMappingsService.getInstance(serviceManager, project, minecraftProvider); + + MappingsMerger.mergeAndSaveMappings(baseTinyMappings, tinyMappings, intermediateMappingsService); } else { final List minecraftJars = minecraftProvider.getMinecraftJars(); @@ -207,16 +191,6 @@ private void storeMappings(MinecraftProvider minecraftProvider, Path inputJar) t } } - private MemoryMappingTree readMappings() { - try { - MemoryMappingTree mappingTree = new MemoryMappingTree(); - MappingReader.read(tinyMappings, mappingTree); - return mappingTree; - } catch (IOException e) { - throw new UncheckedIOException("Failed to read mappings", e); - } - } - private static boolean areMappingsV2(Path path) throws IOException { try (BufferedReader reader = Files.newBufferedReader(path)) { return MappingReader.detectFormat(reader) == MappingFormat.TINY_2; @@ -326,16 +300,10 @@ private static void cleanWorkingDirectory(Path mappingsWorkingDir) { } } - @Override public Path mappingsWorkingDir() { return mappingsWorkingDir; } - @Override - public File intermediaryTinyFile() { - return intermediaryService.get().getIntermediaryTiny().toFile(); - } - private static String createMappingsIdentifier(String mappingsName, String version, String classifier, String minecraftVersion) { // mappingsName . mcVersion . version classifier // Example: net.fabricmc.yarn . 1_16_5 . 1.16.5+build.5 -v2 @@ -365,9 +333,4 @@ public String getBuildServiceName(String name, String from, String to) { public record UnpickMetadata(String unpickGroup, String unpickVersion) { } - - @Override - public void close() throws IOException { - mappingTree = null; - } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java deleted file mode 100644 index 18b8ee89f..000000000 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2016-2021 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.File; -import java.nio.file.Path; - -public interface MappingsProvider { - Path mappingsWorkingDir(); - - File intermediaryTinyFile(); -} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java new file mode 100644 index 000000000..02c923988 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java @@ -0,0 +1,31 @@ +package net.fabricmc.loom.configuration.providers.mappings; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; + +import net.fabricmc.loom.util.service.SharedService; +import net.fabricmc.loom.util.service.SharedServiceManager; +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +public final class MappingsService implements SharedService { + private final MemoryMappingTree mappingTree; + + public MappingsService(Path tinyMappings) { + try { + this.mappingTree = new MemoryMappingTree(); + MappingReader.read(tinyMappings, mappingTree); + } catch (IOException e) { + throw new UncheckedIOException("Failed to read mappings", e); + } + } + + public static synchronized MappingsService create(SharedServiceManager serviceManager, Path tinyMappings) { + return serviceManager.getOrCreateService("MappingsService:" + tinyMappings.toAbsolutePath(), () -> new MappingsService(tinyMappings)); + } + + public MemoryMappingTree getMappingTree() { + return mappingTree; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java index 0ebff3467..08a6e7c3c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java @@ -29,12 +29,13 @@ import java.util.HashMap; import java.util.Map; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; + import org.gradle.api.Project; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.commons.Remapper; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.tinyremapper.TinyRemapper; @@ -55,15 +56,15 @@ public void visit(int version, int access, String name, String signature, String }; } - public static Map getRemappedSignatures(boolean toIntermediary, MappingsProviderImpl mappingsProvider, Project project, String targetNamespace) throws IOException { - if (mappingsProvider.getSignatureFixes() == null) { + public static Map getRemappedSignatures(boolean toIntermediary, MappingConfiguration mappingConfiguration, Project project, String targetNamespace) throws IOException { + if (mappingConfiguration.getSignatureFixes() == null) { // No fixes return Collections.emptyMap(); } if (toIntermediary) { // No need to remap, as these are already intermediary - return mappingsProvider.getSignatureFixes(); + return mappingConfiguration.getSignatureFixes(); } // Remap the sig fixes from intermediary to the target namespace @@ -72,7 +73,7 @@ public static Map getRemappedSignatures(boolean toIntermediary, final Remapper sigAsmRemapper = sigTinyRemapper.getEnvironment().getRemapper(); // Remap the class names and the signatures using a new tiny remapper instance. - for (Map.Entry entry : mappingsProvider.getSignatureFixes().entrySet()) { + for (Map.Entry entry : mappingConfiguration.getSignatureFixes().entrySet()) { remapped.put( sigAsmRemapper.map(entry.getKey()), sigAsmRemapper.mapSignature(entry.getValue(), false) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java index d74b8c876..1b2c17541 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java @@ -35,7 +35,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; import net.fabricmc.loom.configuration.providers.minecraft.SignatureFixerApplyVisitor; @@ -102,7 +102,7 @@ protected String getName(String name) { } protected String getDependencyNotation(String name) { - return "net.minecraft:%s:%s/%s".formatted(getName(name), extension.getMinecraftProvider().minecraftVersion(), extension.getMappingsProvider().mappingsIdentifier()); + return "net.minecraft:%s:%s/%s".formatted(getName(name), extension.getMinecraftProvider().minecraftVersion(), extension.getMappingConfiguration().mappingsIdentifier()); } private boolean areOutputsValid(List remappedJars) { @@ -124,13 +124,13 @@ private void remapInputs(List remappedJars) throws IOException { } private void remapJar(RemappedJars remappedJars) throws IOException { - final MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); + final MappingConfiguration mappingConfiguration = extension.getMappingConfiguration(); final String fromM = remappedJars.sourceNamespace().toString(); final String toM = getTargetNamespace().toString(); Files.deleteIfExists(remappedJars.outputJar()); - final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingsProvider, project, toM); + final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, project, toM); TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(project, fromM, toM, true, (builder) -> { builder.extraPostApplyVisitor(new SignatureFixerApplyVisitor(remappedSignatures)); configureRemapper(remappedJars, builder); @@ -147,7 +147,7 @@ private void remapJar(RemappedJars remappedJars) throws IOException { remapper.readInputs(remappedJars.inputJar()); remapper.apply(outputConsumer); } catch (Exception e) { - throw new RuntimeException("Failed to remap JAR " + remappedJars.inputJar() + " with mappings from " + mappingsProvider.tinyMappings, e); + throw new RuntimeException("Failed to remap JAR " + remappedJars.inputJar() + " with mappings from " + mappingConfiguration.tinyMappings, e); } finally { remapper.finish(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java index a9643debf..1e5f80b52 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java @@ -45,7 +45,7 @@ public NamedMinecraftProvider(Project project, M minecraftProvider) { @Override protected Path getDirectory() { - return extension.getMappingsProvider().mappingsWorkingDir(); + return extension.getMappingConfiguration().mappingsWorkingDir(); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java index 4e479b428..8f8e3e0e8 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java @@ -59,7 +59,7 @@ public ProcessedNamedMinecraftProvider(P parentMinecraftProvide, MinecraftJarPro final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); this.projectMappedDir = extension.getFiles().getRootProjectPersistentCache().toPath() .resolve(getMinecraftProvider().minecraftVersion()) - .resolve(extension.getMappingsProvider().mappingsIdentifier()); + .resolve(extension.getMappingConfiguration().mappingsIdentifier()); } @Override diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index af0254392..fd81d2853 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -275,7 +275,7 @@ public void setIntermediateMappingsProv @Override public File getMappingsFile() { - return LoomGradleExtension.get(getProject()).getMappingsProvider().tinyMappings.toFile(); + return LoomGradleExtension.get(getProject()).getMappingConfiguration().tinyMappings.toFile(); } @Override diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index a54882a6d..b56d06d0a 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -44,7 +44,7 @@ import net.fabricmc.loom.configuration.LoomDependencyManager; import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; import net.fabricmc.loom.configuration.providers.mappings.IntermediaryMappingsProvider; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; @@ -63,7 +63,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen private LoomDependencyManager dependencyManager; private MinecraftProvider minecraftProvider; - private MappingsProviderImpl mappingsProvider; + private MappingConfiguration mappingConfiguration; private NamedMinecraftProvider namedMinecraftProvider; private IntermediaryMinecraftProvider intermediaryMinecraftProvider; private InstallerData installerData; @@ -124,13 +124,13 @@ public void setMinecraftProvider(MinecraftProvider minecraftProvider) { } @Override - public MappingsProviderImpl getMappingsProvider() { - return Objects.requireNonNull(mappingsProvider, "Cannot get MappingsProvider before it has been setup"); + public MappingConfiguration getMappingConfiguration() { + return Objects.requireNonNull(mappingConfiguration, "Cannot get MappingsProvider before it has been setup"); } @Override - public void setMappingsProvider(MappingsProviderImpl mappingsProvider) { - this.mappingsProvider = mappingsProvider; + public void setMappingConfiguration(MappingConfiguration mappingConfiguration) { + this.mappingConfiguration = mappingConfiguration; } @Override diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index b2c1fe428..bca591890 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -319,7 +319,7 @@ private File getMappedJarFileWithSuffix(String suffix) { } private Path getMappings() { - Path inputMappings = getExtension().getMappingsProvider().tinyMappings; + Path inputMappings = getExtension().getMappingConfiguration().tinyMappings; MemoryMappingTree mappingTree = new MemoryMappingTree(); diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index f2b830bed..64e556266 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -52,9 +52,10 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.SourceRemapper; +import net.fabricmc.loom.util.service.ScopedSharedServiceManager; import net.fabricmc.lorenztiny.TinyMappingsJoiner; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -105,10 +106,10 @@ public void doTask() throws Throwable { Files.createDirectories(outputDir); File mappings = loadMappings(); - MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); + MappingConfiguration mappingConfiguration = extension.getMappingConfiguration(); - try { - MemoryMappingTree currentMappings = mappingsProvider.getMappings(); + try (var serviceManager = new ScopedSharedServiceManager()) { + MemoryMappingTree currentMappings = mappingConfiguration.getMappingsService(serviceManager).getMappingTree(); MemoryMappingTree targetMappings = getMappings(mappings); migrateMappings(project, extension, inputDir, outputDir, currentMappings, targetMappings); project.getLogger().lifecycle(":remapped project written to " + outputDir.toAbsolutePath()); diff --git a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java index 16a436bca..97cadac19 100644 --- a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java +++ b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java @@ -31,7 +31,7 @@ import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.loom.util.service.SharedService; import net.fabricmc.loom.util.service.SharedServiceManager; @@ -49,10 +49,10 @@ public static synchronized MappingsService create(SharedServiceManager sharedSer } public static MappingsService createDefault(Project project, SharedServiceManager serviceManager, String from, String to) { - final MappingsProviderImpl mappingsProvider = LoomGradleExtension.get(project).getMappingsProvider(); + final MappingConfiguration mappingConfiguration = LoomGradleExtension.get(project).getMappingConfiguration(); - final String name = mappingsProvider.getBuildServiceName("mappingsProvider", from, to); - return MappingsService.create(serviceManager, name, mappingsProvider.tinyMappings, from, to, false); + final String name = mappingConfiguration.getBuildServiceName("mappingsProvider", from, to); + return MappingsService.create(serviceManager, name, mappingConfiguration.tinyMappings, from, to, false); } private final Options options; diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index 4c069aea7..8fed7ac02 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -33,6 +33,10 @@ import java.util.Set; import java.util.function.Consumer; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; + +import net.fabricmc.loom.util.service.SharedServiceManager; + import org.cadixdev.lorenz.MappingSet; import org.cadixdev.mercury.Mercury; import org.cadixdev.mercury.remapper.MercuryRemapper; @@ -45,19 +49,20 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.lorenztiny.TinyMappingsReader; import net.fabricmc.mappingio.tree.MemoryMappingTree; public class SourceRemapper { private final Project project; + private final SharedServiceManager serviceManager; private final boolean toNamed; private final List> remapTasks = new ArrayList<>(); private Mercury mercury; - public SourceRemapper(Project project, boolean toNamed) { + public SourceRemapper(Project project, SharedServiceManager serviceManager, boolean toNamed) { this.project = project; + this.serviceManager = serviceManager; this.toNamed = toNamed; } @@ -158,11 +163,11 @@ private Mercury getMercuryInstance() { } LoomGradleExtension extension = LoomGradleExtension.get(project); - MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); + MappingConfiguration mappingConfiguration = extension.getMappingConfiguration(); MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> { try { - MemoryMappingTree m = mappingsProvider.getMappings(); + MemoryMappingTree m = mappingConfiguration.getMappingsService(serviceManager).getMappingTree(); project.getLogger().info(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings"); return new TinyMappingsReader(m, toNamed ? MappingsNamespace.INTERMEDIARY.toString() : MappingsNamespace.NAMED.toString(), toNamed ? MappingsNamespace.NAMED.toString() : MappingsNamespace.INTERMEDIARY.toString()).read(); } catch (Exception e) { diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java index de9c82e83..4f0bdfaca 100644 --- a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java +++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java @@ -32,6 +32,9 @@ import java.util.regex.Pattern; import com.google.common.collect.ImmutableMap; + +import net.fabricmc.loom.util.service.SharedServiceManager; + import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; @@ -60,13 +63,13 @@ public final class TinyRemapperHelper { private TinyRemapperHelper() { } - public static TinyRemapper getTinyRemapper(Project project, String fromM, String toM) throws IOException { - return getTinyRemapper(project, fromM, toM, false, (builder) -> { }); + public static TinyRemapper getTinyRemapper(Project project, SharedServiceManager serviceManager, String fromM, String toM) throws IOException { + return getTinyRemapper(project, serviceManager, fromM, toM, false, (builder) -> { }); } - public static TinyRemapper getTinyRemapper(Project project, String fromM, String toM, boolean fixRecords, Consumer builderConsumer) throws IOException { + public static TinyRemapper getTinyRemapper(Project project, SharedServiceManager serviceManager, String fromM, String toM, boolean fixRecords, Consumer builderConsumer) throws IOException { LoomGradleExtension extension = LoomGradleExtension.get(project); - MemoryMappingTree mappingTree = extension.getMappingsProvider().getMappings(); + MemoryMappingTree mappingTree = extension.getMappingConfiguration().getMappingsService(serviceManager).getMappingTree(); if (fixRecords && !mappingTree.getSrcNamespace().equals(fromM)) { throw new IllegalStateException("Mappings src namespace must match remap src namespace"); From 47987b2aa342f9a9fa6c89565ef073d3f89a7b28 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Fri, 7 Oct 2022 22:03:16 +0100 Subject: [PATCH 09/13] Cleanup configuration related code by passing ConfigContext --- .../mixin/AnnotationProcessorInvoker.java | 4 +- .../configuration/CompileConfiguration.java | 32 ++++++----- .../loom/configuration/ConfigContext.java | 30 +++++++++- .../loom/configuration/ConfigContextImpl.java | 33 +++++++++++ .../TransitiveAccessWidenerJarProcessor.java | 7 ++- .../decompile/DecompileConfiguration.java | 10 ++-- .../SingleJarDecompileConfiguration.java | 7 +-- .../SplitDecompileConfiguration.java | 6 +- .../InterfaceInjectionProcessor.java | 7 ++- .../processors/ModJavadocProcessor.java | 11 ---- .../mappings/MappingConfiguration.java | 4 +- .../providers/mappings/MappingsService.java | 31 ----------- .../mappings/TinyMappingsService.java | 55 +++++++++++++++++++ .../minecraft/MergedMinecraftProvider.java | 7 +-- .../minecraft/MinecraftJarConfiguration.java | 35 ++++++------ .../minecraft/MinecraftProvider.java | 5 +- .../minecraft/SignatureFixerApplyVisitor.java | 8 +-- .../minecraft/SingleJarMinecraftProvider.java | 15 +++-- .../minecraft/SplitMinecraftProvider.java | 7 +-- .../AbstractMappedMinecraftProvider.java | 21 ++++--- .../mapped/IntermediaryMinecraftProvider.java | 27 +++++---- .../mapped/NamedMinecraftProvider.java | 27 +++++---- .../ProcessedNamedMinecraftProvider.java | 2 +- .../task/service/SourceRemapperService.java | 2 +- .../task/service/TinyRemapperService.java | 2 +- .../fabricmc/loom/util/SourceRemapper.java | 6 +- .../loom/util/TinyRemapperHelper.java | 4 +- 27 files changed, 243 insertions(+), 162 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java delete mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java 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 7c10f6950..7e3c38157 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -93,7 +93,7 @@ private void passMixinArguments(T task, SourceSet sourceSet) { LoomGradleExtension loom = LoomGradleExtension.get(project); String refmapName = Objects.requireNonNull(MixinExtension.getMixinInformationContainer(sourceSet)).refmapNameProvider().get(); Map args = new HashMap<>() {{ - put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.toFile().getCanonicalPath()); + put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingConfiguration().tinyMappings.toFile().getCanonicalPath()); put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, getMixinMappingsForSourceSet(project, sourceSet).getCanonicalPath()); put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName)); put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:" + loom.getMixin().getRefmapTargetNamespace().get()); @@ -162,6 +162,6 @@ private static void checkPattern(String input, Pattern pattern) { public static File getMixinMappingsForSourceSet(Project project, SourceSet sourceSet) { final LoomGradleExtension extension = LoomGradleExtension.get(project); - return new File(extension.getFiles().getProjectBuildCache(), "mixin-map-" + extension.getMappingsProvider().mappingsIdentifier() + "." + sourceSet.getName() + ".tiny"); + return new File(extension.getFiles().getProjectBuildCache(), "mixin-map-" + extension.getMappingConfiguration().mappingsIdentifier() + "." + sourceSet.getName() + ".tiny"); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 6e0712bf1..49413b907 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -32,8 +32,6 @@ import java.util.List; import java.util.function.Consumer; -import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; - import org.gradle.api.NamedDomainObjectProvider; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; @@ -54,6 +52,7 @@ import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.processors.ModJavadocProcessor; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; @@ -131,6 +130,8 @@ public static void configureCompile(Project project) { }); afterEvaluationWithService(project, (serviceManager) -> { + final ConfigContext configContext = new ConfigContextImpl(project, serviceManager, extension); + MinecraftSourceSets.get(project).afterEvaluate(project); final boolean previousRefreshDeps = extension.refreshDeps(); @@ -141,7 +142,7 @@ public static void configureCompile(Project project) { } try { - setupMinecraft(project, serviceManager); + setupMinecraft(configContext); } catch (Exception e) { throw ExceptionUtil.createDescriptiveWrapper(RuntimeException::new, "Failed to setup Minecraft", e); } @@ -159,7 +160,7 @@ public static void configureCompile(Project project) { setupMixinAp(project, mixin); } - configureDecompileTasks(project); + configureDecompileTasks(configContext); }); finalizedBy(project, "idea", "genIdeaWorkspace"); @@ -182,23 +183,24 @@ public static void configureCompile(Project project) { } // This is not thread safe across projects synchronize it here just to be sure, might be possible to move this further down, but for now this will do. - private static synchronized void setupMinecraft(Project project, SharedServiceManager serviceManager) throws Exception { - final LoomGradleExtension extension = LoomGradleExtension.get(project); + private static synchronized void setupMinecraft(ConfigContext configContext) throws Exception { + final Project project = configContext.project(); + final LoomGradleExtension extension = configContext.extension(); final MinecraftJarConfiguration jarConfiguration = extension.getMinecraftJarConfiguration().get(); // Provide the vanilla mc jars -- TODO share across projects. - final MinecraftProvider minecraftProvider = jarConfiguration.getMinecraftProviderFunction().apply(project); + final MinecraftProvider minecraftProvider = jarConfiguration.getMinecraftProviderFunction().apply(configContext); extension.setMinecraftProvider(minecraftProvider); minecraftProvider.provide(); final DependencyInfo mappingsDep = DependencyInfo.create(project, Constants.Configurations.MAPPINGS); - final MappingConfiguration mappingConfiguration = MappingConfiguration.create(project, serviceManager, mappingsDep, minecraftProvider); + final MappingConfiguration mappingConfiguration = MappingConfiguration.create(project, configContext.serviceManager(), mappingsDep, minecraftProvider); extension.setMappingConfiguration(mappingConfiguration); mappingConfiguration.applyToProject(project, mappingsDep); // Provide the remapped mc jars - final IntermediaryMinecraftProvider intermediaryMinecraftProvider = jarConfiguration.getIntermediaryMinecraftProviderBiFunction().apply(project, minecraftProvider); - NamedMinecraftProvider namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(project, minecraftProvider); + final IntermediaryMinecraftProvider intermediaryMinecraftProvider = jarConfiguration.getIntermediaryMinecraftProviderBiFunction().apply(configContext, minecraftProvider); + NamedMinecraftProvider namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(configContext, minecraftProvider); registerGameProcessors(project); MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(project); @@ -238,7 +240,9 @@ private static void registerGameProcessors(Project project) { } } - extension.addMinecraftJarProcessor(ModJavadocProcessor.class, "fabric-loom:mod-javadoc"); + if (extension.getEnableModProvidedJavadoc().get()) { + extension.addMinecraftJarProcessor(ModJavadocProcessor.class, "fabric-loom:mod-javadoc"); + } } private static void setupMixinAp(Project project, MixinExtension mixin) { @@ -269,11 +273,11 @@ private static void setupMixinAp(Project project, MixinExtension mixin) { } } - private static void configureDecompileTasks(Project project) { - final LoomGradleExtension extension = LoomGradleExtension.get(project); + private static void configureDecompileTasks(ConfigContext configContext) { + final LoomGradleExtension extension = configContext.extension(); extension.getMinecraftJarConfiguration().get().getDecompileConfigurationBiFunction() - .apply(project, extension.getNamedMinecraftProvider()).afterEvaluation(); + .apply(configContext, extension.getNamedMinecraftProvider()).afterEvaluation(); } private static Path getLockFile(Project project) { diff --git a/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java b/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java index 5c9b9898f..470ac414d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java +++ b/src/main/java/net/fabricmc/loom/configuration/ConfigContext.java @@ -1,10 +1,36 @@ -package net.fabricmc.loom.configuration; +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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. + */ -import net.fabricmc.loom.util.service.SharedServiceManager; +package net.fabricmc.loom.configuration; import org.gradle.api.Project; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.service.SharedServiceManager; + public interface ConfigContext { Project project(); SharedServiceManager serviceManager(); + LoomGradleExtension extension(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java new file mode 100644 index 000000000..94a4eee4a --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/ConfigContextImpl.java @@ -0,0 +1,33 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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; + +import org.gradle.api.Project; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.service.SharedServiceManager; + +public record ConfigContextImpl(Project project, SharedServiceManager serviceManager, LoomGradleExtension extension) implements ConfigContext { +} diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java index 707158383..3da420b54 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java @@ -166,7 +166,12 @@ private AccessWidener createAccessWidener() { private TinyRemapper createTinyRemapper() { try { - TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, "intermediary", "named"); + // TODO service manager, via new processor api + if (true) { + throw new UnsupportedOperationException("ToDO"); + } + + TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, null, "intermediary", "named"); tinyRemapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(project)); diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java index 645fb5bc5..f535d0931 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/DecompileConfiguration.java @@ -26,12 +26,12 @@ import java.io.File; -import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; - import org.gradle.api.Project; import org.gradle.api.tasks.TaskProvider; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.configuration.ConfigContext; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.task.UnpickJarTask; @@ -41,10 +41,10 @@ public abstract class DecompileConfiguration protected final LoomGradleExtension extension; protected final MappingConfiguration mappingConfiguration; - public DecompileConfiguration(Project project, T minecraftProvider) { - this.project = project; + public DecompileConfiguration(ConfigContext configContext, T minecraftProvider) { + this.project = configContext.project(); this.minecraftProvider = minecraftProvider; - this.extension = LoomGradleExtension.get(project); + this.extension = configContext.extension(); this.mappingConfiguration = extension.getMappingConfiguration(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java index 07eace63e..6fa25b5c5 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java @@ -28,16 +28,15 @@ import java.nio.file.Path; import java.util.List; -import org.gradle.api.Project; - import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.task.GenerateSourcesTask; import net.fabricmc.loom.util.Constants; public class SingleJarDecompileConfiguration extends DecompileConfiguration { - public SingleJarDecompileConfiguration(Project project, MappedMinecraftProvider minecraftProvider) { - super(project, minecraftProvider); + public SingleJarDecompileConfiguration(ConfigContext configContext, MappedMinecraftProvider minecraftProvider) { + super(configContext, minecraftProvider); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java index 280db04ba..0dd69ff21 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/SplitDecompileConfiguration.java @@ -27,19 +27,19 @@ import java.io.File; import org.gradle.api.Action; -import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.tasks.TaskProvider; import net.fabricmc.loom.api.decompilers.DecompilerOptions; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.task.GenerateSourcesTask; import net.fabricmc.loom.task.UnpickJarTask; import net.fabricmc.loom.util.Constants; public final class SplitDecompileConfiguration extends DecompileConfiguration { - public SplitDecompileConfiguration(Project project, MappedMinecraftProvider.Split minecraftProvider) { - super(project, minecraftProvider); + public SplitDecompileConfiguration(ConfigContext configContext, MappedMinecraftProvider.Split minecraftProvider) { + super(configContext, minecraftProvider); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java index 15ea74c8d..e23ebd127 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java @@ -329,7 +329,12 @@ public void visit(int version, int access, String name, String signature, String private TinyRemapper createTinyRemapper() { try { - TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, "intermediary", "named"); + // TODO service manager, via new processor api + if (true) { + throw new UnsupportedOperationException("ToDO"); + } + + TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, null, "intermediary", "named"); tinyRemapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(project)); for (Path minecraftJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) { diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java b/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java index cf9cdc4e1..7a773e781 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ModJavadocProcessor.java @@ -37,12 +37,10 @@ import javax.inject.Inject; import com.google.gson.JsonElement; -import org.gradle.api.Project; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.processor.MinecraftJarProcessor; import net.fabricmc.loom.api.processor.ProcessorContext; @@ -56,9 +54,6 @@ public abstract class ModJavadocProcessor implements MinecraftJarProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(ModJavadocProcessor.class); - @Inject - public abstract Project getProject(); - private final String name; @Inject @@ -73,12 +68,6 @@ public String getName() { @Override public @Nullable ModJavadocProcessor.Spec buildSpec(SpecContext context) { - final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); - - if (!extension.getEnableModProvidedJavadoc().get()) { - return null; - } - List javadocs = new ArrayList<>(); for (FabricModJson fabricModJson : context.allMods()) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java index aad487646..5cf477755 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java @@ -116,8 +116,8 @@ public static MappingConfiguration create(Project project, SharedServiceManager return mappingProvider; } - public MappingsService getMappingsService(SharedServiceManager serviceManager) { - return MappingsService.create(serviceManager, Objects.requireNonNull(tinyMappings)); + public TinyMappingsService getMappingsService(SharedServiceManager serviceManager) { + return TinyMappingsService.create(serviceManager, Objects.requireNonNull(tinyMappings)); } private void setup(Project project, SharedServiceManager serviceManager, MinecraftProvider minecraftProvider, Path inputJar) throws IOException { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java deleted file mode 100644 index 02c923988..000000000 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsService.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.fabricmc.loom.configuration.providers.mappings; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Path; - -import net.fabricmc.loom.util.service.SharedService; -import net.fabricmc.loom.util.service.SharedServiceManager; -import net.fabricmc.mappingio.MappingReader; -import net.fabricmc.mappingio.tree.MemoryMappingTree; - -public final class MappingsService implements SharedService { - private final MemoryMappingTree mappingTree; - - public MappingsService(Path tinyMappings) { - try { - this.mappingTree = new MemoryMappingTree(); - MappingReader.read(tinyMappings, mappingTree); - } catch (IOException e) { - throw new UncheckedIOException("Failed to read mappings", e); - } - } - - public static synchronized MappingsService create(SharedServiceManager serviceManager, Path tinyMappings) { - return serviceManager.getOrCreateService("MappingsService:" + tinyMappings.toAbsolutePath(), () -> new MappingsService(tinyMappings)); - } - - public MemoryMappingTree getMappingTree() { - return mappingTree; - } -} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java new file mode 100644 index 000000000..cd32313d6 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/TinyMappingsService.java @@ -0,0 +1,55 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 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.io.UncheckedIOException; +import java.nio.file.Path; + +import net.fabricmc.loom.util.service.SharedService; +import net.fabricmc.loom.util.service.SharedServiceManager; +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +public final class TinyMappingsService implements SharedService { + private final MemoryMappingTree mappingTree; + + public TinyMappingsService(Path tinyMappings) { + try { + this.mappingTree = new MemoryMappingTree(); + MappingReader.read(tinyMappings, mappingTree); + } catch (IOException e) { + throw new UncheckedIOException("Failed to read mappings", e); + } + } + + public static synchronized TinyMappingsService create(SharedServiceManager serviceManager, Path tinyMappings) { + return serviceManager.getOrCreateService("TinyMappingsService:" + tinyMappings.toAbsolutePath(), () -> new TinyMappingsService(tinyMappings)); + } + + public MemoryMappingTree getMappingTree() { + return mappingTree; + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MergedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MergedMinecraftProvider.java index 94fe014c8..50ca208f3 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MergedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MergedMinecraftProvider.java @@ -31,15 +31,14 @@ import java.util.List; import java.util.Objects; -import org.gradle.api.Project; - +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.stitch.merge.JarMerger; public final class MergedMinecraftProvider extends MinecraftProvider { private Path minecraftMergedJar; - public MergedMinecraftProvider(Project project) { - super(project); + public MergedMinecraftProvider(ConfigContext configContext) { + super(configContext); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java index c48102b20..04a7468a7 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java @@ -28,8 +28,7 @@ import java.util.function.BiFunction; import java.util.function.Function; -import org.gradle.api.Project; - +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.decompile.DecompileConfiguration; import net.fabricmc.loom.configuration.decompile.SingleJarDecompileConfiguration; import net.fabricmc.loom.configuration.decompile.SplitDecompileConfiguration; @@ -73,39 +72,39 @@ public enum MinecraftJarConfiguration { List.of("client", "server") ); - private final Function minecraftProviderFunction; - private final BiFunction> intermediaryMinecraftProviderBiFunction; - private final BiFunction> namedMinecraftProviderBiFunction; + private final Function minecraftProviderFunction; + private final BiFunction> intermediaryMinecraftProviderBiFunction; + private final BiFunction> namedMinecraftProviderBiFunction; private final BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider> processedNamedMinecraftProviderBiFunction; - private final BiFunction> decompileConfigurationBiFunction; + private final BiFunction> decompileConfigurationBiFunction; private final List supportedEnvironments; @SuppressWarnings("unchecked") // Just a bit of a generic mess :) , Q extends MappedMinecraftProvider> MinecraftJarConfiguration( - Function minecraftProviderFunction, - BiFunction> intermediaryMinecraftProviderBiFunction, - BiFunction namedMinecraftProviderBiFunction, + Function minecraftProviderFunction, + BiFunction> intermediaryMinecraftProviderBiFunction, + BiFunction namedMinecraftProviderBiFunction, BiFunction> processedNamedMinecraftProviderBiFunction, - BiFunction> decompileConfigurationBiFunction, + BiFunction> decompileConfigurationBiFunction, List supportedEnvironments ) { - this.minecraftProviderFunction = (Function) minecraftProviderFunction; - this.intermediaryMinecraftProviderBiFunction = (BiFunction>) (Object) intermediaryMinecraftProviderBiFunction; - this.namedMinecraftProviderBiFunction = (BiFunction>) namedMinecraftProviderBiFunction; + this.minecraftProviderFunction = (Function) minecraftProviderFunction; + this.intermediaryMinecraftProviderBiFunction = (BiFunction>) (Object) intermediaryMinecraftProviderBiFunction; + this.namedMinecraftProviderBiFunction = (BiFunction>) namedMinecraftProviderBiFunction; this.processedNamedMinecraftProviderBiFunction = (BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider>) (Object) processedNamedMinecraftProviderBiFunction; - this.decompileConfigurationBiFunction = (BiFunction>) decompileConfigurationBiFunction; + this.decompileConfigurationBiFunction = (BiFunction>) decompileConfigurationBiFunction; this.supportedEnvironments = supportedEnvironments; } - public Function getMinecraftProviderFunction() { + public Function getMinecraftProviderFunction() { return minecraftProviderFunction; } - public BiFunction> getIntermediaryMinecraftProviderBiFunction() { + public BiFunction> getIntermediaryMinecraftProviderBiFunction() { return intermediaryMinecraftProviderBiFunction; } - public BiFunction> getNamedMinecraftProviderBiFunction() { + public BiFunction> getNamedMinecraftProviderBiFunction() { return namedMinecraftProviderBiFunction; } @@ -113,7 +112,7 @@ public BiFunction> getName return processedNamedMinecraftProviderBiFunction; } - public BiFunction> getDecompileConfigurationBiFunction() { + public BiFunction> getDecompileConfigurationBiFunction() { return decompileConfigurationBiFunction; } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java index 13189391d..7079db7b0 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java @@ -38,6 +38,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.DependencyInfo; import net.fabricmc.loom.configuration.providers.BundleMetadata; import net.fabricmc.loom.util.Constants; @@ -67,8 +68,8 @@ public abstract class MinecraftProvider { private final Project project; - public MinecraftProvider(Project project) { - this.project = project; + public MinecraftProvider(ConfigContext configContext) { + this.project = configContext.project(); } protected boolean provideClient() { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java index 08a6e7c3c..7094dbf0c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SignatureFixerApplyVisitor.java @@ -29,15 +29,15 @@ import java.util.HashMap; import java.util.Map; -import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; - import org.gradle.api.Project; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.commons.Remapper; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.TinyRemapperHelper; +import net.fabricmc.loom.util.service.SharedServiceManager; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.api.TrClass; @@ -56,7 +56,7 @@ public void visit(int version, int access, String name, String signature, String }; } - public static Map getRemappedSignatures(boolean toIntermediary, MappingConfiguration mappingConfiguration, Project project, String targetNamespace) throws IOException { + public static Map getRemappedSignatures(boolean toIntermediary, MappingConfiguration mappingConfiguration, Project project, SharedServiceManager serviceManager, String targetNamespace) throws IOException { if (mappingConfiguration.getSignatureFixes() == null) { // No fixes return Collections.emptyMap(); @@ -69,7 +69,7 @@ public static Map getRemappedSignatures(boolean toIntermediary, // Remap the sig fixes from intermediary to the target namespace final Map remapped = new HashMap<>(); - final TinyRemapper sigTinyRemapper = TinyRemapperHelper.getTinyRemapper(project, MappingsNamespace.INTERMEDIARY.toString(), targetNamespace); + final TinyRemapper sigTinyRemapper = TinyRemapperHelper.getTinyRemapper(project, serviceManager, MappingsNamespace.INTERMEDIARY.toString(), targetNamespace); final Remapper sigAsmRemapper = sigTinyRemapper.getEnvironment().getRemapper(); // Remap the class names and the signatures using a new tiny remapper instance. diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java index 83743035b..e63a5ac27 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java @@ -28,8 +28,7 @@ import java.nio.file.Path; import java.util.List; -import org.gradle.api.Project; - +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.BundleMetadata; import net.fabricmc.tinyremapper.NonClassCopyMode; import net.fabricmc.tinyremapper.OutputConsumerPath; @@ -40,17 +39,17 @@ public final class SingleJarMinecraftProvider extends MinecraftProvider { private Path minecraftEnvOnlyJar; - private SingleJarMinecraftProvider(Project project, Environment environment) { - super(project); + private SingleJarMinecraftProvider(ConfigContext configContext, Environment environment) { + super(configContext); this.environment = environment; } - public static SingleJarMinecraftProvider server(Project project) { - return new SingleJarMinecraftProvider(project, new Server()); + public static SingleJarMinecraftProvider server(ConfigContext configContext) { + return new SingleJarMinecraftProvider(configContext, new Server()); } - public static SingleJarMinecraftProvider client(Project project) { - return new SingleJarMinecraftProvider(project, new Client()); + public static SingleJarMinecraftProvider client(ConfigContext configContext) { + return new SingleJarMinecraftProvider(configContext, new Client()); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SplitMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SplitMinecraftProvider.java index 1da1c36a8..f970aa164 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SplitMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SplitMinecraftProvider.java @@ -28,16 +28,15 @@ import java.nio.file.Path; import java.util.List; -import org.gradle.api.Project; - +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.BundleMetadata; public final class SplitMinecraftProvider extends MinecraftProvider { private Path minecraftClientOnlyJar; private Path minecraftCommonJar; - public SplitMinecraftProvider(Project project) { - super(project); + public SplitMinecraftProvider(ConfigContext configContext) { + super(configContext); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java index 1b2c17541..635502259 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java @@ -35,6 +35,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; @@ -45,13 +46,13 @@ public abstract class AbstractMappedMinecraftProvider implements MappedMinecraftProvider.ProviderImpl { protected final M minecraftProvider; - private final Project project; + protected final ConfigContext configContext; protected final LoomGradleExtension extension; - public AbstractMappedMinecraftProvider(Project project, M minecraftProvider) { - this.project = project; + public AbstractMappedMinecraftProvider(ConfigContext configContext, M minecraftProvider) { + this.configContext = configContext; this.minecraftProvider = minecraftProvider; - this.extension = LoomGradleExtension.get(project); + this.extension = configContext.extension(); } public abstract MappingsNamespace getTargetNamespace(); @@ -130,15 +131,15 @@ private void remapJar(RemappedJars remappedJars) throws IOException { Files.deleteIfExists(remappedJars.outputJar()); - final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, project, toM); - TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(project, fromM, toM, true, (builder) -> { + final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceManager(), toM); + TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(getProject(), configContext.serviceManager(), fromM, toM, true, (builder) -> { builder.extraPostApplyVisitor(new SignatureFixerApplyVisitor(remappedSignatures)); configureRemapper(remappedJars, builder); }); try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(remappedJars.outputJar()).build()) { outputConsumer.addNonClassFiles(remappedJars.inputJar()); - remapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(project)); + remapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(getProject())); for (Path path : remappedJars.remapClasspath()) { remapper.readClassPath(path); @@ -162,8 +163,12 @@ private void cleanOutputs(List remappedJars) throws IOException { } } + public ConfigContext getConfigContext() { + return configContext; + } + public Project getProject() { - return project; + return getConfigContext().project(); } public M getMinecraftProvider() { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java index 5dd9cbdb7..4f1e07ccf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java @@ -27,9 +27,8 @@ import java.nio.file.Path; import java.util.List; -import org.gradle.api.Project; - import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType; @@ -39,8 +38,8 @@ import net.fabricmc.tinyremapper.TinyRemapper; public abstract sealed class IntermediaryMinecraftProvider extends AbstractMappedMinecraftProvider permits IntermediaryMinecraftProvider.MergedImpl, IntermediaryMinecraftProvider.SingleJarImpl, IntermediaryMinecraftProvider.SplitImpl { - public IntermediaryMinecraftProvider(Project project, M minecraftProvider) { - super(project, minecraftProvider); + public IntermediaryMinecraftProvider(ConfigContext configContext, M minecraftProvider) { + super(configContext, minecraftProvider); } @Override @@ -54,8 +53,8 @@ public final MappingsNamespace getTargetNamespace() { } public static final class MergedImpl extends IntermediaryMinecraftProvider implements Merged { - public MergedImpl(Project project, MergedMinecraftProvider minecraftProvider) { - super(project, minecraftProvider); + public MergedImpl(ConfigContext configContext, MergedMinecraftProvider minecraftProvider) { + super(configContext, minecraftProvider); } @Override @@ -67,8 +66,8 @@ public List getRemappedJars() { } public static final class SplitImpl extends IntermediaryMinecraftProvider implements Split { - public SplitImpl(Project project, SplitMinecraftProvider minecraftProvider) { - super(project, minecraftProvider); + public SplitImpl(ConfigContext configContext, SplitMinecraftProvider minecraftProvider) { + super(configContext, minecraftProvider); } @Override @@ -90,17 +89,17 @@ protected void configureRemapper(RemappedJars remappedJars, TinyRemapper.Builder public static final class SingleJarImpl extends IntermediaryMinecraftProvider implements SingleJar { private final SingleJarEnvType env; - private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { - super(project, minecraftProvider); + private SingleJarImpl(ConfigContext configContext, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { + super(configContext, minecraftProvider); this.env = env; } - public static SingleJarImpl server(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.SERVER); + public static SingleJarImpl server(ConfigContext configContext, SingleJarMinecraftProvider minecraftProvider) { + return new SingleJarImpl(configContext, minecraftProvider, SingleJarEnvType.SERVER); } - public static SingleJarImpl client(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.CLIENT); + public static SingleJarImpl client(ConfigContext configContext, SingleJarMinecraftProvider minecraftProvider) { + return new SingleJarImpl(configContext, minecraftProvider, SingleJarEnvType.CLIENT); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java index 1e5f80b52..97de6d967 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java @@ -27,9 +27,8 @@ import java.nio.file.Path; import java.util.List; -import org.gradle.api.Project; - import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType; @@ -39,8 +38,8 @@ import net.fabricmc.tinyremapper.TinyRemapper; public abstract class NamedMinecraftProvider extends AbstractMappedMinecraftProvider { - public NamedMinecraftProvider(Project project, M minecraftProvider) { - super(project, minecraftProvider); + public NamedMinecraftProvider(ConfigContext configContext, M minecraftProvider) { + super(configContext, minecraftProvider); } @Override @@ -54,8 +53,8 @@ public final MappingsNamespace getTargetNamespace() { } public static final class MergedImpl extends NamedMinecraftProvider implements Merged { - public MergedImpl(Project project, MergedMinecraftProvider minecraftProvider) { - super(project, minecraftProvider); + public MergedImpl(ConfigContext configContext, MergedMinecraftProvider minecraftProvider) { + super(configContext, minecraftProvider); } @Override @@ -72,8 +71,8 @@ public List getDependencyTargets() { } public static final class SplitImpl extends NamedMinecraftProvider implements Split { - public SplitImpl(Project project, SplitMinecraftProvider minecraftProvider) { - super(project, minecraftProvider); + public SplitImpl(ConfigContext configContext, SplitMinecraftProvider minecraftProvider) { + super(configContext, minecraftProvider); } @Override @@ -100,17 +99,17 @@ public List getDependencyTargets() { public static final class SingleJarImpl extends NamedMinecraftProvider implements SingleJar { private final SingleJarEnvType env; - private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { - super(project, minecraftProvider); + private SingleJarImpl(ConfigContext configContext, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { + super(configContext, minecraftProvider); this.env = env; } - public static SingleJarImpl server(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.SERVER); + public static SingleJarImpl server(ConfigContext configContext, SingleJarMinecraftProvider minecraftProvider) { + return new SingleJarImpl(configContext, minecraftProvider, SingleJarEnvType.SERVER); } - public static SingleJarImpl client(Project project, SingleJarMinecraftProvider minecraftProvider) { - return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.CLIENT); + public static SingleJarImpl client(ConfigContext configContext, SingleJarMinecraftProvider minecraftProvider) { + return new SingleJarImpl(configContext, minecraftProvider, SingleJarEnvType.CLIENT); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java index 8f8e3e0e8..2a4d8901a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java @@ -50,7 +50,7 @@ public abstract class ProcessedNamedMinecraftProvider new SourceRemapperService(MappingsService.createDefault(project, serviceManager, from, to), task.getClasspath() diff --git a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java index 6d29b9d9f..5e38ef8cd 100644 --- a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java @@ -66,7 +66,7 @@ public static synchronized TinyRemapperService getOrCreate(SharedServiceManager // Generates an id that is used to share the remapper across projects. This tasks in the remap jar task name to handle custom remap jar tasks separately. final var joiner = new StringJoiner(":"); - joiner.add(extension.getMappingsProvider().getBuildServiceName("remapJarService", from, to)); + joiner.add(extension.getMappingConfiguration().getBuildServiceName("remapJarService", from, to)); joiner.add(remapJarTask.getName()); if (kotlinClasspathService != null) { diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index 8fed7ac02..ab2e79836 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -33,10 +33,6 @@ import java.util.Set; import java.util.function.Consumer; -import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; - -import net.fabricmc.loom.util.service.SharedServiceManager; - import org.cadixdev.lorenz.MappingSet; import org.cadixdev.mercury.Mercury; import org.cadixdev.mercury.remapper.MercuryRemapper; @@ -49,6 +45,8 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; +import net.fabricmc.loom.util.service.SharedServiceManager; import net.fabricmc.lorenztiny.TinyMappingsReader; import net.fabricmc.mappingio.tree.MemoryMappingTree; diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java index 4f0bdfaca..01e8d9a38 100644 --- a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java +++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java @@ -32,13 +32,11 @@ import java.util.regex.Pattern; import com.google.common.collect.ImmutableMap; - -import net.fabricmc.loom.util.service.SharedServiceManager; - import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.util.service.SharedServiceManager; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; From 00a3b7ff4eef587211934c6c8a11d0a775716ba5 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 9 Oct 2022 14:08:23 +0100 Subject: [PATCH 10/13] Move Iface injection to new MinecraftJarProcessor API --- .../api/InterfaceInjectionExtensionAPI.java | 10 +- .../loom/api/processor/ProcessorContext.java | 4 + .../loom/api/processor/SpecContext.java | 3 + .../configuration/CompileConfiguration.java | 25 +- .../AccessWidenerJarProcessor.java | 10 +- .../TransitiveAccessWidenerJarProcessor.java | 16 +- .../InterfaceInjectionProcessor.java | 301 ++++++------------ .../processors/ProcessorContextImpl.java | 33 +- .../processors/SpecContextImpl.java | 33 +- .../minecraft/MinecraftSourceSets.java | 2 - .../ProcessedNamedMinecraftProvider.java | 2 +- .../extension/LoomGradleExtensionApiImpl.java | 1 + .../loom/task/GenerateSourcesTask.java | 5 - .../loom/util/fmj/FabricModJsonFactory.java | 5 + 14 files changed, 199 insertions(+), 251 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/api/InterfaceInjectionExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/InterfaceInjectionExtensionAPI.java index 5a3cfbd33..e8a5da7b2 100644 --- a/src/main/java/net/fabricmc/loom/api/InterfaceInjectionExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/InterfaceInjectionExtensionAPI.java @@ -38,15 +38,15 @@ public interface InterfaceInjectionExtensionAPI { */ Property getEnableDependencyInterfaceInjection(); + Property getIsEnabled(); + /** - * Contains a list of {@link SourceSet} that may contain a fabric.mod.json file with interfaces to inject. - * By default, this list contains only the main {@link SourceSet}. - * - * @return the list property containing the {@link SourceSet} + * @deprecated now uses the source sets defined in {@link LoomGradleExtensionAPI#getMods()} */ + @Deprecated(forRemoval = true) ListProperty getInterfaceInjectionSourceSets(); default boolean isEnabled() { - return getEnableDependencyInterfaceInjection().get() || !getInterfaceInjectionSourceSets().get().isEmpty(); + return getIsEnabled().get(); } } diff --git a/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java b/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java index 9444e58bc..5f934e653 100644 --- a/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java +++ b/src/main/java/net/fabricmc/loom/api/processor/ProcessorContext.java @@ -24,7 +24,9 @@ package net.fabricmc.loom.api.processor; +import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; +import net.fabricmc.tinyremapper.TinyRemapper; public interface ProcessorContext { MinecraftJarConfiguration getJarConfiguration(); @@ -34,4 +36,6 @@ public interface ProcessorContext { boolean includesClient(); boolean includesServer(); + + TinyRemapper createRemapper(MappingsNamespace from, MappingsNamespace to); } diff --git a/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java b/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java index 3370ae71c..e0480168c 100644 --- a/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java +++ b/src/main/java/net/fabricmc/loom/api/processor/SpecContext.java @@ -34,6 +34,9 @@ public interface SpecContext { List localMods(); + // Returns mods that are both on the compile and runtime classpath + List modDependenciesCompileRuntime(); + default List allMods() { return Stream.concat(modDependencies().stream(), localMods().stream()).toList(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 49413b907..7cdb58463 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -43,6 +43,7 @@ import org.gradle.api.tasks.javadoc.Javadoc; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.api.InterfaceInjectionExtensionAPI; import net.fabricmc.loom.build.mixin.GroovyApInvoker; import net.fabricmc.loom.build.mixin.JavaApInvoker; import net.fabricmc.loom.build.mixin.KaptApInvoker; @@ -202,7 +203,7 @@ private static synchronized void setupMinecraft(ConfigContext configContext) thr final IntermediaryMinecraftProvider intermediaryMinecraftProvider = jarConfiguration.getIntermediaryMinecraftProviderBiFunction().apply(configContext, minecraftProvider); NamedMinecraftProvider namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(configContext, minecraftProvider); - registerGameProcessors(project); + registerGameProcessors(configContext); MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(project); if (minecraftJarProcessorManager != null) { @@ -217,32 +218,30 @@ private static synchronized void setupMinecraft(ConfigContext configContext) thr namedMinecraftProvider.provide(true); } - private static void registerGameProcessors(Project project) { - final LoomGradleExtension extension = LoomGradleExtension.get(project); + private static void registerGameProcessors(ConfigContext configContext) { + final LoomGradleExtension extension = configContext.extension(); if (extension.getAccessWidenerPath().isPresent()) { - extension.getGameJarProcessors().add(new AccessWidenerJarProcessor(project)); + extension.getGameJarProcessors().add(new AccessWidenerJarProcessor(configContext)); } if (extension.getEnableTransitiveAccessWideners().get()) { - TransitiveAccessWidenerJarProcessor transitiveAccessWidenerJarProcessor = new TransitiveAccessWidenerJarProcessor(project); + TransitiveAccessWidenerJarProcessor transitiveAccessWidenerJarProcessor = new TransitiveAccessWidenerJarProcessor(configContext); if (!transitiveAccessWidenerJarProcessor.isEmpty()) { extension.getGameJarProcessors().add(transitiveAccessWidenerJarProcessor); } } - if (extension.getInterfaceInjection().isEnabled()) { - InterfaceInjectionProcessor jarProcessor = new InterfaceInjectionProcessor(project); - - if (!jarProcessor.isEmpty()) { - extension.getGameJarProcessors().add(jarProcessor); - } - } - if (extension.getEnableModProvidedJavadoc().get()) { extension.addMinecraftJarProcessor(ModJavadocProcessor.class, "fabric-loom:mod-javadoc"); } + + final InterfaceInjectionExtensionAPI interfaceInjection = extension.getInterfaceInjection(); + + if (interfaceInjection.isEnabled()) { + extension.addMinecraftJarProcessor(InterfaceInjectionProcessor.class, "fabric-loom:interface-inject", interfaceInjection.getEnableDependencyInterfaceInjection().get()); + } } private static void setupMixinAp(Project project, MixinExtension mixin) { diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java index e1b23ea3b..daacaf4bf 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/AccessWidenerJarProcessor.java @@ -37,6 +37,7 @@ import net.fabricmc.accesswidener.AccessWidener; import net.fabricmc.accesswidener.AccessWidenerReader; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.processors.JarProcessor; import net.fabricmc.loom.util.Checksum; import net.fabricmc.loom.util.ZipUtils; @@ -44,15 +45,13 @@ public class AccessWidenerJarProcessor implements JarProcessor { // Filename used to store hash of input access widener in processed jar file private static final String HASH_FILENAME = "aw.sha256"; - // The mod's own access widener file - private byte[] modAccessWidener; private final AccessWidener accessWidener = new AccessWidener(); private final Project project; // This is a SHA256 hash across the mod's and all transitive AWs private byte[] inputHash; - public AccessWidenerJarProcessor(Project project) { - this.project = project; + public AccessWidenerJarProcessor(ConfigContext configContext) { + this.project = configContext.project(); } @Override @@ -66,6 +65,9 @@ public void setup() { Path awPath = extension.getAccessWidenerPath().get().getAsFile().toPath(); // Read our own mod's access widener, used later for producing a version remapped to intermediary + // The mod's own access widener file + byte[] modAccessWidener; + try { modAccessWidener = Files.readAllBytes(awPath); } catch (NoSuchFileException e) { diff --git a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java index 3da420b54..21b1fd74d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesswidener/TransitiveAccessWidenerJarProcessor.java @@ -48,6 +48,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.processors.JarProcessor; import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.tinyremapper.TinyRemapper; @@ -56,14 +57,16 @@ * Applies transitive access wideners that are inherited from mod and api dependencies. */ public class TransitiveAccessWidenerJarProcessor implements JarProcessor { + private final ConfigContext configContext; private final Project project; private final LoomGradleExtension extension; private final List transitiveAccessWideners; - public TransitiveAccessWidenerJarProcessor(Project project) { - this.project = project; - this.extension = LoomGradleExtension.get(project); + public TransitiveAccessWidenerJarProcessor(ConfigContext configContext) { + this.configContext = configContext; + this.project = configContext.project(); + this.extension = configContext.extension(); transitiveAccessWideners = getTransitiveAccessWideners(); @@ -166,12 +169,7 @@ private AccessWidener createAccessWidener() { private TinyRemapper createTinyRemapper() { try { - // TODO service manager, via new processor api - if (true) { - throw new UnsupportedOperationException("ToDO"); - } - - TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, null, "intermediary", "named"); + TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, configContext.serviceManager(), "intermediary", "named"); tinyRemapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(project)); diff --git a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java index e23ebd127..585e2c1f6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/ifaceinject/InterfaceInjectionProcessor.java @@ -24,217 +24,157 @@ package net.fabricmc.loom.configuration.ifaceinject; -import java.io.File; import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; -import com.google.common.base.Preconditions; -import com.google.common.hash.Hasher; -import com.google.common.hash.Hashing; +import javax.inject.Inject; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import org.gradle.api.Project; -import org.gradle.api.tasks.SourceSet; +import org.jetbrains.annotations.Nullable; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.commons.Remapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.api.InterfaceInjectionExtensionAPI; -import net.fabricmc.loom.api.RemapConfigurationSettings; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; -import net.fabricmc.loom.configuration.processors.JarProcessor; -import net.fabricmc.loom.task.GenerateSourcesTask; -import net.fabricmc.loom.util.Checksum; +import net.fabricmc.loom.api.processor.MinecraftJarProcessor; +import net.fabricmc.loom.api.processor.ProcessorContext; +import net.fabricmc.loom.api.processor.SpecContext; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.Pair; -import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.fmj.FabricModJson; -import net.fabricmc.loom.util.fmj.FabricModJsonFactory; import net.fabricmc.mappingio.tree.MappingTree; -import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.tinyremapper.TinyRemapper; -public class InterfaceInjectionProcessor implements JarProcessor, GenerateSourcesTask.MappingsProcessor { - private final Map> injectedInterfaces; - private final Project project; - private final LoomGradleExtension extension; - private final InterfaceInjectionExtensionAPI interfaceInjectionExtension; - private final byte[] inputHash; - private Map> remappedInjectedInterfaces; - - public InterfaceInjectionProcessor(Project project) { - this.project = project; - this.extension = LoomGradleExtension.get(project); - this.interfaceInjectionExtension = this.extension.getInterfaceInjection(); - this.injectedInterfaces = getInjectedInterfaces().stream() - .collect(Collectors.groupingBy(InjectedInterface::className)); - - this.inputHash = hashInjectedInterfaces(); - } +public abstract class InterfaceInjectionProcessor implements MinecraftJarProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceInjectionProcessor.class); - public boolean isEmpty() { - return injectedInterfaces.isEmpty(); - } + private final String name; + private final boolean fromDependencies; - @Override - public String getId() { - Preconditions.checkArgument(!isEmpty()); - return "loom:interface_injection:" + Checksum.toHex(inputHash); + @Inject + public InterfaceInjectionProcessor(String name, boolean fromDependencies) { + this.name = name; + this.fromDependencies = fromDependencies; } @Override - public void setup() { + public String getName() { + return name; } @Override - public void process(File jarFile) { - // Lazily remap from intermediary->named - if (remappedInjectedInterfaces == null) { - TinyRemapper tinyRemapper = createTinyRemapper(); - Remapper remapper = tinyRemapper.getEnvironment().getRemapper(); - - try { - remappedInjectedInterfaces = new HashMap<>(injectedInterfaces.size()); - - for (Map.Entry> entry : injectedInterfaces.entrySet()) { - String namedClassName = remapper.map(entry.getKey()); - remappedInjectedInterfaces.put( - namedClassName, - entry.getValue().stream() - .map(injectedInterface -> - new InjectedInterface( - injectedInterface.modId(), - namedClassName, - remapper.map(injectedInterface.ifaceName()) - )) - .toList() - ); - } - } finally { - tinyRemapper.finish(); - } + public @Nullable InterfaceInjectionProcessor.Spec buildSpec(SpecContext context) { + List injectedInterfaces = new ArrayList<>(); + + injectedInterfaces.addAll(InjectedInterface.fromMods(context.localMods())); + // Find the injected interfaces from mods that are both on the compile and runtime classpath. + // Runtime is also required to ensure that the interface and it's impl is present when running the mc jar. + + if (fromDependencies) { + injectedInterfaces.addAll(InjectedInterface.fromMods(context.modDependenciesCompileRuntime())); } - try { - ZipUtils.transform(jarFile.toPath(), getTransformers()); - } catch (IOException e) { - throw new RuntimeException("Failed to apply interface injections to " + jarFile, e); + if (injectedInterfaces.isEmpty()) { + return null; } - } - private List>> getTransformers() { - return remappedInjectedInterfaces.keySet().stream() - .map(string -> new Pair<>(string.replaceAll("\\.", "/") + ".class", getTransformer(string))) - .collect(Collectors.toList()); + return new Spec(injectedInterfaces); } - private ZipUtils.UnsafeUnaryOperator getTransformer(String className) { - return input -> { - ClassReader reader = new ClassReader(input); - ClassWriter writer = new ClassWriter(0); - List ifaces = remappedInjectedInterfaces.get(className); - ClassVisitor classVisitor = new InjectingClassVisitor(Constants.ASM_VERSION, writer, ifaces); - - // Log which mods add which interface to the class - project.getLogger().info("Injecting interfaces into " + className + ": " - + ifaces.stream().map(i -> i.ifaceName() + " [" + i.modId() + "]" - ).collect(Collectors.joining(", "))); - - reader.accept(classVisitor, 0); - return writer.toByteArray(); - }; + public record Spec(List injectedInterfaces) implements MinecraftJarProcessor.Spec { } - private List getInjectedInterfaces() { - List result = new ArrayList<>(); + @Override + public void processJar(Path jar, Spec spec, ProcessorContext context) throws IOException { + // Remap from intermediary->named + final TinyRemapper tinyRemapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED); + final Remapper remapper = tinyRemapper.getEnvironment().getRemapper(); + final List remappedInjectedInterfaces; - if (interfaceInjectionExtension.getEnableDependencyInterfaceInjection().get()) { - result.addAll(getDependencyInjectedInterfaces()); + try { + remappedInjectedInterfaces = spec.injectedInterfaces().stream() + .map(injectedInterface -> remap(injectedInterface, remapper)) + .toList(); + } finally { + tinyRemapper.finish(); } - for (SourceSet sourceSet : interfaceInjectionExtension.getInterfaceInjectionSourceSets().get()) { - result.addAll(getSourceInjectedInterface(sourceSet)); + try { + ZipUtils.transform(jar, getTransformers(remappedInjectedInterfaces)); + } catch (IOException e) { + throw new RuntimeException("Failed to apply interface injections to " + jar, e); } - - return result; } - // Find the injected interfaces from mods that are both on the compile and runtime classpath. - // Runtime is also required to ensure that the interface and it's impl is present when running the mc jar. - private List getDependencyInjectedInterfaces() { - final Function> resolve = settings -> - settings.getSourceConfiguration().get().resolve().stream() - .map(File::toPath); - - final List runtimeEntries = extension.getRuntimeRemapConfigurations().stream() - .flatMap(resolve) - .toList(); - - return extension.getCompileRemapConfigurations().stream() - .flatMap(resolve) - .filter(runtimeEntries::contains) // Use the intersection of the two configurations. - .flatMap(path -> InjectedInterface.fromModJar(path).stream()) - .toList(); + private InjectedInterface remap(InjectedInterface in, Remapper remapper) { + return new InjectedInterface( + in.modId(), + remapper.map(in.className()), + remapper.map(in.ifaceName()) + ); } - private List getSourceInjectedInterface(SourceSet sourceSet) { - final FabricModJson fabricModJson; - - try { - fabricModJson = FabricModJsonFactory.createFromSourceSetsNullable(sourceSet); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - - if (fabricModJson == null) { - return Collections.emptyList(); - } + private List>> getTransformers(List injectedInterfaces) { + return injectedInterfaces.stream() + .collect(Collectors.groupingBy(InjectedInterface::className)) + .entrySet() + .stream() + .map(entry -> { + final String zipEntry = entry.getKey().replaceAll("\\.", "/") + ".class"; + return new Pair<>(zipEntry, getTransformer(entry.getValue())); + }).toList(); + } - return InjectedInterface.fromFabricModJson(fabricModJson); + private ZipUtils.UnsafeUnaryOperator getTransformer(List injectedInterfaces) { + return input -> { + final ClassReader reader = new ClassReader(input); + final ClassWriter writer = new ClassWriter(0); + final ClassVisitor classVisitor = new InjectingClassVisitor(Constants.ASM_VERSION, writer, injectedInterfaces); + reader.accept(classVisitor, 0); + return writer.toByteArray(); + }; } @Override - public boolean transform(MemoryMappingTree mappings) { - if (injectedInterfaces.isEmpty()) { - return false; - } + public MappingsProcessor processMappings() { + return (mappings, spec, context) -> { + if (!MappingsNamespace.INTERMEDIARY.toString().equals(mappings.getSrcNamespace())) { + throw new IllegalStateException("Mapping tree must have intermediary src mappings not " + mappings.getSrcNamespace()); + } - if (!MappingsNamespace.INTERMEDIARY.toString().equals(mappings.getSrcNamespace())) { - throw new IllegalStateException("Mapping tree must have intermediary src mappings not " + mappings.getSrcNamespace()); - } + Map> map = spec.injectedInterfaces().stream() + .collect(Collectors.groupingBy(InjectedInterface::className)); - for (Map.Entry> entry : injectedInterfaces.entrySet()) { - final String className = entry.getKey(); - final List injectedInterfaces = entry.getValue(); + for (Map.Entry> entry : map.entrySet()) { + final String className = entry.getKey(); + final List injectedInterfaces = entry.getValue(); - MappingTree.ClassMapping classMapping = mappings.getClass(className); + MappingTree.ClassMapping classMapping = mappings.getClass(className); - if (classMapping == null) { - final String modIds = injectedInterfaces.stream().map(InjectedInterface::modId).distinct().collect(Collectors.joining(",")); - project.getLogger().warn("Failed to find class ({}) to add injected interfaces from mod(s) ({})", className, modIds); - continue; - } + if (classMapping == null) { + final String modIds = injectedInterfaces.stream().map(InjectedInterface::modId).distinct().collect(Collectors.joining(",")); + LOGGER.warn("Failed to find class ({}) to add injected interfaces from mod(s) ({})", className, modIds); + continue; + } - classMapping.setComment(appendComment(classMapping.getComment(), injectedInterfaces)); - } + classMapping.setComment(appendComment(classMapping.getComment(), injectedInterfaces)); + } - return true; + return true; + }; } private static String appendComment(String comment, List injectedInterfaces) { @@ -254,20 +194,7 @@ private static String appendComment(String comment, List inje } private record InjectedInterface(String modId, String className, String ifaceName) { - /** - * Reads the injected interfaces contained in a mod jar, or returns empty if there is none. - */ - public static List fromModJar(Path modJarPath) { - FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(modJarPath); - - if (fabricModJson == null) { - return Collections.emptyList(); - } - - return fromFabricModJson(fabricModJson); - } - - public static List fromFabricModJson(FabricModJson fabricModJson) { + public static List fromMod(FabricModJson fabricModJson) { final String modId = fabricModJson.getId(); final JsonElement jsonElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE); @@ -289,6 +216,13 @@ public static List fromFabricModJson(FabricModJson fabricModJ return result; } + + public static List fromMods(List fabricModJsons) { + return fabricModJsons.stream() + .map(InjectedInterface::fromMod) + .flatMap(List::stream) + .toList(); + } } private static class InjectingClassVisitor extends ClassVisitor { @@ -326,41 +260,4 @@ public void visit(int version, int access, String name, String signature, String super.visit(version, access, name, signature, superName, modifiedInterfaces.toArray(new String[0])); } } - - private TinyRemapper createTinyRemapper() { - try { - // TODO service manager, via new processor api - if (true) { - throw new UnsupportedOperationException("ToDO"); - } - - TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(project, null, "intermediary", "named"); - tinyRemapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(project)); - - for (Path minecraftJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) { - tinyRemapper.readClassPath(minecraftJar); - } - - return tinyRemapper; - } catch (IOException e) { - throw new RuntimeException("Failed to create tiny remapper for intermediary->named", e); - } - } - - private byte[] hashInjectedInterfaces() { - // Hash the interfaces we're about to inject to not have to repeat this everytime - Hasher hasher = Hashing.sha256().newHasher(); - - for (Map.Entry> entry : injectedInterfaces.entrySet()) { - hasher.putString("class:", StandardCharsets.UTF_8); - hasher.putString(entry.getKey(), StandardCharsets.UTF_8); - - for (InjectedInterface ifaceName : entry.getValue()) { - hasher.putString("iface:", StandardCharsets.UTF_8); - hasher.putString(ifaceName.ifaceName(), StandardCharsets.UTF_8); - } - } - - return hasher.hash().asBytes(); - } } diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java index 382a54c93..f8a2e1165 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java @@ -24,21 +24,22 @@ package net.fabricmc.loom.configuration.processors; -import org.gradle.api.Project; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; -import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.processor.ProcessorContext; +import net.fabricmc.loom.configuration.ConfigContext; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJar; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; +import net.fabricmc.loom.util.TinyRemapperHelper; +import net.fabricmc.tinyremapper.TinyRemapper; -public record ProcessorContextImpl(MinecraftJarConfiguration jarConfiguration, MinecraftJar minecraftJar) implements ProcessorContext { - public static ProcessorContext create(Project project, MinecraftJar minecraftJar) { - return new ProcessorContextImpl(LoomGradleExtension.get(project).getMinecraftJarConfiguration().get(), minecraftJar); - } - +public record ProcessorContextImpl(ConfigContext configContext, MinecraftJar minecraftJar) implements ProcessorContext { @Override public MinecraftJarConfiguration getJarConfiguration() { - return jarConfiguration; + return configContext.extension().getMinecraftJarConfiguration().get(); } @Override @@ -55,4 +56,20 @@ public boolean includesClient() { public boolean includesServer() { return minecraftJar.includesServer(); } + + @Override + public TinyRemapper createRemapper(MappingsNamespace from, MappingsNamespace to) { + try { + TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(configContext().project(), configContext().serviceManager(), from.toString(), to.toString()); + tinyRemapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(configContext.project())); + + for (Path minecraftJar : configContext.extension().getMinecraftJars(MappingsNamespace.INTERMEDIARY)) { + tinyRemapper.readClassPath(minecraftJar); + } + + return tinyRemapper; + } catch (IOException e) { + throw new UncheckedIOException("Failed to create tiny remapper", e); + } + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java index 50567c970..996fd8d26 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java @@ -27,11 +27,15 @@ import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; import org.gradle.api.Project; import org.gradle.api.tasks.SourceSet; @@ -47,9 +51,9 @@ * @param modDependencies External mods that are depended on * @param localMods The main mod being built. In the future this may also include other mods. */ -public record SpecContextImpl(List modDependencies, List localMods) implements SpecContext { +public record SpecContextImpl(List modDependencies, List localMods, List compileRuntimeMods) implements SpecContext { public static SpecContextImpl create(Project project) { - return new SpecContextImpl(getDependentMods(project), getMods(project)); + return new SpecContextImpl(getDependentMods(project), getMods(project), getCompileRuntimeMods(project)); } private static List getDependentMods(Project project) { @@ -95,8 +99,33 @@ private static List getMods(Project project) { return Collections.emptyList(); } + private static List getCompileRuntimeMods(Project project) { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + final Function> resolve = settings -> + settings.getSourceConfiguration().get().resolve().stream() + .map(File::toPath); + + final List runtimeEntries = extension.getRuntimeRemapConfigurations().stream() + .flatMap(resolve) + .toList(); + + return extension.getCompileRemapConfigurations().stream() + .flatMap(resolve) + .filter(runtimeEntries::contains) // Use the intersection of the two configurations. + .map(FabricModJsonFactory::createFromZipOptional) + .filter(Optional::isPresent) + .map(Optional::get) + .sorted(Comparator.comparing(FabricModJson::getId)) + .toList(); + } + // Sort to ensure stable caching private static List sorted(List mods) { return mods.stream().sorted(Comparator.comparing(FabricModJson::getId)).toList(); } + + @Override + public List modDependenciesCompileRuntime() { + return compileRuntimeMods; + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java index c1ba3920b..1b32fed0c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java @@ -220,8 +220,6 @@ private void evaluate(Project project) { // The client only sources to the combined sources jar. jar.from(clientOnlySourceSet.getAllSource()); }); - - extension.getInterfaceInjection().getInterfaceInjectionSourceSets().add(clientOnlySourceSet); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java index 2a4d8901a..18413335c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java @@ -92,7 +92,7 @@ private void processJars() throws IOException { Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING); - jarProcessorManager.processJar(outputJar, ProcessorContextImpl.create(getProject(), minecraftJar)); + jarProcessorManager.processJar(outputJar, new ProcessorContextImpl(configContext, minecraftJar)); } } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index fd81d2853..cebfaf08f 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -136,6 +136,7 @@ protected LoomGradleExtensionApiImpl(Project project, LoomFiles directories) { this.splitModDependencies.finalizeValueOnRead(); this.interfaceInjectionExtension = project.getObjects().newInstance(InterfaceInjectionExtensionAPI.class); + this.interfaceInjectionExtension.getIsEnabled().convention(true); this.splitEnvironmentalSourceSet = project.getObjects().property(Boolean.class).convention(false); this.splitEnvironmentalSourceSet.finalizeValueOnRead(); diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index bca591890..45a604883 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -66,7 +66,6 @@ import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.processor.MappingProcessorContext; import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerMappingsProcessor; -import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.decompilers.LineNumberRemapper; import net.fabricmc.loom.util.Constants; @@ -335,10 +334,6 @@ private Path getMappings() { mappingsProcessors.add(new TransitiveAccessWidenerMappingsProcessor(getProject())); } - if (getExtension().getInterfaceInjection().isEnabled()) { - mappingsProcessors.add(new InterfaceInjectionProcessor(getProject())); - } - MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(getProject()); if (minecraftJarProcessorManager != null) { diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java index 812b385f9..917ef1235 100644 --- a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java @@ -33,6 +33,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Optional; import com.google.gson.JsonObject; import org.gradle.api.tasks.SourceSet; @@ -91,6 +92,10 @@ public static FabricModJson createFromZipNullable(Path zipPath) { return create(jsonObject, new FabricModJsonSource.ZipSource(zipPath)); } + public static Optional createFromZipOptional(Path zipPath) { + return Optional.ofNullable(createFromZipNullable(zipPath)); + } + public static FabricModJson createFromDirectory(Path directory) throws IOException { final Path path = directory.resolve(FABRIC_MOD_JSON); From ccc3e77fe1f62ed0a5c7af5a236297541028ca6a Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 9 Oct 2022 14:56:45 +0100 Subject: [PATCH 11/13] Only use mixin mappings from projects with the same mapping id. --- .../loom/task/service/TinyRemapperService.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java index 5e38ef8cd..298cdd468 100644 --- a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java @@ -84,7 +84,7 @@ public static synchronized TinyRemapperService getOrCreate(SharedServiceManager mappings.add(MappingsService.createDefault(project, serviceManager, from, to).getMappingsProvider()); if (legacyMixin) { - mappings.add(gradleMixinMappingProvider(serviceManager, project.getGradle(), from, to)); + mappings.add(gradleMixinMappingProvider(serviceManager, project.getGradle(), extension.getMappingConfiguration().mappingsIdentifier, from, to)); } return new TinyRemapperService(mappings, !legacyMixin, kotlinClasspathService); @@ -96,8 +96,15 @@ public static synchronized TinyRemapperService getOrCreate(SharedServiceManager } // Add all of the mixin mappings from all loom projects. - private static IMappingProvider gradleMixinMappingProvider(SharedServiceManager serviceManager, Gradle gradle, String from, String to) { + private static IMappingProvider gradleMixinMappingProvider(SharedServiceManager serviceManager, Gradle gradle, String mappingId, String from, String to) { return out -> GradleUtils.allLoomProjects(gradle, project -> { + final LoomGradleExtension extension = LoomGradleExtension.get(project); + + if (!mappingId.equals(extension.getMappingConfiguration().mappingsIdentifier)) { + // Only find mixin mappings that are from other projects with the same mapping id. + return; + } + for (SourceSet sourceSet : SourceSetHelper.getSourceSets(project)) { final File mixinMappings = AnnotationProcessorInvoker.getMixinMappingsForSourceSet(project, sourceSet); From 5f67780824ca8fd6b7c4a2cbf97acc2f5f9684bb Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 24 Oct 2022 18:55:55 +0100 Subject: [PATCH 12/13] Update nightly gradle version. --- src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy b/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy index 8f43a6d9f..284bd4f69 100644 --- a/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/LoomTestConstants.groovy @@ -27,7 +27,7 @@ package net.fabricmc.loom.test import org.gradle.util.GradleVersion class LoomTestConstants { - private final static String NIGHTLY_VERSION = "8.0-20221001011953+0000" + private final static String NIGHTLY_VERSION = "8.0-20221022221212+0000" private final static boolean NIGHTLY_EXISTS = nightlyExists(NIGHTLY_VERSION) public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion() From e7bee0daa87ef1b7943bf8b1f7014a49a9cd1d14 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 24 Oct 2022 20:29:34 +0100 Subject: [PATCH 13/13] Store minecraft jars in a maven repo instead of an ivy repo. Improve intelij support for attaching sources. --- .../fabricmc/loom/LoomRepositoryPlugin.java | 28 ++++--- .../ide/idea/IdeaConfiguration.java | 79 ++++++++++++++++++- .../mods/dependency/LocalMavenHelper.java | 18 ++--- .../mods/dependency/ModDependency.java | 4 +- .../MinecraftJarProcessorManager.java | 4 + .../providers/minecraft/MinecraftJar.java | 43 ++++++++-- .../AbstractMappedMinecraftProvider.java | 64 ++++++++++++--- .../mapped/IntermediaryMinecraftProvider.java | 9 +-- .../mapped/MappedMinecraftProvider.java | 22 +++--- .../mapped/NamedMinecraftProvider.java | 9 +-- .../ProcessedNamedMinecraftProvider.java | 69 ++++++++-------- .../fabricmc/loom/extension/LoomFiles.java | 2 + .../loom/extension/LoomFilesBaseImpl.java | 10 +++ .../task/launch/GenerateDLIConfigTask.java | 4 +- 14 files changed, 266 insertions(+), 99 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java index c0da3e8da..ca1311363 100644 --- a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -29,7 +29,6 @@ import org.gradle.api.artifacts.ArtifactRepositoryContainer; import org.gradle.api.artifacts.dsl.RepositoryHandler; import org.gradle.api.artifacts.repositories.ArtifactRepository; -import org.gradle.api.artifacts.repositories.IvyArtifactRepository; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import org.gradle.api.initialization.Settings; import org.gradle.api.invocation.Gradle; @@ -62,10 +61,8 @@ public void apply(@NotNull PluginAware target) { } private void declareRepositories(RepositoryHandler repositories, LoomFiles files, ExtensionAware target) { - repositories.maven(repo -> { - repo.setName("UserLocalRemappedMods"); - repo.setUrl(files.getRemappedModCache()); - }); + declareLocalRepositories(repositories, files); + repositories.maven(repo -> { repo.setName("Fabric"); repo.setUrl(MirrorUtil.getFabricRepository(target)); @@ -93,17 +90,22 @@ private void declareRepositories(RepositoryHandler repositories, LoomFiles files } repositories.mavenCentral(); + } - repositories.ivy(repo -> { - repo.setUrl(files.getUserCache()); - repo.patternLayout(layout -> layout.artifact("[revision]/[artifact](-[classifier])(.[ext])")); - repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + private void declareLocalRepositories(RepositoryHandler repositories, LoomFiles files) { + repositories.maven(repo -> { + repo.setName("LoomLocalRemappedMods"); + repo.setUrl(files.getRemappedModCache()); }); - repositories.ivy(repo -> { - repo.setUrl(files.getRootProjectPersistentCache()); - repo.patternLayout(layout -> layout.artifact("[revision]/[artifact](-[classifier])(.[ext])")); - repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + repositories.maven(repo -> { + repo.setName("LoomGlobalMinecraft"); + repo.setUrl(files.getGlobalMinecraftRepo()); + }); + + repositories.maven(repo -> { + repo.setName("LoomLocalMinecraft"); + repo.setUrl(files.getLocalMinecraftRepo()); }); } diff --git a/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java index 71029e8f9..f1cb169fa 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2021 FabricMC + * Copyright (c) 2021-2022 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 @@ -24,20 +24,32 @@ package net.fabricmc.loom.configuration.ide.idea; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.gradle.StartParameter; import org.gradle.TaskExecutionRequest; import org.gradle.api.Project; +import org.gradle.api.Task; import org.gradle.api.tasks.TaskProvider; import org.gradle.internal.DefaultTaskExecutionRequest; +import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.configuration.ide.RunConfigSettings; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.task.LoomTasks; public class IdeaConfiguration { + private static final String INIT_SCRIPT_NAME = "ijmiscinit"; + private static final Pattern NOTATION_PATTERN = Pattern.compile("'net\\.minecraft:(?.*):(.*):sources'"); + public static void setup(Project project) { TaskProvider ideaSyncTask = project.getTasks().register("ideaSyncTask", IdeaSyncTask.class, task -> { if (LoomGradleExtension.get(project).getRunConfigs().stream().anyMatch(RunConfigSettings::isIdeConfigGenerated)) { @@ -47,6 +59,12 @@ public static void setup(Project project) { } }); + project.getTasks().configureEach(task -> { + if (task.getName().equals("DownloadSources")) { + hookDownloadSources(project, task); + } + }); + if (!IdeaUtils.isIdeaSync()) { return; } @@ -57,4 +75,63 @@ public static void setup(Project project) { taskRequests.add(new DefaultTaskExecutionRequest(List.of("ideaSyncTask"))); startParameter.setTaskRequests(taskRequests); } + + /* + "Parse" the init script enough to figure out what jar we are talking about. + + Intelij code: https://github.com/JetBrains/intellij-community/blob/a09b1b84ab64a699794c860bc96774766dd38958/plugins/gradle/java/src/util/GradleAttachSourcesProvider.java + */ + private static void hookDownloadSources(Project project, Task task) { + List initScripts = project.getGradle().getStartParameter().getInitScripts(); + + for (File initScript : initScripts) { + if (!initScript.getName().contains(INIT_SCRIPT_NAME)) { + continue; + } + + try { + final String script = Files.readString(initScript.toPath(), StandardCharsets.UTF_8); + final String notation = parseInitScript(project, script); + + if (notation != null) { + task.dependsOn(getGenSourcesTaskName(LoomGradleExtension.get(project), notation)); + } + } catch (IOException e) { + // Ignore + } + } + } + + @Nullable + private static String parseInitScript(Project project, String script) { + if (!script.contains("Attempt to download sources from") + || !script.contains("downloadSources_") + || !script.contains("'%s'".formatted(project.getPath()))) { + // Failed some basic sanity checks. + return null; + } + + // A little gross but should do the job nicely. + final Matcher matcher = NOTATION_PATTERN.matcher(script); + + if (matcher.find()) { + return matcher.group("name"); + } + + return null; + } + + private static String getGenSourcesTaskName(LoomGradleExtension extension, String notation) { + final MinecraftJarConfiguration configuration = extension.getMinecraftJarConfiguration().get(); + + if (configuration == MinecraftJarConfiguration.SPLIT) { + if (notation.contains("minecraft-clientOnly")) { + return "genClientOnlySources"; + } + + return "genCommonSources"; + } + + return "genSources"; + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java index 4d7e31e7a..33af9b963 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/LocalMavenHelper.java @@ -32,25 +32,22 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import org.gradle.api.Project; import org.jetbrains.annotations.Nullable; -import net.fabricmc.loom.LoomGradleExtension; - public final class LocalMavenHelper { private final String group; private final String name; private final String version; @Nullable private final String baseClassifier; - private final Project project; + private final Path root; - LocalMavenHelper(String group, String name, String version, @Nullable String classifier, Project project) { + public LocalMavenHelper(String group, String name, String version, @Nullable String classifier, Path root) { this.group = group; this.name = name; this.version = version; this.baseClassifier = classifier; - this.project = project; + this.root = root; } public Path copyToMaven(Path artifact, @Nullable String classifier) throws IOException { @@ -75,7 +72,7 @@ public String getNotation() { return String.format("%s:%s:%s", group, name, version); } - private void savePom() { + public void savePom() { try { String pomTemplate; @@ -94,13 +91,8 @@ private void savePom() { } } - private Path getRoot() { - final LoomGradleExtension extension = LoomGradleExtension.get(project); - return extension.getFiles().getRemappedModCache().toPath(); - } - private Path getDirectory() { - return getRoot().resolve("%s/%s/%s".formatted(group.replace(".", "/"), name, version)); + return root.resolve("%s/%s/%s".formatted(group.replace(".", "/"), name, version)); } private Path getPomPath() { diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java index 2cde009cc..bfcd0b022 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/dependency/ModDependency.java @@ -69,7 +69,9 @@ public ModDependency(ArtifactRef artifact, String mappingsSuffix, Project projec public abstract void applyToProject(Project project); protected LocalMavenHelper createMaven(String name) { - return new LocalMavenHelper(getRemappedGroup(), name, this.version, this.classifier, this.project); + final LoomGradleExtension extension = LoomGradleExtension.get(project); + final Path root = extension.getFiles().getRemappedModCache().toPath(); + return new LocalMavenHelper(getRemappedGroup(), name, this.version, this.classifier, root); } public ArtifactRef getInputArtifact() { diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java index 609045fec..291cfa46b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftJarProcessorManager.java @@ -152,6 +152,10 @@ private void processJar(Path jar, ProcessorContext context) throws IOException { } private boolean processMappings(MemoryMappingTree mappings, MappingProcessorContext context) { + if (mappingsProcessor() == null) { + return false; + } + return mappingsProcessor().transform(mappings, spec, context); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java index 4e18410fd..6686a1311 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJar.java @@ -24,24 +24,31 @@ package net.fabricmc.loom.configuration.providers.minecraft; +import java.io.File; import java.nio.file.Path; import java.util.Objects; public abstract sealed class MinecraftJar permits MinecraftJar.Merged, MinecraftJar.Common, MinecraftJar.ServerOnly, MinecraftJar.ClientOnly { private final Path path; private final boolean merged, client, server; + private final String name; - protected MinecraftJar(Path path, boolean merged, boolean client, boolean server) { + protected MinecraftJar(Path path, boolean merged, boolean client, boolean server, String name) { this.path = Objects.requireNonNull(path); this.merged = merged; this.client = client; this.server = server; + this.name = name; } public Path getPath() { return path; } + public File toFile() { + return getPath().toFile(); + } + public boolean isMerged() { return merged; } @@ -54,27 +61,53 @@ public boolean includesServer() { return server; } + public String getName() { + return name; + } + + public abstract MinecraftJar forPath(Path path); + public static final class Merged extends MinecraftJar { public Merged(Path path) { - super(path, true, true, true); + super(path, true, true, true, "merged"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new Merged(path); } } public static final class Common extends MinecraftJar { public Common(Path path) { - super(path, false, false, true); + super(path, false, false, true, "common"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new Common(path); } } public static final class ServerOnly extends MinecraftJar { public ServerOnly(Path path) { - super(path, false, false, true); + super(path, false, false, true, "serverOnly"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new ServerOnly(path); } } public static final class ClientOnly extends MinecraftJar { public ClientOnly(Path path) { - super(path, false, true, false); + super(path, false, true, false, "clientOnly"); + } + + @Override + public MinecraftJar forPath(Path path) { + return new ClientOnly(path); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java index 635502259..d88d3dd9d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java @@ -24,22 +24,28 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.function.Function; import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.ConfigContext; +import net.fabricmc.loom.configuration.mods.dependency.LocalMavenHelper; import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJar; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets; import net.fabricmc.loom.configuration.providers.minecraft.SignatureFixerApplyVisitor; +import net.fabricmc.loom.extension.LoomFiles; import net.fabricmc.loom.util.TinyRemapperHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; @@ -91,24 +97,53 @@ public void provide(boolean applyDependencies) throws Exception { } } - protected abstract Path getDirectory(); - @Override public Path getJar(String name) { - return getDirectory().resolve(getName(name) + ".jar"); + return getMavenHelper(name).getOutputFile(null); + } + + public enum MavenScope { + // Output files will be stored per project + LOCAL(LoomFiles::getLocalMinecraftRepo), + // Output files will be stored globally + GLOBAL(LoomFiles::getGlobalMinecraftRepo); + + private final Function fileFunction; + + MavenScope(Function fileFunction) { + this.fileFunction = fileFunction; + } + + public Path getRoot(LoomGradleExtension extension) { + return fileFunction.apply(extension.getFiles()).toPath(); + } + } + + public abstract MavenScope getMavenScope(); + + public LocalMavenHelper getMavenHelper(String name) { + return new LocalMavenHelper("net.minecraft", getName(name), getVersion(), null, getMavenScope().getRoot(extension)); } protected String getName(String name) { - return "minecraft-%s-%s".formatted(name, getTargetNamespace().toString()); + if (getTargetNamespace() != MappingsNamespace.NAMED) { + name = getTargetNamespace().name().toLowerCase(Locale.ROOT) + "-" + name; + } + + return "minecraft-" + name; + } + + protected String getVersion() { + return "%s-%s".formatted(extension.getMinecraftProvider().minecraftVersion(), extension.getMappingConfiguration().mappingsIdentifier()); } protected String getDependencyNotation(String name) { - return "net.minecraft:%s:%s/%s".formatted(getName(name), extension.getMinecraftProvider().minecraftVersion(), extension.getMappingConfiguration().mappingsIdentifier()); + return "net.minecraft:%s:%s".formatted(getName(name), getVersion()); } private boolean areOutputsValid(List remappedJars) { for (RemappedJars remappedJar : remappedJars) { - if (!Files.exists(remappedJar.outputJar())) { + if (!getMavenHelper(remappedJar.name()).exists(null)) { return false; } } @@ -129,7 +164,7 @@ private void remapJar(RemappedJars remappedJars) throws IOException { final String fromM = remappedJars.sourceNamespace().toString(); final String toM = getTargetNamespace().toString(); - Files.deleteIfExists(remappedJars.outputJar()); + Files.deleteIfExists(remappedJars.outputJarPath()); final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceManager(), toM); TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(getProject(), configContext.serviceManager(), fromM, toM, true, (builder) -> { @@ -137,7 +172,7 @@ private void remapJar(RemappedJars remappedJars) throws IOException { configureRemapper(remappedJars, builder); }); - try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(remappedJars.outputJar()).build()) { + try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(remappedJars.outputJarPath()).build()) { outputConsumer.addNonClassFiles(remappedJars.inputJar()); remapper.readClassPath(TinyRemapperHelper.getMinecraftDependencies(getProject())); @@ -152,6 +187,8 @@ private void remapJar(RemappedJars remappedJars) throws IOException { } finally { remapper.finish(); } + + getMavenHelper(remappedJars.name()).savePom(); } protected void configureRemapper(RemappedJars remappedJars, TinyRemapper.Builder tinyRemapperBuilder) { @@ -159,7 +196,7 @@ protected void configureRemapper(RemappedJars remappedJars, TinyRemapper.Builder private void cleanOutputs(List remappedJars) throws IOException { for (RemappedJars remappedJar : remappedJars) { - Files.deleteIfExists(remappedJar.outputJar()); + Files.deleteIfExists(remappedJar.outputJarPath()); } } @@ -175,6 +212,13 @@ public M getMinecraftProvider() { return minecraftProvider; } - public record RemappedJars(Path inputJar, Path outputJar, MappingsNamespace sourceNamespace, Path... remapClasspath) { + public record RemappedJars(Path inputJar, MinecraftJar outputJar, MappingsNamespace sourceNamespace, Path... remapClasspath) { + public Path outputJarPath() { + return outputJar().getPath(); + } + + public String name() { + return outputJar().getName(); + } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java index 4f1e07ccf..76f962f93 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/IntermediaryMinecraftProvider.java @@ -24,7 +24,6 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; -import java.nio.file.Path; import java.util.List; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; @@ -43,13 +42,13 @@ public IntermediaryMinecraftProvider(ConfigContext configContext, M minecraftPro } @Override - protected Path getDirectory() { - return extension.getMinecraftProvider().workingDir().toPath(); + public final MappingsNamespace getTargetNamespace() { + return MappingsNamespace.INTERMEDIARY; } @Override - public final MappingsNamespace getTargetNamespace() { - return MappingsNamespace.INTERMEDIARY; + public MavenScope getMavenScope() { + return MavenScope.GLOBAL; } public static final class MergedImpl extends IntermediaryMinecraftProvider implements Merged { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java index 73b0caa93..4ea323493 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/MappedMinecraftProvider.java @@ -44,13 +44,13 @@ interface ProviderImpl extends MappedMinecraftProvider { interface Merged extends ProviderImpl { String MERGED = "merged"; - default Path getMergedJar() { - return getJar(MERGED); + default MinecraftJar getMergedJar() { + return new MinecraftJar.Merged(getJar(MERGED)); } @Override default List getMinecraftJars() { - return List.of(new MinecraftJar.Merged(getMergedJar())); + return List.of(getMergedJar()); } } @@ -58,17 +58,17 @@ interface Split extends ProviderImpl { String COMMON = "common"; String CLIENT_ONLY = "clientOnly"; - default Path getCommonJar() { - return getJar(COMMON); + default MinecraftJar getCommonJar() { + return new MinecraftJar.Common(getJar(COMMON)); } - default Path getClientOnlyJar() { - return getJar(CLIENT_ONLY); + default MinecraftJar getClientOnlyJar() { + return new MinecraftJar.ClientOnly(getJar(CLIENT_ONLY)); } @Override default List getMinecraftJars() { - return List.of(new MinecraftJar.Common(getCommonJar()), new MinecraftJar.ClientOnly(getClientOnlyJar())); + return List.of(getCommonJar(), getClientOnlyJar()); } } @@ -79,13 +79,13 @@ default String envName() { return "%sOnly".formatted(env()); } - default Path getEnvOnlyJar() { - return getJar(envName()); + default MinecraftJar getEnvOnlyJar() { + return env().getJar().apply(getJar(envName())); } @Override default List getMinecraftJars() { - return List.of(env().getJar().apply(getEnvOnlyJar())); + return List.of(getEnvOnlyJar()); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java index 97de6d967..bf66d5be0 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/NamedMinecraftProvider.java @@ -24,7 +24,6 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; -import java.nio.file.Path; import java.util.List; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; @@ -43,13 +42,13 @@ public NamedMinecraftProvider(ConfigContext configContext, M minecraftProvider) } @Override - protected Path getDirectory() { - return extension.getMappingConfiguration().mappingsWorkingDir(); + public final MappingsNamespace getTargetNamespace() { + return MappingsNamespace.NAMED; } @Override - public final MappingsNamespace getTargetNamespace() { - return MappingsNamespace.NAMED; + public MavenScope getMavenScope() { + return MavenScope.GLOBAL; } public static final class MergedImpl extends NamedMinecraftProvider implements Merged { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java index 18413335c..d3297130d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/ProcessedNamedMinecraftProvider.java @@ -25,14 +25,14 @@ package net.fabricmc.loom.configuration.providers.minecraft.mapped; import java.io.IOException; -import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.List; import java.util.Objects; -import net.fabricmc.loom.LoomGradleExtension; +import org.gradle.api.Project; + +import net.fabricmc.loom.configuration.mods.dependency.LocalMavenHelper; import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.processors.ProcessorContextImpl; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; @@ -46,20 +46,11 @@ public abstract class ProcessedNamedMinecraftProvider> extends NamedMinecraftProvider { private final P parentMinecraftProvider; private final MinecraftJarProcessorManager jarProcessorManager; - private final String projectMappedName; - private final Path projectMappedDir; public ProcessedNamedMinecraftProvider(P parentMinecraftProvide, MinecraftJarProcessorManager jarProcessorManager) { super(parentMinecraftProvide.getConfigContext(), parentMinecraftProvide.getMinecraftProvider()); this.parentMinecraftProvider = parentMinecraftProvide; this.jarProcessorManager = Objects.requireNonNull(jarProcessorManager); - - this.projectMappedName = "minecraft-project-%s-".formatted(getProject().getPath().replace(':', '@')); - - final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); - this.projectMappedDir = extension.getFiles().getRootProjectPersistentCache().toPath() - .resolve(getMinecraftProvider().minecraftVersion()) - .resolve(extension.getMappingConfiguration().mappingsIdentifier()); } @Override @@ -78,21 +69,20 @@ public void provide(boolean applyDependencies) throws Exception { } } - private void processJars() throws IOException { - try { - Files.createDirectories(projectMappedDir); - } catch (IOException e) { - throw new UncheckedIOException("Failed to create project mapped dir", e); - } + @Override + public MavenScope getMavenScope() { + return MavenScope.LOCAL; + } + private void processJars() throws IOException { for (MinecraftJar minecraftJar : parentMinecraftProvider.getMinecraftJars()) { - Path inputJar = minecraftJar.getPath(); - final Path outputJar = getProcessedPath(inputJar); - deleteSimilarJars(outputJar); + final MinecraftJar outputJar = getProcessedPath(minecraftJar); + deleteSimilarJars(outputJar.getPath()); - Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING); + final LocalMavenHelper mavenHelper = getMavenHelper(minecraftJar.getName()); + final Path outputPath = mavenHelper.copyToMaven(minecraftJar.getPath(), null); - jarProcessorManager.processJar(outputJar, new ProcessorContextImpl(configContext, minecraftJar)); + jarProcessorManager.processJar(outputPath, new ProcessorContextImpl(configContext, minecraftJar)); } } @@ -111,8 +101,13 @@ private void applyDependencies() { private void deleteSimilarJars(Path jar) throws IOException { Files.deleteIfExists(jar); + final Path parent = jar.getParent(); + + if (Files.notExists(parent)) { + return; + } - for (Path path : Files.list(jar.getParent()).filter(Files::isRegularFile) + for (Path path : Files.list(parent).filter(Files::isRegularFile) .filter(path -> path.getFileName().startsWith(jar.getFileName().toString().replace(".jar", ""))).toList()) { Files.deleteIfExists(path); } @@ -120,7 +115,14 @@ private void deleteSimilarJars(Path jar) throws IOException { @Override protected String getName(String name) { - return "%s%s-%s".formatted(projectMappedName, name, getTargetNamespace().toString()); + final Project project = getProject(); + + if (project.getRootProject() == project) { + return "minecraft-%s-project-root".formatted(name); + } + + final String projectPath = project.getPath().replace(':', '@'); + return "minecraft-%s-project-%s".formatted(name, projectPath); } @Override @@ -135,8 +137,8 @@ public List getRemappedJars() { } @Override - public List getMinecraftJarPaths() { - return getParentMinecraftProvider().getMinecraftJarPaths().stream() + public List getMinecraftJars() { + return getParentMinecraftProvider().getMinecraftJars().stream() .map(this::getProcessedPath) .toList(); } @@ -145,8 +147,9 @@ public P getParentMinecraftProvider() { return parentMinecraftProvider; } - public Path getProcessedPath(Path input) { - return projectMappedDir.resolve(input.getFileName().toString().replace("minecraft-", projectMappedName)); + public MinecraftJar getProcessedPath(MinecraftJar minecraftJar) { + final Path path = getMavenHelper(minecraftJar.getName()).getOutputFile(null); + return minecraftJar.forPath(path); } public static final class MergedImpl extends ProcessedNamedMinecraftProvider implements Merged { @@ -155,7 +158,7 @@ public MergedImpl(NamedMinecraftProvider.MergedImpl parentMinecraftProvide, Mine } @Override - public Path getMergedJar() { + public MinecraftJar getMergedJar() { return getProcessedPath(getParentMinecraftProvider().getMergedJar()); } } @@ -166,12 +169,12 @@ public SplitImpl(NamedMinecraftProvider.SplitImpl parentMinecraftProvide, Minecr } @Override - public Path getCommonJar() { + public MinecraftJar getCommonJar() { return getProcessedPath(getParentMinecraftProvider().getCommonJar()); } @Override - public Path getClientOnlyJar() { + public MinecraftJar getClientOnlyJar() { return getProcessedPath(getParentMinecraftProvider().getClientOnlyJar()); } } @@ -193,7 +196,7 @@ public static ProcessedNamedMinecraftProvider.SingleJarImpl client(NamedMinecraf } @Override - public Path getEnvOnlyJar() { + public MinecraftJar getEnvOnlyJar() { return getProcessedPath(getParentMinecraftProvider().getEnvOnlyJar()); } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomFiles.java b/src/main/java/net/fabricmc/loom/extension/LoomFiles.java index 6e5e0f12b..9d115ab0b 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomFiles.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomFiles.java @@ -48,4 +48,6 @@ static LoomFiles create(Settings settings) { File getDevLauncherConfig(); File getUnpickLoggingConfigFile(); File getRemapClasspathFile(); + File getGlobalMinecraftRepo(); + File getLocalMinecraftRepo(); } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomFilesBaseImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomFilesBaseImpl.java index 16752f5d1..d7f0c469b 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomFilesBaseImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomFilesBaseImpl.java @@ -97,4 +97,14 @@ public File getUnpickLoggingConfigFile() { public File getRemapClasspathFile() { return new File(getProjectPersistentCache(), "remapClasspath.txt"); } + + @Override + public File getGlobalMinecraftRepo() { + return new File(getUserCache(), "minecraftMaven"); + } + + @Override + public File getLocalMinecraftRepo() { + return new File(getRootProjectPersistentCache(), "minecraftMaven"); + } } diff --git a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java index 49a6b1c12..7176e985c 100644 --- a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java +++ b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java @@ -105,8 +105,8 @@ private String getGameJarPath(String env) { MappedMinecraftProvider.Split split = (MappedMinecraftProvider.Split) getExtension().getNamedMinecraftProvider(); return switch (env) { - case "client" -> split.getClientOnlyJar().toAbsolutePath().toString(); - case "common" -> split.getCommonJar().toAbsolutePath().toString(); + case "client" -> split.getClientOnlyJar().getPath().toAbsolutePath().toString(); + case "common" -> split.getCommonJar().getPath().toAbsolutePath().toString(); default -> throw new UnsupportedOperationException(); }; }