From 81fa551382d9c7016f769014ed56d119a3d676ed Mon Sep 17 00:00:00 2001 From: LogicFan <38597904+LogicFan@users.noreply.github.com> Date: Sun, 18 Jul 2021 09:13:47 -0400 Subject: [PATCH] Better Mixin AP configuration (#423) * [SPON-15] Apply Mixin AP config for all projects. * Revert "[SPON-15] Apply Mixin AP config for all projects." This reverts commit 93576e83b1221949d551b6307938f7dd6dc8fbbe. * use setter & getter * fix broken test introduced in 54d6ef7896f22f89d6594703d09e3195c814cf10 * initial commit for mixin extension * refactor getConfiguration * apply mixin extension * [SPON-15] allow across project AP config * [SPON-15] revert some changes * [SPON-15] refactor codes * [SPON-15] fix bugs * [SPON-15] bring back cross-project apconfig * [SPON-15] bug fix: move add default sourceSet earlier * [SPON-15] fix style * [SPON-15] refactor MixinAPExtension * add test * update test * [SPON-15] fix test * Update MixinAnnotationProcessorExtension.java * [SPON-15] fix test * fix deprecated gradle API * [SPON-15] refactor ApInvoker * [SPON-15] refactor ApInvoker * allow change refmap name in sourceSet bases * add new condition on test * [SPON-15] fix wrong suffix * Revert "[SPON-15] fix wrong suffix" This reverts commit 98910392d91c26cd0454cca8cfc03c4e3d417fd6. * fix mixinjson suffix * use stream instead of collection for mixin json name * change name for function * use correct auto-refmap * fix file name * add with action * add test * refactor some codes * refactor code * update test * fix checkstyle * better error message * fix checkstyle * remove corss project option * allow mixin inside loom * remove project0 I should remove all project0. If I forget one please tell me. * move `mixin` inside `loom` * fix spotless * merge attempt * fix checkstyle * seperate api & impl * add experimental annotation for API * use API * Fix indentation Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com> * fix typo Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com> * fix typo Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com> * better javadoc Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com> --- .../fabricmc/loom/LoomGradleExtension.java | 3 + .../loom/api/LoomGradleExtensionAPI.java | 4 + .../loom/api/MixinApExtensionAPI.java | 92 ++++++++++++ .../loom/build/MixinRefmapHelper.java | 60 +++----- .../mixin/AnnotationProcessorInvoker.java | 56 +++---- .../loom/build/mixin/JavaApInvoker.java | 29 ++-- .../loom/build/mixin/KaptApInvoker.java | 38 ++--- .../loom/build/mixin/ScalaApInvoker.java | 24 ++- .../configuration/CompileConfiguration.java | 4 + .../extension/LoomGradleExtensionApiImpl.java | 13 ++ .../extension/LoomGradleExtensionImpl.java | 7 + .../loom/extension/MixinApExtension.java | 126 ++++++++++++++++ .../extension/MixinApExtensionApiImpl.java | 110 ++++++++++++++ .../loom/extension/MixinApExtensionImpl.java | 125 ++++++++++++++++ .../net/fabricmc/loom/task/RemapJarTask.java | 2 +- .../integration/MixinApAutoRefmapTest.groovy | 73 +++++++++ .../test/integration/MixinApSimpleTest.groovy | 63 ++++++++ .../projects/mixinApAutoRefmap/build.gradle | 139 ++++++++++++++++++ .../mixinApAutoRefmap/gradle.properties | 16 ++ .../mixinApAutoRefmap/settings.gradle | 10 ++ .../java/net/fabricmc/example/ExampleMod.java | 14 ++ .../example/mixin/ExampleMixinMain.java | 15 ++ .../src/main/resources/assets/modid/icon.png | Bin 0 -> 453 bytes .../src/main/resources/fabric.mod.json | 37 +++++ .../src/main/resources/main.mixins.json | 14 ++ .../fabricmc/example/mixin/ExampleMixin0.java | 15 ++ .../src/mixin/resources/m0.mixins.json | 14 ++ .../example/mixin/ExampleMixin1_1.java | 15 ++ .../example/mixin/ExampleMixin1_2.java | 15 ++ .../src/mixin1/resources/m1_1.mixins.json | 14 ++ .../src/mixin1/resources/m1_2.mixins.json | 14 ++ .../projects/mixinApSimple/build.gradle | 119 +++++++++++++++ .../projects/mixinApSimple/gradle.properties | 16 ++ .../projects/mixinApSimple/settings.gradle | 10 ++ .../java/net/fabricmc/example/ExampleMod.java | 14 ++ .../fabricmc/example/mixin/ExampleMixin1.java | 15 ++ .../src/main/resources/assets/modid/icon.png | Bin 0 -> 453 bytes .../src/main/resources/fabric.mod.json | 39 +++++ .../src/main/resources/main.mixins.json | 14 ++ .../fabricmc/example/mixin/ExampleMixin0.java | 15 ++ .../src/mixin/resources/m0.mixins.json | 14 ++ .../fabricmc/example/mixin/ExampleMixin1.java | 15 ++ .../src/mixin1/resources/m1.mixins.json | 14 ++ 43 files changed, 1342 insertions(+), 104 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/api/MixinApExtensionAPI.java create mode 100644 src/main/java/net/fabricmc/loom/extension/MixinApExtension.java create mode 100644 src/main/java/net/fabricmc/loom/extension/MixinApExtensionApiImpl.java create mode 100644 src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java create mode 100644 src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy create mode 100644 src/test/groovy/net/fabricmc/loom/test/integration/MixinApSimpleTest.groovy create mode 100644 src/test/resources/projects/mixinApAutoRefmap/build.gradle create mode 100644 src/test/resources/projects/mixinApAutoRefmap/gradle.properties create mode 100644 src/test/resources/projects/mixinApAutoRefmap/settings.gradle create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/ExampleMod.java create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/mixin/ExampleMixinMain.java create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/main/resources/assets/modid/icon.png create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/main/resources/main.mixins.json create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/m0.mixins.json create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_1.java create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_2.java create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_1.mixins.json create mode 100644 src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_2.mixins.json create mode 100644 src/test/resources/projects/mixinApSimple/build.gradle create mode 100644 src/test/resources/projects/mixinApSimple/gradle.properties create mode 100644 src/test/resources/projects/mixinApSimple/settings.gradle create mode 100644 src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/ExampleMod.java create mode 100644 src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/mixin/ExampleMixin1.java create mode 100644 src/test/resources/projects/mixinApSimple/src/main/resources/assets/modid/icon.png create mode 100644 src/test/resources/projects/mixinApSimple/src/main/resources/fabric.mod.json create mode 100644 src/test/resources/projects/mixinApSimple/src/main/resources/main.mixins.json create mode 100644 src/test/resources/projects/mixinApSimple/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java create mode 100644 src/test/resources/projects/mixinApSimple/src/mixin/resources/m0.mixins.json create mode 100644 src/test/resources/projects/mixinApSimple/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1.java create mode 100644 src/test/resources/projects/mixinApSimple/src/mixin1/resources/m1.mixins.json diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 8cb82c6..2705898 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -44,6 +44,7 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; import net.fabricmc.loom.extension.LoomFiles; import net.fabricmc.loom.extension.LoomGradleExtensionImpl; +import net.fabricmc.loom.extension.MixinApExtension; public interface LoomGradleExtension extends LoomGradleExtensionAPI { static LoomGradleExtension get(Project project) { @@ -102,4 +103,6 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { // TODO reimplement a way to change this, was never really supported api anyway return String.format("https://maven.fabricmc.net/net/fabricmc/intermediary/%1$s/intermediary-%1$s-v2.jar", minecraftVersion); } + + MixinApExtension getMixinApExtension(); } diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java index 72e6695..e4d3e93 100644 --- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java @@ -31,6 +31,7 @@ import org.gradle.api.Action; import org.gradle.api.NamedDomainObjectContainer; import org.gradle.api.artifacts.Dependency; import org.gradle.api.file.ConfigurableFileCollection; +import org.jetbrains.annotations.ApiStatus; import net.fabricmc.loom.api.decompilers.LoomDecompiler; import net.fabricmc.loom.configuration.ide.RunConfigSettings; @@ -81,6 +82,9 @@ public interface LoomGradleExtensionAPI { NamedDomainObjectContainer getRunConfigs(); + @ApiStatus.Experimental + void mixin(Action action); + void setCustomManifest(String customManifest); String getCustomManifest(); diff --git a/src/main/java/net/fabricmc/loom/api/MixinApExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/MixinApExtensionAPI.java new file mode 100644 index 0000000..88b7fa7 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/api/MixinApExtensionAPI.java @@ -0,0 +1,92 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 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.api; + +import org.gradle.api.Action; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.util.PatternSet; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Experimental +public interface MixinApExtensionAPI { + /** + * Apply Mixin AP to sourceSet. + * @param sourceSet the sourceSet that applies Mixin AP. + * @param refmapName the output ref-map name. By default this will + * be {@link net.fabricmc.loom.LoomGradleExtension#getRefmapName()} + * @param action used for filter the mixin json files. By default this will be all files + * with name {@code *.mixins.json} that is inside the {@code resources} folder + * of {@code sourceSet}. + */ + void add(SourceSet sourceSet, String refmapName, Action action); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSet the sourceSet that applies Mixin AP. + * @param refmapName the output ref-map name. + */ + void add(SourceSet sourceSet, String refmapName); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSet the sourceSet that applies Mixin AP. + * @param action used for filter the mixin json files. + */ + void add(SourceSet sourceSet, Action action); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSet the sourceSet that applies Mixin AP. + */ + void add(SourceSet sourceSet); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSetName the name of sourceSet that applies Mixin AP. + * @param refmapName the output ref-map name. + * @param action used for filter the mixin json files. + */ + void add(String sourceSetName, String refmapName, Action action); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSetName the name of sourceSet that applies Mixin AP. + * @param refmapName the output ref-map name. + */ + void add(String sourceSetName, String refmapName); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSetName the name of sourceSet that applies Mixin AP. + * @param action used for filter the mixin json files. + */ + void add(String sourceSetName, Action action); + + /** + * Apply Mixin AP to sourceSet. See {@link MixinApExtensionAPI#add(SourceSet, String, Action)} for more detail. + * @param sourceSetName the name of sourceSet that applies Mixin AP. + */ + void add(String sourceSetName); +} diff --git a/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java b/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java index bc77574..458a5ff 100644 --- a/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java +++ b/src/main/java/net/fabricmc/loom/build/MixinRefmapHelper.java @@ -25,71 +25,47 @@ package net.fabricmc.loom.build; import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; import java.nio.file.Path; -import java.util.HashSet; -import java.util.Set; +import java.util.Objects; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import com.google.gson.JsonObject; +import org.gradle.api.Project; import org.zeroturnaround.zip.ZipUtil; import org.zeroturnaround.zip.transform.StringZipEntryTransformer; import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; +import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.extension.MixinApExtension; public final class MixinRefmapHelper { private MixinRefmapHelper() { } - public static boolean addRefmapName(String filename, Path outputPath) { + public static boolean addRefmapName(Project project, Path outputPath) { + MixinApExtension mixin = LoomGradleExtension.get(project).getMixinApExtension(); File output = outputPath.toFile(); - Set mixinFilenames = findMixins(output, true); - if (mixinFilenames.size() > 0) { - return ZipUtil.transformEntries(output, mixinFilenames.stream().map((f) -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { + return mixin.getMixinSourceSetsStream().map(sourceSet -> { + MixinApExtension.MixinInformationContainer container = Objects.requireNonNull( + MixinApExtension.getMixinInformationContainer(sourceSet) + ); + Stream mixinJsonNames = container.getMixinJsonNames(); + String refmapName = container.getRefmapName(); + + return ZipUtil.transformEntries(output, mixinJsonNames.map(f -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { @Override - protected String transform(ZipEntry zipEntry, String input) throws IOException { + protected String transform(ZipEntry zipEntry, String input) { JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class); if (!json.has("refmap")) { - json.addProperty("refmap", filename); + json.addProperty("refmap", refmapName); } return LoomGradlePlugin.GSON.toJson(json); } })).toArray(ZipEntryTransformerEntry[]::new)); - } else { - return false; - } - } - - private static Set findMixins(File output, boolean onlyWithoutRefmap) { - // first, identify all of the mixin files - Set mixinFilename = new HashSet<>(); - // TODO: this is a lovely hack - ZipUtil.iterate(output, (stream, entry) -> { - if (!entry.isDirectory() && entry.getName().endsWith(".json") && !entry.getName().contains("/") && !entry.getName().contains("\\")) { - // JSON file in root directory - try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { - JsonObject json = LoomGradlePlugin.GSON.fromJson(inputStreamReader, JsonObject.class); - - if (json != null) { - boolean hasMixins = json.has("mixins") && json.get("mixins").isJsonArray(); - boolean hasClient = json.has("client") && json.get("client").isJsonArray(); - boolean hasServer = json.has("server") && json.get("server").isJsonArray(); - - if (json.has("package") && (hasMixins || hasClient || hasServer)) { - if (!onlyWithoutRefmap || !json.has("refmap") || !json.has("minVersion")) { - mixinFilename.add(entry.getName()); - } - } - } - } catch (Exception ignored) { - // ... - } - } - }); - return mixinFilename; + }).reduce(false, Boolean::logicalOr); } } 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 6d0910c..04c47c9 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -29,16 +29,17 @@ import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.stream.Stream; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; -import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.TaskCollection; +import net.fabricmc.loom.extension.MixinApExtension; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.util.Constants; @@ -48,37 +49,46 @@ import net.fabricmc.loom.util.Constants; * See Java and Kapt implementations for a more deep understanding of the things passed by the children. */ public abstract class AnnotationProcessorInvoker { + public static final String JAVA = "java"; + public static final String SCALA = "scala"; + protected final Project project; - private final Collection annotationProcessorConfigurations; - protected final TaskCollection invokerTasks; + protected final Map invokerTasks; + private final Collection apConfigurations; protected AnnotationProcessorInvoker(Project project, - Collection annotationProcessorConfigurations, - TaskCollection invokerTasks) { + Collection apConfigurations, + Map invokerTasks) { this.project = project; - this.annotationProcessorConfigurations = annotationProcessorConfigurations; + this.apConfigurations = apConfigurations; this.invokerTasks = invokerTasks; } + protected static Collection getApConfigurations(Project project, Function getApConfigNameFunc) { + MixinApExtension mixin = LoomGradleExtension.get(project).getMixinApExtension(); + return mixin.getApConfigurationsStream(getApConfigNameFunc).collect(Collectors.toList()); + } + protected abstract void passArgument(T compileTask, String key, String value); - protected abstract File getDestinationDir(T task); + protected abstract File getRefmapDestinationDir(T task); - protected final String getRefmapDestination(T task, LoomGradleExtension extension) throws IOException { - return new File(getDestinationDir(task), extension.getRefmapName()).getCanonicalPath(); + protected final String getRefmapDestination(T task, String refmapName) throws IOException { + return new File(getRefmapDestinationDir(task), refmapName).getCanonicalPath(); } - private void passMixinArguments(T task) { + private void passMixinArguments(T task, SourceSet sourceSet) { try { - LoomGradleExtension extension = LoomGradleExtension.get(project); + LoomGradleExtension loom = LoomGradleExtension.get(project); + String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).getRefmapName(); Map args = new HashMap<>() {{ - put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, extension.getMappingsProvider().tinyMappings.getCanonicalPath()); - put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, extension.getNextMixinMappings().getCanonicalPath()); - put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, extension)); + put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.getCanonicalPath()); + put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, loom.getNextMixinMappings().getCanonicalPath()); + put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName)); put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:intermediary"); }}; - project.getLogger().debug("Outputting refmap to dir: " + getDestinationDir(task) + " for compile task: " + 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) { project.getLogger().error("Could not configure mixin annotation processors", e); @@ -90,7 +100,7 @@ public abstract class AnnotationProcessorInvoker { LoomGradleExtension extension = LoomGradleExtension.get(project); if (!extension.ideSync()) { - for (Configuration processorConfig : annotationProcessorConfigurations) { + for (Configuration processorConfig : apConfigurations) { project.getLogger().info("Adding mixin to classpath of AP config: " + processorConfig.getName()); // Pass named MC classpath to mixin AP classpath processorConfig.extendsFrom( @@ -105,14 +115,8 @@ public abstract class AnnotationProcessorInvoker { } } - for (T task : invokerTasks) { - passMixinArguments(task); + for (Map.Entry entry : invokerTasks.entrySet()) { + passMixinArguments(entry.getValue(), entry.getKey()); } } - - static Stream getNonTestSourceSets(Project project) { - return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets() - .stream() - .filter(sourceSet -> !sourceSet.getName().equals("test")); - } } diff --git a/src/main/java/net/fabricmc/loom/build/mixin/JavaApInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/JavaApInvoker.java index aa7d46a..a449600 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/JavaApInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/JavaApInvoker.java @@ -25,17 +25,30 @@ package net.fabricmc.loom.build.mixin; import java.io.File; -import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.compile.JavaCompile; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.extension.MixinApExtension; + public class JavaApInvoker extends AnnotationProcessorInvoker { public JavaApInvoker(Project project) { - super(project, getConfigurations(project), project.getTasks().withType(JavaCompile.class)); + super( + project, + AnnotationProcessorInvoker.getApConfigurations(project, JavaApInvoker::getAptConfigurationName), + getInvokerTasks(project)); + } + + private static Map getInvokerTasks(Project project) { + MixinApExtension mixin = LoomGradleExtension.get(project).getMixinApExtension(); + return mixin.getInvokerTasksStream(AnnotationProcessorInvoker.JAVA) + .collect(Collectors.toMap(Map.Entry::getKey, entry -> Objects.requireNonNull((JavaCompile) entry.getValue()))); } @Override @@ -44,18 +57,10 @@ public class JavaApInvoker extends AnnotationProcessorInvoker { } @Override - protected File getDestinationDir(JavaCompile task) { + protected File getRefmapDestinationDir(JavaCompile task) { return task.getDestinationDir(); } - private static List getConfigurations(Project project) { - // java plugin generates an AP configuration for every source set based off of the getAptConfigurationName method. - return AnnotationProcessorInvoker.getNonTestSourceSets(project) - .map(sourceSet -> project.getConfigurations() - .getByName(getAptConfigurationName(sourceSet.getName())) - ).collect(Collectors.toList()); - } - private static String getAptConfigurationName(String sourceSet) { // This is documented by the gradle 4.6 release notes https://docs.gradle.org/4.6/release-notes.html#potential-breaking-changes return sourceSet.equals("main") ? JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME : sourceSet + "AnnotationProcessor"; diff --git a/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java index 5632423..3fea3c6 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/KaptApInvoker.java @@ -29,18 +29,18 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import kotlin.Unit; import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.compile.JavaCompile; -import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.gradle.plugin.KaptExtension; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.extension.MixinApExtension; public class KaptApInvoker extends AnnotationProcessorInvoker { private final KaptExtension kaptExtension = project.getExtensions().getByType(KaptExtension.class); @@ -48,7 +48,10 @@ public class KaptApInvoker extends AnnotationProcessorInvoker { private final File dummyRefmapDirectory; public KaptApInvoker(Project project) { - super(project, getConfigurations(project), project.getTasks().withType(JavaCompile.class)); + super( + project, + AnnotationProcessorInvoker.getApConfigurations(project, KaptApInvoker::getKaptConfigurationName), + getInvokerTasks(project)); try { dummyRefmapDirectory = Files.createTempDirectory("temp_refmap").toFile(); @@ -62,18 +65,26 @@ public class KaptApInvoker extends AnnotationProcessorInvoker { kaptExtension.setIncludeCompileClasspath(false); } + private static Map getInvokerTasks(Project project) { + MixinApExtension mixin = LoomGradleExtension.get(project).getMixinApExtension(); + return mixin.getInvokerTasksStream(AnnotationProcessorInvoker.JAVA) + .collect(Collectors.toMap(Map.Entry::getKey, entry -> Objects.requireNonNull((JavaCompile) entry.getValue()))); + } + @Override public void configureMixin() { super.configureMixin(); - for (JavaCompile task : invokerTasks) { + for (Map.Entry entry : invokerTasks.entrySet()) { // Kapt only allows specifying javac args to all annotation processors at once. So we need to specify some dummy // target location for the refmap and then move it to the correct place for each sourceset + JavaCompile task = entry.getValue(); + SourceSet sourceSet = entry.getKey(); task.doLast(t -> { try { - LoomGradleExtension extension = LoomGradleExtension.get(project); - Path src = Paths.get(getRefmapDestination(task, extension)); - Path dest = Paths.get(task.getDestinationDir().toString(), extension.getRefmapName()); + String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).getRefmapName(); + Path src = Paths.get(getRefmapDestination(task, refmapName)); + Path dest = Paths.get(task.getDestinationDir().toString(), refmapName); // Possible that no mixin annotations exist if (Files.exists(src)) { @@ -87,15 +98,6 @@ public class KaptApInvoker extends AnnotationProcessorInvoker { } } - @NotNull - private static List getConfigurations(Project project) { - // Kapt generates an AP configuration for every source set based off of the getKaptConfigurationName method. - return AnnotationProcessorInvoker.getNonTestSourceSets(project) - .map(sourceSet -> project.getConfigurations() - .getByName(getKaptConfigurationName(sourceSet.getName())) - ).collect(Collectors.toList()); - } - // Pulled out from the internal class: https://github.com/JetBrains/kotlin/blob/33a0ec9b4f40f3d6f1f96b2db504ade4c2fafe03/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt#L92 private static String getKaptConfigurationName(String sourceSetName) { if (!sourceSetName.equals(SourceSet.MAIN_SOURCE_SET_NAME)) { @@ -116,7 +118,7 @@ public class KaptApInvoker extends AnnotationProcessorInvoker { } @Override - protected File getDestinationDir(JavaCompile task) { + protected File getRefmapDestinationDir(JavaCompile task) { return dummyRefmapDirectory; } } diff --git a/src/main/java/net/fabricmc/loom/build/mixin/ScalaApInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/ScalaApInvoker.java index bc77e15..7a3238b 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/ScalaApInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/ScalaApInvoker.java @@ -25,17 +25,31 @@ package net.fabricmc.loom.build.mixin; import java.io.File; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; import com.google.common.collect.ImmutableList; import org.gradle.api.Project; +import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.scala.ScalaCompile; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.extension.MixinApExtension; + public class ScalaApInvoker extends AnnotationProcessorInvoker { public ScalaApInvoker(Project project) { - super(project, - // Scala just uses the java AP configuration afaik. This of course assumes the java AP also gets configured. - ImmutableList.of(), - project.getTasks().withType(ScalaCompile.class)); + super( + project, + // Scala just uses the java AP configuration afaik. This of course assumes the java AP also gets configured. + ImmutableList.of(), + getInvokerTasks(project)); + } + + private static Map getInvokerTasks(Project project) { + MixinApExtension mixin = LoomGradleExtension.get(project).getMixinApExtension(); + return mixin.getInvokerTasksStream(AnnotationProcessorInvoker.SCALA) + .collect(Collectors.toMap(Map.Entry::getKey, entry -> Objects.requireNonNull((ScalaCompile) entry.getValue()))); } @Override @@ -44,7 +58,7 @@ public class ScalaApInvoker extends AnnotationProcessorInvoker { } @Override - protected File getDestinationDir(ScalaCompile task) { + protected File getRefmapDestinationDir(ScalaCompile task) { return task.getDestinationDir(); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index e2afdff..89bab1f 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -33,6 +33,7 @@ import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.api.tasks.javadoc.Javadoc; import org.gradle.jvm.tasks.Jar; +import net.fabricmc.loom.extension.MixinApExtension; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.build.mixin.JavaApInvoker; import net.fabricmc.loom.build.mixin.KaptApInvoker; @@ -143,6 +144,9 @@ public final class CompileConfiguration { System.setProperty("log4j.skipJansi", "true"); project.getLogger().info("Configuring compiler arguments for Java"); + MixinApExtension mixinApExtension = LoomGradleExtension.get(project).getMixinApExtension(); + mixinApExtension.init(); + new JavaApInvoker(project).configureMixin(); if (project.getPluginManager().hasPlugin("scala")) { diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 5c1e5f1..3d9ca87 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -36,6 +36,7 @@ import org.gradle.api.artifacts.Dependency; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.plugins.BasePluginConvention; +import net.fabricmc.loom.api.MixinApExtensionAPI; import net.fabricmc.loom.api.decompilers.LoomDecompiler; import net.fabricmc.loom.api.LoomGradleExtensionAPI; import net.fabricmc.loom.configuration.ide.RunConfigSettings; @@ -159,6 +160,11 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA return remapMod; } + @Override + public void mixin(Action action) { + action.execute(getMixinApExtension()); + } + @Override public void setCustomManifest(String customManifest) { Objects.requireNonNull(customManifest, "Custom manifest cannot be null"); @@ -174,6 +180,8 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA protected abstract LoomFiles getFiles(); + protected abstract MixinApExtension getMixinApExtension(); + // This is here to ensure that LoomGradleExtensionApiImpl compiles without any unimplemented methods private final class EnsureCompile extends LoomGradleExtensionApiImpl { private EnsureCompile() { @@ -190,5 +198,10 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA protected LoomFiles getFiles() { throw new RuntimeException("Yeah... something is really wrong"); } + + @Override + protected MixinApExtension getMixinApExtension() { + throw new RuntimeException("Yeah... something is really wrong"); + } } } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index 72fbcee..436f9b6 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -47,6 +47,7 @@ import net.fabricmc.loom.configuration.processors.JarProcessorManager; public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implements LoomGradleExtension { private final Project project; + private final MixinApExtension mixinApExtension; private final LoomFiles loomFiles; private final ConfigurableFileCollection unmappedMods; @@ -62,6 +63,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen public LoomGradleExtensionImpl(Project project, LoomFiles files) { super(project, files); this.project = project; + this.mixinApExtension = new MixinApExtensionImpl(project); this.loomFiles = files; this.unmappedMods = project.files(); } @@ -160,4 +162,9 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen return provider; } + + @Override + public MixinApExtension getMixinApExtension() { + return this.mixinApExtension; + } } diff --git a/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java b/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java new file mode 100644 index 0000000..e63700b --- /dev/null +++ b/src/main/java/net/fabricmc/loom/extension/MixinApExtension.java @@ -0,0 +1,126 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016-2017 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.extension; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.gradle.api.InvalidUserDataException; +import org.gradle.api.Task; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.plugins.ExtraPropertiesExtension; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.util.PatternSet; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.loom.api.MixinApExtensionAPI; + +/** + * A gradle extension to configure mixin annotation processor. + */ +@ApiStatus.Experimental +public interface MixinApExtension extends MixinApExtensionAPI { + String MIXIN_INFORMATION_CONTAINER = "mixin"; + + /** + * An information container stores necessary information + * for configuring the mixin annotation processor. It's stored + * in [SourceSet].ext.mixin. + */ + final class MixinInformationContainer { + private final SourceSet sourceSet; + private final String refmapName; + private Stream mixinJsonNames; + + final PatternSet mixinJsonPattern; + + public MixinInformationContainer(@NotNull SourceSet sourceSet, + @NotNull String refmapName, + @NotNull PatternSet mixinJsonPattern) { + this.sourceSet = sourceSet; + this.refmapName = refmapName; + this.mixinJsonPattern = mixinJsonPattern; + } + + void setMixinJsonNames(@NotNull Stream mixinJsonNames) { + if (this.mixinJsonNames == null) { + this.mixinJsonNames = mixinJsonNames; + } + } + + @NotNull + public Stream getMixinJsonNames() { + return Objects.requireNonNull(mixinJsonNames); + } + + @NotNull + public SourceSet getSourceSet() { + return sourceSet; + } + + @NotNull + public String getRefmapName() { + return refmapName; + } + } + + @Nullable + static MixinInformationContainer getMixinInformationContainer(SourceSet sourceSet) { + ExtraPropertiesExtension extra = sourceSet.getExtensions().getExtraProperties(); + return extra.has(MIXIN_INFORMATION_CONTAINER) ? (MixinInformationContainer) extra.get(MIXIN_INFORMATION_CONTAINER) : null; + } + + static void setMixinInformationContainer(SourceSet sourceSet, MixinInformationContainer container) { + ExtraPropertiesExtension extra = sourceSet.getExtensions().getExtraProperties(); + + if (extra.has(MIXIN_INFORMATION_CONTAINER)) { + throw new InvalidUserDataException("The sourceSet " + sourceSet.getName() + + " has been configured for mixin annotation processor multiple times"); + } + + extra.set(MIXIN_INFORMATION_CONTAINER, container); + } + + @NotNull + Stream getMixinSourceSetsStream(); + + @NotNull + Stream getApConfigurationsStream(Function getApConfigNameFunc); + + @NotNull + Stream> getInvokerTasksStream(String compileTaskLanguage); + + @NotNull + @Input + Collection getMixinSourceSets(); + + void init(); +} diff --git a/src/main/java/net/fabricmc/loom/extension/MixinApExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/MixinApExtensionApiImpl.java new file mode 100644 index 0000000..7632638 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/extension/MixinApExtensionApiImpl.java @@ -0,0 +1,110 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 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.extension; + +import org.gradle.api.Action; +import org.gradle.api.InvalidUserDataException; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.util.PatternSet; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.api.MixinApExtensionAPI; + +public abstract class MixinApExtensionApiImpl implements MixinApExtensionAPI { + protected abstract Project getProject(); + protected abstract PatternSet add0(SourceSet sourceSet, String refmapName); + + @Override + public void add(SourceSet sourceSet, String refmapName, Action action) { + PatternSet pattern = add0(sourceSet, refmapName); + action.execute(pattern); + } + + @Override + public void add(SourceSet sourceSet, String refmapName) { + add(sourceSet, refmapName, x -> { }); + } + + @Override + public void add(String sourceSetName, String refmapName, Action action) { + // try to find sourceSet with name sourceSetName in this project + SourceSet sourceSet = getProject().getConvention().getPlugin(JavaPluginConvention.class) + .getSourceSets().findByName(sourceSetName); + + if (sourceSet == null) { + throw new InvalidUserDataException("No sourceSet " + sourceSetName + " was found"); + } + + PatternSet pattern = add0(sourceSet, refmapName); + action.execute(pattern); + } + + @Override + public void add(String sourceSetName, String refmapName) { + add(sourceSetName, refmapName, x -> { }); + } + + @Override + public void add(SourceSet sourceSet, Action action) { + LoomGradleExtension extension = LoomGradleExtension.get(getProject()); + add(sourceSet, extension.getRefmapName(), action); + } + + @Override + public void add(SourceSet sourceSet) { + add(sourceSet, x -> { }); + } + + @Override + public void add(String sourceSetName, Action action) { + LoomGradleExtension extension = LoomGradleExtension.get(getProject()); + add(sourceSetName, extension.getRefmapName(), action); + } + + @Override + public void add(String sourceSetName) { + add(sourceSetName, x -> { }); + } + + // This is here to ensure that LoomGradleExtensionApiImpl compiles without any unimplemented methods + private final class EnsureCompile extends MixinApExtensionApiImpl { + private EnsureCompile() { + super(); + throw new RuntimeException(); + } + + @Override + protected Project getProject() { + throw new RuntimeException("Yeah... something is really wrong"); + } + + @Override + protected PatternSet add0(SourceSet sourceSet, String refmapName) { + throw new RuntimeException("Yeah... something is really wrong"); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java new file mode 100644 index 0000000..fd54110 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/extension/MixinApExtensionImpl.java @@ -0,0 +1,125 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 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.extension; + +import java.io.File; +import java.util.AbstractMap; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.UnknownTaskException; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.util.PatternSet; +import org.jetbrains.annotations.NotNull; + +public class MixinApExtensionImpl extends MixinApExtensionApiImpl implements MixinApExtension { + private boolean isDefault; + private final Project project; + + public MixinApExtensionImpl(Project project) { + this.isDefault = true; + this.project = project; + } + + @Override + public Project getProject() { + return this.project; + } + + @Override + protected PatternSet add0(SourceSet sourceSet, String refmapName) { + PatternSet pattern = new PatternSet().setIncludes(Collections.singletonList("*.mixins.json")); + MixinApExtension.setMixinInformationContainer(sourceSet, new MixinApExtension.MixinInformationContainer(sourceSet, refmapName, pattern)); + + isDefault = false; + + return pattern; + } + + @Override + @NotNull + public Stream getMixinSourceSetsStream() { + return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().stream() + .filter(sourceSet -> { + MixinApExtension.MixinInformationContainer container = MixinApExtension.getMixinInformationContainer(sourceSet); + + if (container != null) { + PatternSet pattern = container.mixinJsonPattern; + Stream mixinJsonNames = sourceSet.getResources() + .matching(pattern).getFiles().stream().map(File::getName); + container.setMixinJsonNames(mixinJsonNames); + return true; + } + + return false; + }); + } + + @Override + @NotNull + public Stream getApConfigurationsStream(Function getApConfigNameFunc) { + return getMixinSourceSetsStream() + .map(sourceSet -> project.getConfigurations().getByName(getApConfigNameFunc.apply(sourceSet.getName()))); + } + + @Override + @NotNull + public Stream> getInvokerTasksStream(String compileTaskLanguage) { + return getMixinSourceSetsStream() + .flatMap(sourceSet -> { + try { + Task task = project.getTasks().getByName(sourceSet.getCompileTaskName(compileTaskLanguage)); + return Stream.of(new AbstractMap.SimpleEntry<>(sourceSet, task)); + } catch (UnknownTaskException ignored) { + return Stream.empty(); + } + }); + } + + @Override + @NotNull + @Input + public Collection getMixinSourceSets() { + return getMixinSourceSetsStream().collect(Collectors.toList()); + } + + @Override + public void init() { + if (isDefault) { + project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().forEach(this::add); + } + + isDefault = false; + } +} diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index eed672f..3ec8352 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -170,7 +170,7 @@ public class RemapJarTask extends Jar { throw new RuntimeException("Failed to remap " + input + " to " + output + " - file missing!"); } - if (MixinRefmapHelper.addRefmapName(extension.getRefmapName(), output)) { + if (MixinRefmapHelper.addRefmapName(project, output)) { project.getLogger().debug("Transformed mixin reference maps in output JAR!"); } diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy new file mode 100644 index 0000000..80ed7c8 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/MixinApAutoRefmapTest.groovy @@ -0,0 +1,73 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016-2017 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.integration + +import net.fabricmc.loom.test.util.ProjectTestTrait +import spock.lang.Specification +import spock.lang.Unroll +import com.google.gson.JsonParser; +import java.util.jar.JarFile + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class MixinApAutoRefmapTest extends Specification implements ProjectTestTrait { + @Override + String name() { + "mixinApAutoRefmap" + } + + @Unroll + def "build (gradle #gradle)"() { + when: + def result = create("build", gradle) + + then: + result.task(":build").outcome == SUCCESS + + // verify the ref-map name is correctly generated + def jar = new JarFile(getOutputFile("fabric-example-mod-1.0.0-universal.jar").absoluteFile) + jar.getEntry("refmap0000.json") == null + jar.getEntry("refmap0001.json") != null + jar.getEntry("refmap0002.json") != null + jar.getEntry("refmap0003.json") != null + + def j1 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("main.mixins.json")))) + j1.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0001.json" + + def j2 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m0.mixins.json")))) + j2.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0002.json" + + def j3 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_1.mixins.json")))) + j3.asJsonObject.getAsJsonPrimitive("refmap").getAsString() == "refmap0003.json" + + def j4 = JsonParser.parseReader(new InputStreamReader(jar.getInputStream(jar.getEntry("m1_2.mixins.json")))) + !j4.asJsonObject.has("refmap") + + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/MixinApSimpleTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/MixinApSimpleTest.groovy new file mode 100644 index 0000000..793915e --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/MixinApSimpleTest.groovy @@ -0,0 +1,63 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016-2017 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.integration + +import net.fabricmc.loom.test.util.ProjectTestTrait +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.jar.JarFile + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class MixinApSimpleTest extends Specification implements ProjectTestTrait { + @Override + String name() { + "mixinApSimple" + } + + @Unroll + def "build (gradle #gradle)"() { + when: + def result = create("build", gradle) + + then: + result.task(":build").outcome == SUCCESS + + // verify the ref-map name is correctly generated + def main = new JarFile(getOutputFile("fabric-example-mod-1.0.0-dev.jar").absoluteFile) + main.getEntry("main-refmap0000.json") != null + def mixin = new JarFile(getOutputFile("fabric-example-mod-1.0.0-mixin.jar").absoluteFile) + mixin.getEntry("default-refmap0000.json") != null + def mixin1 = new JarFile(getOutputFile("fabric-example-mod-1.0.0-mixin1.jar").absoluteFile) + mixin1.getEntry("main-refmap0000.json") == null + mixin1.getEntry("default-refmap0000.json") == null + + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/build.gradle b/src/test/resources/projects/mixinApAutoRefmap/build.gradle new file mode 100644 index 0000000..93b0507 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/build.gradle @@ -0,0 +1,139 @@ +plugins { + id 'fabric-loom' + id 'com.github.johnrengelman.shadow' version '7.0.0' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_16 +targetCompatibility = JavaVersion.VERSION_16 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +sourceSets.register("mixin") { + it.compileClasspath += sourceSets["main"].compileClasspath + it.runtimeClasspath += sourceSets["main"].runtimeClasspath +} +sourceSets.register("mixin1") { + it.compileClasspath += sourceSets["main"].compileClasspath + it.runtimeClasspath += sourceSets["main"].runtimeClasspath +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // Minecraft 1.17 (21w19a) upwards uses Java 16. + it.options.release = 16 +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +loom { + refmapName = "refmap0000.json" + + mixin { + add(sourceSets["main"], "refmap0001.json") + add(sourceSets["mixin"], "refmap0002.json") + add(sourceSets["mixin1"], "refmap0003.json") { + it.exclude("m1_2.mixins.json") + } + } +} + +shadowJar { + archiveClassifier.set("universal-dev") + configurations = [] + + from(sourceSets["main"].output) + from(sourceSets["mixin"].output) + from(sourceSets["mixin1"].output) +} + +remapJar { + dependsOn(shadowJar) + archiveClassifier.set("universal") + input.fileValue(tasks["shadowJar"].outputs.files.singleFile) +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +tasks.register("mixinJar0", Jar.class) { + it.archiveClassifier.set("mixin") + it.from(sourceSets["mixin"].output) +} + +tasks.register("mixinJar1", Jar.class) { + it.archiveClassifier.set("mixin1") + it.from(sourceSets["mixin1"].output) +} + +assemble { + dependsOn tasks["mixinJar0"] + dependsOn tasks["mixinJar1"] +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} \ No newline at end of file diff --git a/src/test/resources/projects/mixinApAutoRefmap/gradle.properties b/src/test/resources/projects/mixinApAutoRefmap/gradle.properties new file mode 100644 index 0000000..60cb9a4 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/gradle.properties @@ -0,0 +1,16 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties + # check these on https://fabricmc.net/versions.html + minecraft_version=1.17 + yarn_mappings=1.17+build.13 + loader_version=0.11.6 + +# Mod Properties + mod_version = 1.0.0 + maven_group = com.example + archives_base_name = fabric-example-mod + +# Dependencies + fabric_version=0.36.0+1.17 diff --git a/src/test/resources/projects/mixinApAutoRefmap/settings.gradle b/src/test/resources/projects/mixinApAutoRefmap/settings.gradle new file mode 100644 index 0000000..56603bc --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + mavenLocal() + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/ExampleMod.java b/src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/ExampleMod.java new file mode 100644 index 0000000..e5ed082 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/ExampleMod.java @@ -0,0 +1,14 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/mixin/ExampleMixinMain.java b/src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/mixin/ExampleMixinMain.java new file mode 100644 index 0000000..33bca34 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/main/java/net/fabricmc/example/mixin/ExampleMixinMain.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.ChatScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ChatScreen.class) +public class ExampleMixinMain { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/assets/modid/icon.png b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/assets/modid/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..047b91f2347de5cf95f23284476fddbe21ba23fe GIT binary patch literal 453 zcmV;$0XqJPP)QAFYGys`80vegN0XDFh0OXKz&i8?Le#x7{1X)R+00000NkvXXu0mjf73i~T literal 0 HcmV?d00001 diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..c8aeaef --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/fabric.mod.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + ], + + "depends": { + "fabricloader": ">=0.11.3", + "fabric": "*", + "minecraft": "1.17.x", + "java": ">=16" + }, + "suggests": { + "another-mod": "*" + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/main.mixins.json b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/main.mixins.json new file mode 100644 index 0000000..5d969e0 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/main/resources/main.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixinMain" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java new file mode 100644 index 0000000..db9bd0d --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin0 { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/m0.mixins.json b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/m0.mixins.json new file mode 100644 index 0000000..e2c4148 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin/resources/m0.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin0" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_1.java b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_1.java new file mode 100644 index 0000000..ffb4641 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_1.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin1_1 { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_2.java b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_2.java new file mode 100644 index 0000000..8d9593d --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1_2.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin1_2 { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_1.mixins.json b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_1.mixins.json new file mode 100644 index 0000000..2ba6803 --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_1.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin1_1" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_2.mixins.json b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_2.mixins.json new file mode 100644 index 0000000..74cac4b --- /dev/null +++ b/src/test/resources/projects/mixinApAutoRefmap/src/mixin1/resources/m1_2.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin1_2" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/mixinApSimple/build.gradle b/src/test/resources/projects/mixinApSimple/build.gradle new file mode 100644 index 0000000..bf2d09f --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/build.gradle @@ -0,0 +1,119 @@ +plugins { + id 'fabric-loom' version '0.9.local' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_16 +targetCompatibility = JavaVersion.VERSION_16 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +sourceSets.register("mixin") { + it.compileClasspath += sourceSets["main"].compileClasspath + it.runtimeClasspath += sourceSets["main"].runtimeClasspath +} +sourceSets.register("mixin1") { + it.compileClasspath += sourceSets["main"].compileClasspath + it.runtimeClasspath += sourceSets["main"].runtimeClasspath +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // Minecraft 1.17 (21w19a) upwards uses Java 16. + it.options.release = 16 +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +loom { + refmapName = "default-refmap0000.json" + mixin { + add(sourceSets["main"], "main-refmap0000.json") + add(sourceSets["mixin"]) + } +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +tasks.register("mixinJar0", Jar.class) { + it.archiveClassifier.set("mixin") + it.from(sourceSets["mixin"].output) +} + +tasks.register("mixinJar1", Jar.class) { + it.archiveClassifier.set("mixin1") + it.from(sourceSets["mixin1"].output) +} + +assemble { + dependsOn tasks["mixinJar0"] + dependsOn tasks["mixinJar1"] +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/src/test/resources/projects/mixinApSimple/gradle.properties b/src/test/resources/projects/mixinApSimple/gradle.properties new file mode 100644 index 0000000..60cb9a4 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/gradle.properties @@ -0,0 +1,16 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties + # check these on https://fabricmc.net/versions.html + minecraft_version=1.17 + yarn_mappings=1.17+build.13 + loader_version=0.11.6 + +# Mod Properties + mod_version = 1.0.0 + maven_group = com.example + archives_base_name = fabric-example-mod + +# Dependencies + fabric_version=0.36.0+1.17 diff --git a/src/test/resources/projects/mixinApSimple/settings.gradle b/src/test/resources/projects/mixinApSimple/settings.gradle new file mode 100644 index 0000000..56603bc --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + mavenLocal() + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/ExampleMod.java b/src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/ExampleMod.java new file mode 100644 index 0000000..e5ed082 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/ExampleMod.java @@ -0,0 +1,14 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/mixin/ExampleMixin1.java b/src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/mixin/ExampleMixin1.java new file mode 100644 index 0000000..f8d3422 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/main/java/net/fabricmc/example/mixin/ExampleMixin1.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.ChatScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ChatScreen.class) +public class ExampleMixin1 { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/main/resources/assets/modid/icon.png b/src/test/resources/projects/mixinApSimple/src/main/resources/assets/modid/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..047b91f2347de5cf95f23284476fddbe21ba23fe GIT binary patch literal 453 zcmV;$0XqJPP)QAFYGys`80vegN0XDFh0OXKz&i8?Le#x7{1X)R+00000NkvXXu0mjf73i~T literal 0 HcmV?d00001 diff --git a/src/test/resources/projects/mixinApSimple/src/main/resources/fabric.mod.json b/src/test/resources/projects/mixinApSimple/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..893f34b --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/main/resources/fabric.mod.json @@ -0,0 +1,39 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + "main.mixins.json", + "m0.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.11.3", + "fabric": "*", + "minecraft": "1.17.x", + "java": ">=16" + }, + "suggests": { + "another-mod": "*" + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/main/resources/main.mixins.json b/src/test/resources/projects/mixinApSimple/src/main/resources/main.mixins.json new file mode 100644 index 0000000..d7205a4 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/main/resources/main.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin1" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java b/src/test/resources/projects/mixinApSimple/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java new file mode 100644 index 0000000..db9bd0d --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/mixin/java/net/fabricmc/example/mixin/ExampleMixin0.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin0 { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/mixin/resources/m0.mixins.json b/src/test/resources/projects/mixinApSimple/src/mixin/resources/m0.mixins.json new file mode 100644 index 0000000..e2c4148 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/mixin/resources/m0.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin0" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1.java b/src/test/resources/projects/mixinApSimple/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1.java new file mode 100644 index 0000000..c30a643 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/mixin1/java/net/fabricmc/example/mixin/ExampleMixin1.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin1 { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/mixinApSimple/src/mixin1/resources/m1.mixins.json b/src/test/resources/projects/mixinApSimple/src/mixin1/resources/m1.mixins.json new file mode 100644 index 0000000..e2c4148 --- /dev/null +++ b/src/test/resources/projects/mixinApSimple/src/mixin1/resources/m1.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "client": [ + "ExampleMixin0" + ], + "injectors": { + "defaultRequire": 1 + } +}