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 54d6ef7896
* 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>
dev/0.11
parent
b4ac68825f
commit
81fa551382
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<RunConfigSettings> getRunConfigs();
|
||||
|
||||
@ApiStatus.Experimental
|
||||
void mixin(Action<MixinApExtensionAPI> action);
|
||||
|
||||
void setCustomManifest(String customManifest);
|
||||
|
||||
String getCustomManifest();
|
||||
|
|
|
@ -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<PatternSet> 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<PatternSet> 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<PatternSet> 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<PatternSet> 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);
|
||||
}
|
|
@ -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<String> 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<String> 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<String> findMixins(File output, boolean onlyWithoutRefmap) {
|
||||
// first, identify all of the mixin files
|
||||
Set<String> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<T extends Task> {
|
||||
public static final String JAVA = "java";
|
||||
public static final String SCALA = "scala";
|
||||
|
||||
protected final Project project;
|
||||
private final Collection<Configuration> annotationProcessorConfigurations;
|
||||
protected final TaskCollection<T> invokerTasks;
|
||||
protected final Map<SourceSet, T> invokerTasks;
|
||||
private final Collection<Configuration> apConfigurations;
|
||||
|
||||
protected AnnotationProcessorInvoker(Project project,
|
||||
Collection<Configuration> annotationProcessorConfigurations,
|
||||
TaskCollection<T> invokerTasks) {
|
||||
Collection<Configuration> apConfigurations,
|
||||
Map<SourceSet, T> invokerTasks) {
|
||||
this.project = project;
|
||||
this.annotationProcessorConfigurations = annotationProcessorConfigurations;
|
||||
this.apConfigurations = apConfigurations;
|
||||
this.invokerTasks = invokerTasks;
|
||||
}
|
||||
|
||||
protected static Collection<Configuration> getApConfigurations(Project project, Function<String, String> 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<String, String> 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<T extends Task> {
|
|||
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<T extends Task> {
|
|||
}
|
||||
}
|
||||
|
||||
for (T task : invokerTasks) {
|
||||
passMixinArguments(task);
|
||||
for (Map.Entry<SourceSet, T> entry : invokerTasks.entrySet()) {
|
||||
passMixinArguments(entry.getValue(), entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
static Stream<SourceSet> getNonTestSourceSets(Project project) {
|
||||
return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets()
|
||||
.stream()
|
||||
.filter(sourceSet -> !sourceSet.getName().equals("test"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<JavaCompile> {
|
||||
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<SourceSet, JavaCompile> 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<JavaCompile> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected File getDestinationDir(JavaCompile task) {
|
||||
protected File getRefmapDestinationDir(JavaCompile task) {
|
||||
return task.getDestinationDir();
|
||||
}
|
||||
|
||||
private static List<Configuration> 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";
|
||||
|
|
|
@ -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<JavaCompile> {
|
||||
private final KaptExtension kaptExtension = project.getExtensions().getByType(KaptExtension.class);
|
||||
|
@ -48,7 +48,10 @@ public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> {
|
|||
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<JavaCompile> {
|
|||
kaptExtension.setIncludeCompileClasspath(false);
|
||||
}
|
||||
|
||||
private static Map<SourceSet, JavaCompile> 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<SourceSet, JavaCompile> 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<JavaCompile> {
|
|||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<Configuration> 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<JavaCompile> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected File getDestinationDir(JavaCompile task) {
|
||||
protected File getRefmapDestinationDir(JavaCompile task) {
|
||||
return dummyRefmapDirectory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ScalaCompile> {
|
||||
public ScalaApInvoker(Project project) {
|
||||
super(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));
|
||||
getInvokerTasks(project));
|
||||
}
|
||||
|
||||
private static Map<SourceSet, ScalaCompile> 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<ScalaCompile> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected File getDestinationDir(ScalaCompile task) {
|
||||
protected File getRefmapDestinationDir(ScalaCompile task) {
|
||||
return task.getDestinationDir();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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<MixinApExtensionAPI> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String> 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<String> mixinJsonNames) {
|
||||
if (this.mixinJsonNames == null) {
|
||||
this.mixinJsonNames = mixinJsonNames;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Stream<String> 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<SourceSet> getMixinSourceSetsStream();
|
||||
|
||||
@NotNull
|
||||
Stream<Configuration> getApConfigurationsStream(Function<String, String> getApConfigNameFunc);
|
||||
|
||||
@NotNull
|
||||
Stream<Map.Entry<SourceSet, Task>> getInvokerTasksStream(String compileTaskLanguage);
|
||||
|
||||
@NotNull
|
||||
@Input
|
||||
Collection<SourceSet> getMixinSourceSets();
|
||||
|
||||
void init();
|
||||
}
|
|
@ -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<PatternSet> 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<PatternSet> 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<PatternSet> 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<PatternSet> 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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<SourceSet> 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<String> mixinJsonNames = sourceSet.getResources()
|
||||
.matching(pattern).getFiles().stream().map(File::getName);
|
||||
container.setMixinJsonNames(mixinJsonNames);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Stream<Configuration> getApConfigurationsStream(Function<String, String> getApConfigNameFunc) {
|
||||
return getMixinSourceSetsStream()
|
||||
.map(sourceSet -> project.getConfigurations().getByName(getApConfigNameFunc.apply(sourceSet.getName())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Stream<Map.Entry<SourceSet, Task>> 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<SourceSet> getMixinSourceSets() {
|
||||
return getMixinSourceSetsStream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (isDefault) {
|
||||
project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().forEach(this::add);
|
||||
}
|
||||
|
||||
isDefault = false;
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
|
||||
|
|
|
@ -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 | _
|
||||
}
|
||||
}
|
|
@ -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 | _
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,10 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
mavenLocal()
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 453 B |
|
@ -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": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixinMain"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin0"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin1_1"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin1_2"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,10 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
mavenLocal()
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 453 B |
|
@ -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": "*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin1"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin0"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin0"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue