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>
			
			
This commit is contained in:
		
							parent
							
								
									b4ac68825f
								
							
						
					
					
						commit
						81fa551382
					
				
					 43 changed files with 1342 additions and 104 deletions
				
			
		|  | @ -44,6 +44,7 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; | import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; | ||||||
| import net.fabricmc.loom.extension.LoomFiles; | import net.fabricmc.loom.extension.LoomFiles; | ||||||
| import net.fabricmc.loom.extension.LoomGradleExtensionImpl; | import net.fabricmc.loom.extension.LoomGradleExtensionImpl; | ||||||
|  | import net.fabricmc.loom.extension.MixinApExtension; | ||||||
| 
 | 
 | ||||||
| public interface LoomGradleExtension extends LoomGradleExtensionAPI { | public interface LoomGradleExtension extends LoomGradleExtensionAPI { | ||||||
| 	static LoomGradleExtension get(Project project) { | 	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 | 		// 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); | 		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.NamedDomainObjectContainer; | ||||||
| import org.gradle.api.artifacts.Dependency; | import org.gradle.api.artifacts.Dependency; | ||||||
| import org.gradle.api.file.ConfigurableFileCollection; | import org.gradle.api.file.ConfigurableFileCollection; | ||||||
|  | import org.jetbrains.annotations.ApiStatus; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.api.decompilers.LoomDecompiler; | import net.fabricmc.loom.api.decompilers.LoomDecompiler; | ||||||
| import net.fabricmc.loom.configuration.ide.RunConfigSettings; | import net.fabricmc.loom.configuration.ide.RunConfigSettings; | ||||||
|  | @ -81,6 +82,9 @@ public interface LoomGradleExtensionAPI { | ||||||
| 
 | 
 | ||||||
| 	NamedDomainObjectContainer<RunConfigSettings> getRunConfigs(); | 	NamedDomainObjectContainer<RunConfigSettings> getRunConfigs(); | ||||||
| 
 | 
 | ||||||
|  | 	@ApiStatus.Experimental | ||||||
|  | 	void mixin(Action<MixinApExtensionAPI> action); | ||||||
|  | 
 | ||||||
| 	void setCustomManifest(String customManifest); | 	void setCustomManifest(String customManifest); | ||||||
| 
 | 
 | ||||||
| 	String getCustomManifest(); | 	String getCustomManifest(); | ||||||
|  |  | ||||||
							
								
								
									
										92
									
								
								src/main/java/net/fabricmc/loom/api/MixinApExtensionAPI.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/main/java/net/fabricmc/loom/api/MixinApExtensionAPI.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -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; | package net.fabricmc.loom.build; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; |  | ||||||
| import java.io.InputStreamReader; |  | ||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
| import java.util.HashSet; | import java.util.Objects; | ||||||
| import java.util.Set; | import java.util.stream.Stream; | ||||||
| import java.util.zip.ZipEntry; | import java.util.zip.ZipEntry; | ||||||
| 
 | 
 | ||||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||||
|  | import org.gradle.api.Project; | ||||||
| import org.zeroturnaround.zip.ZipUtil; | import org.zeroturnaround.zip.ZipUtil; | ||||||
| import org.zeroturnaround.zip.transform.StringZipEntryTransformer; | import org.zeroturnaround.zip.transform.StringZipEntryTransformer; | ||||||
| import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; | import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; | ||||||
| 
 | 
 | ||||||
|  | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.LoomGradlePlugin; | import net.fabricmc.loom.LoomGradlePlugin; | ||||||
|  | import net.fabricmc.loom.extension.MixinApExtension; | ||||||
| 
 | 
 | ||||||
| public final class MixinRefmapHelper { | public final class MixinRefmapHelper { | ||||||
| 	private 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(); | 		File output = outputPath.toFile(); | ||||||
| 		Set<String> mixinFilenames = findMixins(output, true); |  | ||||||
| 
 | 
 | ||||||
| 		if (mixinFilenames.size() > 0) { | 		return mixin.getMixinSourceSetsStream().map(sourceSet -> { | ||||||
| 			return ZipUtil.transformEntries(output, mixinFilenames.stream().map((f) -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { | 			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 | 				@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); | 					JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class); | ||||||
| 
 | 
 | ||||||
| 					if (!json.has("refmap")) { | 					if (!json.has("refmap")) { | ||||||
| 						json.addProperty("refmap", filename); | 						json.addProperty("refmap", refmapName); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					return LoomGradlePlugin.GSON.toJson(json); | 					return LoomGradlePlugin.GSON.toJson(json); | ||||||
| 				} | 				} | ||||||
| 			})).toArray(ZipEntryTransformerEntry[]::new)); | 			})).toArray(ZipEntryTransformerEntry[]::new)); | ||||||
| 		} else { | 		}).reduce(false, Boolean::logicalOr); | ||||||
| 			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; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,16 +29,17 @@ import java.io.IOException; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.Map; | 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.Project; | ||||||
| import org.gradle.api.Task; | import org.gradle.api.Task; | ||||||
| import org.gradle.api.artifacts.Configuration; | import org.gradle.api.artifacts.Configuration; | ||||||
| import org.gradle.api.artifacts.ConfigurationContainer; | import org.gradle.api.artifacts.ConfigurationContainer; | ||||||
| import org.gradle.api.plugins.JavaPluginConvention; |  | ||||||
| import org.gradle.api.tasks.SourceSet; | 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.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.util.Constants; | 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. |  * 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 abstract class AnnotationProcessorInvoker<T extends Task> { | ||||||
|  | 	public static final String JAVA = "java"; | ||||||
|  | 	public static final String SCALA = "scala"; | ||||||
|  | 
 | ||||||
| 	protected final Project project; | 	protected final Project project; | ||||||
| 	private final Collection<Configuration> annotationProcessorConfigurations; | 	protected final Map<SourceSet, T> invokerTasks; | ||||||
| 	protected final TaskCollection<T> invokerTasks; | 	private final Collection<Configuration> apConfigurations; | ||||||
| 
 | 
 | ||||||
| 	protected AnnotationProcessorInvoker(Project project, | 	protected AnnotationProcessorInvoker(Project project, | ||||||
| 										Collection<Configuration> annotationProcessorConfigurations, | 										Collection<Configuration> apConfigurations, | ||||||
| 										TaskCollection<T> invokerTasks) { | 										Map<SourceSet, T> invokerTasks) { | ||||||
| 		this.project = project; | 		this.project = project; | ||||||
| 		this.annotationProcessorConfigurations = annotationProcessorConfigurations; | 		this.apConfigurations = apConfigurations; | ||||||
| 		this.invokerTasks = invokerTasks; | 		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 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 { | 	protected final String getRefmapDestination(T task, String refmapName) throws IOException { | ||||||
| 		return new File(getDestinationDir(task), extension.getRefmapName()).getCanonicalPath(); | 		return new File(getRefmapDestinationDir(task), refmapName).getCanonicalPath(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void passMixinArguments(T task) { | 	private void passMixinArguments(T task, SourceSet sourceSet) { | ||||||
| 		try { | 		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<>() {{ | 			Map<String, String> args = new HashMap<>() {{ | ||||||
| 					put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, extension.getMappingsProvider().tinyMappings.getCanonicalPath()); | 					put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.getCanonicalPath()); | ||||||
| 					put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, extension.getNextMixinMappings().getCanonicalPath()); | 					put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, loom.getNextMixinMappings().getCanonicalPath()); | ||||||
| 					put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, extension)); | 					put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName)); | ||||||
| 					put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:intermediary"); | 					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)); | 			args.forEach((k, v) -> passArgument(task, k, v)); | ||||||
| 		} catch (IOException e) { | 		} catch (IOException e) { | ||||||
| 			project.getLogger().error("Could not configure mixin annotation processors", 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); | 		LoomGradleExtension extension = LoomGradleExtension.get(project); | ||||||
| 
 | 
 | ||||||
| 		if (!extension.ideSync()) { | 		if (!extension.ideSync()) { | ||||||
| 			for (Configuration processorConfig : annotationProcessorConfigurations) { | 			for (Configuration processorConfig : apConfigurations) { | ||||||
| 				project.getLogger().info("Adding mixin to classpath of AP config: " + processorConfig.getName()); | 				project.getLogger().info("Adding mixin to classpath of AP config: " + processorConfig.getName()); | ||||||
| 				// Pass named MC classpath to mixin AP classpath | 				// Pass named MC classpath to mixin AP classpath | ||||||
| 				processorConfig.extendsFrom( | 				processorConfig.extendsFrom( | ||||||
|  | @ -105,14 +115,8 @@ public abstract class AnnotationProcessorInvoker<T extends Task> { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (T task : invokerTasks) { | 		for (Map.Entry<SourceSet, T> entry : invokerTasks.entrySet()) { | ||||||
| 			passMixinArguments(task); | 			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; | package net.fabricmc.loom.build.mixin; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.util.List; | import java.util.Map; | ||||||
|  | import java.util.Objects; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
| import org.gradle.api.artifacts.Configuration; |  | ||||||
| import org.gradle.api.plugins.JavaPlugin; | import org.gradle.api.plugins.JavaPlugin; | ||||||
|  | import org.gradle.api.tasks.SourceSet; | ||||||
| import org.gradle.api.tasks.compile.JavaCompile; | 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 class JavaApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||||
| 	public JavaApInvoker(Project project) { | 	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 | 	@Override | ||||||
|  | @ -44,18 +57,10 @@ public class JavaApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected File getDestinationDir(JavaCompile task) { | 	protected File getRefmapDestinationDir(JavaCompile task) { | ||||||
| 		return task.getDestinationDir(); | 		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) { | 	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 | 		// 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"; | 		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.Files; | ||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
| import java.nio.file.Paths; | import java.nio.file.Paths; | ||||||
| import java.util.List; | import java.util.Map; | ||||||
|  | import java.util.Objects; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
| import kotlin.Unit; | import kotlin.Unit; | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
| import org.gradle.api.artifacts.Configuration; |  | ||||||
| import org.gradle.api.tasks.SourceSet; | import org.gradle.api.tasks.SourceSet; | ||||||
| import org.gradle.api.tasks.compile.JavaCompile; | import org.gradle.api.tasks.compile.JavaCompile; | ||||||
| import org.jetbrains.annotations.NotNull; |  | ||||||
| import org.jetbrains.kotlin.gradle.plugin.KaptExtension; | import org.jetbrains.kotlin.gradle.plugin.KaptExtension; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
|  | import net.fabricmc.loom.extension.MixinApExtension; | ||||||
| 
 | 
 | ||||||
| public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||||
| 	private final KaptExtension kaptExtension = project.getExtensions().getByType(KaptExtension.class); | 	private final KaptExtension kaptExtension = project.getExtensions().getByType(KaptExtension.class); | ||||||
|  | @ -48,7 +48,10 @@ public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||||
| 	private final File dummyRefmapDirectory; | 	private final File dummyRefmapDirectory; | ||||||
| 
 | 
 | ||||||
| 	public KaptApInvoker(Project project) { | 	public KaptApInvoker(Project project) { | ||||||
| 		super(project, getConfigurations(project), project.getTasks().withType(JavaCompile.class)); | 		super( | ||||||
|  | 				project, | ||||||
|  | 				AnnotationProcessorInvoker.getApConfigurations(project, KaptApInvoker::getKaptConfigurationName), | ||||||
|  | 				getInvokerTasks(project)); | ||||||
| 
 | 
 | ||||||
| 		try { | 		try { | ||||||
| 			dummyRefmapDirectory = Files.createTempDirectory("temp_refmap").toFile(); | 			dummyRefmapDirectory = Files.createTempDirectory("temp_refmap").toFile(); | ||||||
|  | @ -62,18 +65,26 @@ public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||||
| 		kaptExtension.setIncludeCompileClasspath(false); | 		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 | 	@Override | ||||||
| 	public void configureMixin() { | 	public void configureMixin() { | ||||||
| 		super.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 | 			// 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 | 			// 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 -> { | 			task.doLast(t -> { | ||||||
| 				try { | 				try { | ||||||
| 					LoomGradleExtension extension = LoomGradleExtension.get(project); | 					String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).getRefmapName(); | ||||||
| 					Path src = Paths.get(getRefmapDestination(task, extension)); | 					Path src = Paths.get(getRefmapDestination(task, refmapName)); | ||||||
| 					Path dest = Paths.get(task.getDestinationDir().toString(), extension.getRefmapName()); | 					Path dest = Paths.get(task.getDestinationDir().toString(), refmapName); | ||||||
| 
 | 
 | ||||||
| 					// Possible that no mixin annotations exist | 					// Possible that no mixin annotations exist | ||||||
| 					if (Files.exists(src)) { | 					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 | 	// 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) { | 	private static String getKaptConfigurationName(String sourceSetName) { | ||||||
| 		if (!sourceSetName.equals(SourceSet.MAIN_SOURCE_SET_NAME)) { | 		if (!sourceSetName.equals(SourceSet.MAIN_SOURCE_SET_NAME)) { | ||||||
|  | @ -116,7 +118,7 @@ public class KaptApInvoker extends AnnotationProcessorInvoker<JavaCompile> { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected File getDestinationDir(JavaCompile task) { | 	protected File getRefmapDestinationDir(JavaCompile task) { | ||||||
| 		return dummyRefmapDirectory; | 		return dummyRefmapDirectory; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,17 +25,31 @@ | ||||||
| package net.fabricmc.loom.build.mixin; | package net.fabricmc.loom.build.mixin; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Objects; | ||||||
|  | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
| import com.google.common.collect.ImmutableList; | import com.google.common.collect.ImmutableList; | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
|  | import org.gradle.api.tasks.SourceSet; | ||||||
| import org.gradle.api.tasks.scala.ScalaCompile; | 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 class ScalaApInvoker extends AnnotationProcessorInvoker<ScalaCompile> { | ||||||
| 	public ScalaApInvoker(Project project) { | 	public ScalaApInvoker(Project project) { | ||||||
| 		super(project, | 		super( | ||||||
| 						// Scala just uses the java AP configuration afaik. This of course assumes the java AP also gets configured. | 				project, | ||||||
| 						ImmutableList.of(), | 				// Scala just uses the java AP configuration afaik. This of course assumes the java AP also gets configured. | ||||||
| 						project.getTasks().withType(ScalaCompile.class)); | 				ImmutableList.of(), | ||||||
|  | 				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 | 	@Override | ||||||
|  | @ -44,7 +58,7 @@ public class ScalaApInvoker extends AnnotationProcessorInvoker<ScalaCompile> { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected File getDestinationDir(ScalaCompile task) { | 	protected File getRefmapDestinationDir(ScalaCompile task) { | ||||||
| 		return task.getDestinationDir(); | 		return task.getDestinationDir(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ import org.gradle.api.tasks.compile.JavaCompile; | ||||||
| import org.gradle.api.tasks.javadoc.Javadoc; | import org.gradle.api.tasks.javadoc.Javadoc; | ||||||
| import org.gradle.jvm.tasks.Jar; | import org.gradle.jvm.tasks.Jar; | ||||||
| 
 | 
 | ||||||
|  | import net.fabricmc.loom.extension.MixinApExtension; | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.build.mixin.JavaApInvoker; | import net.fabricmc.loom.build.mixin.JavaApInvoker; | ||||||
| import net.fabricmc.loom.build.mixin.KaptApInvoker; | import net.fabricmc.loom.build.mixin.KaptApInvoker; | ||||||
|  | @ -143,6 +144,9 @@ public final class CompileConfiguration { | ||||||
| 			System.setProperty("log4j.skipJansi", "true"); | 			System.setProperty("log4j.skipJansi", "true"); | ||||||
| 
 | 
 | ||||||
| 			project.getLogger().info("Configuring compiler arguments for Java"); | 			project.getLogger().info("Configuring compiler arguments for Java"); | ||||||
|  | 			MixinApExtension mixinApExtension = LoomGradleExtension.get(project).getMixinApExtension(); | ||||||
|  | 			mixinApExtension.init(); | ||||||
|  | 
 | ||||||
| 			new JavaApInvoker(project).configureMixin(); | 			new JavaApInvoker(project).configureMixin(); | ||||||
| 
 | 
 | ||||||
| 			if (project.getPluginManager().hasPlugin("scala")) { | 			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.file.ConfigurableFileCollection; | ||||||
| import org.gradle.api.plugins.BasePluginConvention; | import org.gradle.api.plugins.BasePluginConvention; | ||||||
| 
 | 
 | ||||||
|  | import net.fabricmc.loom.api.MixinApExtensionAPI; | ||||||
| import net.fabricmc.loom.api.decompilers.LoomDecompiler; | import net.fabricmc.loom.api.decompilers.LoomDecompiler; | ||||||
| import net.fabricmc.loom.api.LoomGradleExtensionAPI; | import net.fabricmc.loom.api.LoomGradleExtensionAPI; | ||||||
| import net.fabricmc.loom.configuration.ide.RunConfigSettings; | import net.fabricmc.loom.configuration.ide.RunConfigSettings; | ||||||
|  | @ -159,6 +160,11 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA | ||||||
| 		return remapMod; | 		return remapMod; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void mixin(Action<MixinApExtensionAPI> action) { | ||||||
|  | 		action.execute(getMixinApExtension()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public void setCustomManifest(String customManifest) { | 	public void setCustomManifest(String customManifest) { | ||||||
| 		Objects.requireNonNull(customManifest, "Custom manifest cannot be null"); | 		Objects.requireNonNull(customManifest, "Custom manifest cannot be null"); | ||||||
|  | @ -174,6 +180,8 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA | ||||||
| 
 | 
 | ||||||
| 	protected abstract LoomFiles getFiles(); | 	protected abstract LoomFiles getFiles(); | ||||||
| 
 | 
 | ||||||
|  | 	protected abstract MixinApExtension getMixinApExtension(); | ||||||
|  | 
 | ||||||
| 	// This is here to ensure that LoomGradleExtensionApiImpl compiles without any unimplemented methods | 	// This is here to ensure that LoomGradleExtensionApiImpl compiles without any unimplemented methods | ||||||
| 	private final class EnsureCompile extends LoomGradleExtensionApiImpl { | 	private final class EnsureCompile extends LoomGradleExtensionApiImpl { | ||||||
| 		private EnsureCompile() { | 		private EnsureCompile() { | ||||||
|  | @ -190,5 +198,10 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA | ||||||
| 		protected LoomFiles getFiles() { | 		protected LoomFiles getFiles() { | ||||||
| 			throw new RuntimeException("Yeah... something is really wrong"); | 			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 { | public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implements LoomGradleExtension { | ||||||
| 	private final Project project; | 	private final Project project; | ||||||
|  | 	private final MixinApExtension mixinApExtension; | ||||||
| 	private final LoomFiles loomFiles; | 	private final LoomFiles loomFiles; | ||||||
| 	private final ConfigurableFileCollection unmappedMods; | 	private final ConfigurableFileCollection unmappedMods; | ||||||
| 
 | 
 | ||||||
|  | @ -62,6 +63,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen | ||||||
| 	public LoomGradleExtensionImpl(Project project, LoomFiles files) { | 	public LoomGradleExtensionImpl(Project project, LoomFiles files) { | ||||||
| 		super(project, files); | 		super(project, files); | ||||||
| 		this.project = project; | 		this.project = project; | ||||||
|  | 		this.mixinApExtension = new MixinApExtensionImpl(project); | ||||||
| 		this.loomFiles = files; | 		this.loomFiles = files; | ||||||
| 		this.unmappedMods = project.files(); | 		this.unmappedMods = project.files(); | ||||||
| 	} | 	} | ||||||
|  | @ -160,4 +162,9 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen | ||||||
| 
 | 
 | ||||||
| 		return provider; | 		return provider; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public MixinApExtension getMixinApExtension() { | ||||||
|  | 		return this.mixinApExtension; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										126
									
								
								src/main/java/net/fabricmc/loom/extension/MixinApExtension.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								src/main/java/net/fabricmc/loom/extension/MixinApExtension.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -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!"); | 						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!"); | 						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  | _ | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										139
									
								
								src/test/resources/projects/mixinApAutoRefmap/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/test/resources/projects/mixinApAutoRefmap/build.gradle
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										119
									
								
								src/test/resources/projects/mixinApSimple/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/test/resources/projects/mixinApSimple/build.gradle
									
									
									
									
									
										Normal file
									
								
							|  | @ -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. | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								src/test/resources/projects/mixinApSimple/gradle.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/test/resources/projects/mixinApSimple/gradle.properties
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||||
							
								
								
									
										10
									
								
								src/test/resources/projects/mixinApSimple/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/test/resources/projects/mixinApSimple/settings.gradle
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 a new issue