Mod Remapping Refactor. (#362)
Improved gradle 7 support General cleanup
This commit is contained in:
		
							parent
							
								
									e9c7c21ede
								
							
						
					
					
						commit
						7231b9e053
					
				
					 13 changed files with 689 additions and 356 deletions
				
			
		
							
								
								
									
										95
									
								
								src/main/java/net/fabricmc/loom/build/nesting/JarNester.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/main/java/net/fabricmc/loom/build/nesting/JarNester.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,95 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 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.build.nesting; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.zip.ZipEntry; | ||||||
|  | 
 | ||||||
|  | import com.google.common.base.Preconditions; | ||||||
|  | import com.google.gson.JsonArray; | ||||||
|  | import com.google.gson.JsonElement; | ||||||
|  | import com.google.gson.JsonObject; | ||||||
|  | import org.gradle.api.logging.Logger; | ||||||
|  | import org.zeroturnaround.zip.FileSource; | ||||||
|  | import org.zeroturnaround.zip.ZipEntrySource; | ||||||
|  | import org.zeroturnaround.zip.ZipUtil; | ||||||
|  | import org.zeroturnaround.zip.transform.StringZipEntryTransformer; | ||||||
|  | import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.LoomGradlePlugin; | ||||||
|  | import net.fabricmc.loom.util.ModUtils; | ||||||
|  | 
 | ||||||
|  | public class JarNester { | ||||||
|  | 	public static void nestJars(Collection<File> jars, File modJar, Logger logger) { | ||||||
|  | 		if (jars.isEmpty()) { | ||||||
|  | 			logger.debug("Nothing to nest into " + modJar.getName()); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		Preconditions.checkArgument(ModUtils.isMod(modJar), "Cannot nest jars into none mod jar " + modJar.getName()); | ||||||
|  | 
 | ||||||
|  | 		ZipUtil.addEntries(modJar, jars.stream().map(file -> new FileSource("META-INF/jars/" + file.getName(), file)).toArray(ZipEntrySource[]::new)); | ||||||
|  | 
 | ||||||
|  | 		boolean didNest = ZipUtil.transformEntries(modJar, single(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() { | ||||||
|  | 			@Override | ||||||
|  | 			protected String transform(ZipEntry zipEntry, String input) { | ||||||
|  | 				JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class); | ||||||
|  | 				JsonArray nestedJars = json.getAsJsonArray("jars"); | ||||||
|  | 
 | ||||||
|  | 				if (nestedJars == null || !json.has("jars")) { | ||||||
|  | 					nestedJars = new JsonArray(); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				for (File file : jars) { | ||||||
|  | 					String nestedJarPath = "META-INF/jars/" + file.getName(); | ||||||
|  | 
 | ||||||
|  | 					for (JsonElement nestedJar : nestedJars) { | ||||||
|  | 						JsonObject jsonObject = nestedJar.getAsJsonObject(); | ||||||
|  | 
 | ||||||
|  | 						if (jsonObject.has("file") && jsonObject.get("file").getAsString().equals(nestedJarPath)) { | ||||||
|  | 							throw new IllegalStateException("Cannot nest 2 jars at the same path: " + nestedJarPath); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					JsonObject jsonObject = new JsonObject(); | ||||||
|  | 					jsonObject.addProperty("file", nestedJarPath); | ||||||
|  | 					nestedJars.add(jsonObject); | ||||||
|  | 
 | ||||||
|  | 					logger.debug("Nested " + nestedJarPath + " into " + modJar.getName()); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				json.add("jars", nestedJars); | ||||||
|  | 
 | ||||||
|  | 				return LoomGradlePlugin.GSON.toJson(json); | ||||||
|  | 			} | ||||||
|  | 		}))); | ||||||
|  | 		Preconditions.checkArgument(didNest, "Failed to nest jars into " + modJar.getName()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private static ZipEntryTransformerEntry[] single(ZipEntryTransformerEntry element) { | ||||||
|  | 		return new ZipEntryTransformerEntry[]{element}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,46 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 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.build.nesting; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | 
 | ||||||
|  | public class MergedNestedJarProvider implements NestedJarProvider { | ||||||
|  | 	private final NestedJarProvider[] parents; | ||||||
|  | 
 | ||||||
|  | 	public MergedNestedJarProvider(NestedJarProvider... parents) { | ||||||
|  | 		this.parents = parents; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public Collection<File> provide() { | ||||||
|  | 		return Arrays.stream(parents) | ||||||
|  | 				.map(NestedJarProvider::provide) | ||||||
|  | 				.flatMap(Collection::stream) | ||||||
|  | 				.collect(Collectors.toList()); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -22,22 +22,18 @@ | ||||||
|  * SOFTWARE. |  * SOFTWARE. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.build; | package net.fabricmc.loom.build.nesting; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.nio.file.Path; |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| import java.util.zip.ZipEntry; |  | ||||||
| 
 | 
 | ||||||
| import com.google.gson.JsonArray; |  | ||||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||||
| import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
|  | @ -50,121 +46,30 @@ import org.gradle.api.artifacts.ResolvedArtifact; | ||||||
| import org.gradle.api.artifacts.ResolvedConfiguration; | import org.gradle.api.artifacts.ResolvedConfiguration; | ||||||
| import org.gradle.api.artifacts.ResolvedDependency; | import org.gradle.api.artifacts.ResolvedDependency; | ||||||
| import org.gradle.api.tasks.bundling.AbstractArchiveTask; | import org.gradle.api.tasks.bundling.AbstractArchiveTask; | ||||||
| import org.zeroturnaround.zip.FileSource; |  | ||||||
| import org.zeroturnaround.zip.ZipEntrySource; |  | ||||||
| import org.zeroturnaround.zip.ZipUtil; | import org.zeroturnaround.zip.ZipUtil; | ||||||
| import org.zeroturnaround.zip.transform.StringZipEntryTransformer; |  | ||||||
| import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; |  | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.LoomGradlePlugin; | import net.fabricmc.loom.LoomGradlePlugin; | ||||||
| import net.fabricmc.loom.task.RemapJarTask; | import net.fabricmc.loom.task.RemapJarTask; | ||||||
| import net.fabricmc.loom.util.Constants; | import net.fabricmc.loom.util.Constants; | ||||||
| 
 | 
 | ||||||
| public class NestedJars { | public final class NestedDependencyProvider implements NestedJarProvider { | ||||||
| 	public static boolean addNestedJars(Project project, Path modJarPath) { | 	final Project project; | ||||||
| 		List<File> containedJars = getContainedJars(project); | 	final List<DependencyInfo<?>> files; | ||||||
| 
 | 
 | ||||||
| 		if (containedJars.isEmpty()) { | 	private NestedDependencyProvider(Project project, List<DependencyInfo<?>> files) { | ||||||
| 			return false; | 		this.project = project; | ||||||
| 		} | 		this.files = files; | ||||||
| 
 |  | ||||||
| 		File modJar = modJarPath.toFile(); |  | ||||||
| 
 |  | ||||||
| 		ZipUtil.addOrReplaceEntries(modJar, containedJars.stream().map(file -> new FileSource("META-INF/jars/" + file.getName(), file)).toArray(ZipEntrySource[]::new)); |  | ||||||
| 
 |  | ||||||
| 		return ZipUtil.transformEntries(modJar, single(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() { |  | ||||||
| 			@Override |  | ||||||
| 			protected String transform(ZipEntry zipEntry, String input) { |  | ||||||
| 				JsonObject json = LoomGradlePlugin.GSON.fromJson(input, JsonObject.class); |  | ||||||
| 				JsonArray nestedJars = json.getAsJsonArray("jars"); |  | ||||||
| 
 |  | ||||||
| 				if (nestedJars == null || !json.has("jars")) { |  | ||||||
| 					nestedJars = new JsonArray(); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				for (File file : containedJars) { |  | ||||||
| 					JsonObject jsonObject = new JsonObject(); |  | ||||||
| 					jsonObject.addProperty("file", "META-INF/jars/" + file.getName()); |  | ||||||
| 					nestedJars.add(jsonObject); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				json.add("jars", nestedJars); |  | ||||||
| 
 |  | ||||||
| 				return LoomGradlePlugin.GSON.toJson(json); |  | ||||||
| 			} |  | ||||||
| 		}))); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static List<File> getContainedJars(Project project) { | 	public static NestedDependencyProvider createNestedDependencyProviderFromConfiguration(Project project, Configuration configuration) { | ||||||
| 		List<File> fileList = new ArrayList<>(); | 		List<DependencyInfo<?>> fileList = new ArrayList<>(); | ||||||
|  | 		Set<String> visited = new HashSet<>(); | ||||||
| 
 | 
 | ||||||
| 		Configuration configuration = project.getConfigurations().getByName(Constants.Configurations.INCLUDE); | 		fileList.addAll(populateProjectDependencies(configuration, visited)); | ||||||
| 		ResolvedConfiguration resolvedConfiguration = configuration.getResolvedConfiguration(); | 		fileList.addAll(populateResolvedDependencies(configuration, visited)); | ||||||
| 		Set<ResolvedDependency> dependencies = resolvedConfiguration.getFirstLevelModuleDependencies(); |  | ||||||
| 
 | 
 | ||||||
| 		// Bit ugly doing this, id guess there is a better way but this works. | 		return new NestedDependencyProvider(project, fileList); | ||||||
| 		Set<String> projectDeps = new HashSet<>(); |  | ||||||
| 
 |  | ||||||
| 		for (Dependency dependency : configuration.getDependencies()) { |  | ||||||
| 			if (dependency instanceof ProjectDependency) { |  | ||||||
| 				ProjectDependency projectDependency = (ProjectDependency) dependency; |  | ||||||
| 				Project dependencyProject = projectDependency.getDependencyProject(); |  | ||||||
| 
 |  | ||||||
| 				projectDeps.add(dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion()); |  | ||||||
| 
 |  | ||||||
| 				// TODO change this to allow just normal jar tasks, so a project can have a none loom sub project |  | ||||||
| 				Collection<Task> remapJarTasks = dependencyProject.getTasksByName("remapJar", false); |  | ||||||
| 				Collection<Task> jarTasks = dependencyProject.getTasksByName("jar", false); |  | ||||||
| 
 |  | ||||||
| 				for (Task task : remapJarTasks.isEmpty() ? jarTasks : remapJarTasks) { |  | ||||||
| 					if (task instanceof RemapJarTask) { |  | ||||||
| 						fileList.addAll(prepareForNesting( |  | ||||||
| 								Collections.singleton(((RemapJarTask) task).getArchivePath()), |  | ||||||
| 								projectDependency, |  | ||||||
| 								new ProjectDependencyMetaExtractor(), |  | ||||||
| 								project |  | ||||||
| 						)); |  | ||||||
| 					} else if (task instanceof AbstractArchiveTask) { |  | ||||||
| 						fileList.addAll(prepareForNesting( |  | ||||||
| 								Collections.singleton(((AbstractArchiveTask) task).getArchivePath()), |  | ||||||
| 								projectDependency, |  | ||||||
| 								new ProjectDependencyMetaExtractor(), |  | ||||||
| 								project |  | ||||||
| 						)); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for (ResolvedDependency dependency : dependencies) { |  | ||||||
| 			if (projectDeps.contains(dependency.getModuleGroup() + ":" + dependency.getModuleName() + ":" + dependency.getModuleVersion())) { |  | ||||||
| 				continue; |  | ||||||
| 			} else { |  | ||||||
| 				fileList.addAll(prepareForNesting( |  | ||||||
| 						dependency |  | ||||||
| 								.getModuleArtifacts() |  | ||||||
| 								.stream() |  | ||||||
| 								.map(ResolvedArtifact::getFile) |  | ||||||
| 								.collect(Collectors.toSet()), |  | ||||||
| 						dependency, |  | ||||||
| 						new ResolvedDependencyMetaExtractor(), |  | ||||||
| 						project |  | ||||||
| 				)); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for (File file : fileList) { |  | ||||||
| 			if (!file.exists()) { |  | ||||||
| 				throw new RuntimeException("Failed to include nested jars, as it could not be found @ " + file.getAbsolutePath()); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (file.isDirectory() || !file.getName().endsWith(".jar")) { |  | ||||||
| 				throw new RuntimeException("Failed to include nested jars, as file was not a jar: " + file.getAbsolutePath()); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return fileList; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Looks for any deps that require a sub project to be built first | 	// Looks for any deps that require a sub project to be built first | ||||||
|  | @ -190,11 +95,69 @@ public class NestedJars { | ||||||
| 		return remapTasks; | 		return remapTasks; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//This is a good place to do pre-nesting operations, such as adding a fabric.mod.json to a library | 	private static List<DependencyInfo<ProjectDependency>> populateProjectDependencies(Configuration configuration, Set<String> visited) { | ||||||
| 	private static <D> List<File> prepareForNesting(Set<File> files, D dependency, DependencyMetaExtractor<D> metaExtractor, Project project) { | 		List<DependencyInfo<ProjectDependency>> fileList = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 		for (Dependency dependency : configuration.getDependencies()) { | ||||||
|  | 			if (dependency instanceof ProjectDependency) { | ||||||
|  | 				ProjectDependency projectDependency = (ProjectDependency) dependency; | ||||||
|  | 				Project dependencyProject = projectDependency.getDependencyProject(); | ||||||
|  | 
 | ||||||
|  | 				visited.add(dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion()); | ||||||
|  | 
 | ||||||
|  | 				// TODO change this to allow just normal jar tasks, so a project can have a none loom sub project | ||||||
|  | 				Collection<Task> remapJarTasks = dependencyProject.getTasksByName("remapJar", false); | ||||||
|  | 				Collection<Task> jarTasks = dependencyProject.getTasksByName("jar", false); | ||||||
|  | 
 | ||||||
|  | 				for (Task task : remapJarTasks.isEmpty() ? jarTasks : remapJarTasks) { | ||||||
|  | 					if (task instanceof RemapJarTask) { | ||||||
|  | 						File file = ((RemapJarTask) task).getArchivePath(); | ||||||
|  | 						fileList.add(new DependencyInfo<>(projectDependency, new ProjectDependencyMetaExtractor(), file)); | ||||||
|  | 					} else if (task instanceof AbstractArchiveTask) { | ||||||
|  | 						File file = ((AbstractArchiveTask) task).getArchivePath(); | ||||||
|  | 						fileList.add(new DependencyInfo<>(projectDependency, new ProjectDependencyMetaExtractor(), file)); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return fileList; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private static List<DependencyInfo<ResolvedDependency>> populateResolvedDependencies(Configuration configuration, Set<String> visited) { | ||||||
|  | 		ResolvedConfiguration resolvedConfiguration = configuration.getResolvedConfiguration(); | ||||||
|  | 		Set<ResolvedDependency> dependencies = resolvedConfiguration.getFirstLevelModuleDependencies(); | ||||||
|  | 
 | ||||||
|  | 		List<DependencyInfo<ResolvedDependency>> fileList = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 		for (ResolvedDependency dependency : dependencies) { | ||||||
|  | 			if (visited.contains(dependency.getModuleGroup() + ":" + dependency.getModuleName() + ":" + dependency.getModuleVersion())) { | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			List<File> files = dependency | ||||||
|  | 					.getModuleArtifacts() | ||||||
|  | 					.stream() | ||||||
|  | 					.map(ResolvedArtifact::getFile) | ||||||
|  | 					.collect(Collectors.toList()); | ||||||
|  | 
 | ||||||
|  | 			for (File file : files) { | ||||||
|  | 				fileList.add(new DependencyInfo<>(dependency, new ResolvedDependencyMetaExtractor(), file)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return fileList; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public List<File> provide() { | ||||||
| 		List<File> fileList = new ArrayList<>(); | 		List<File> fileList = new ArrayList<>(); | ||||||
| 
 | 
 | ||||||
| 		for (File file : files) { | 		for (DependencyInfo<?> metaFile : files) { | ||||||
|  | 			metaFile.validateInputs(); | ||||||
|  | 
 | ||||||
|  | 			File file = metaFile.file; | ||||||
|  | 
 | ||||||
| 			//A lib that doesnt have a mod.json, we turn it into a fake mod | 			//A lib that doesnt have a mod.json, we turn it into a fake mod | ||||||
| 			if (!ZipUtil.containsEntry(file, "fabric.mod.json")) { | 			if (!ZipUtil.containsEntry(file, "fabric.mod.json")) { | ||||||
| 				LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | 				LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
|  | @ -216,7 +179,7 @@ public class NestedJars { | ||||||
| 					throw new RuntimeException("Failed to copy file", e); | 					throw new RuntimeException("Failed to copy file", e); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				ZipUtil.addEntry(tempFile, "fabric.mod.json", getMod(dependency, metaExtractor).getBytes()); | 				ZipUtil.addEntry(tempFile, "fabric.mod.json", generateModForDependency(metaFile).getBytes()); | ||||||
| 				fileList.add(tempFile); | 				fileList.add(tempFile); | ||||||
| 			} else { | 			} else { | ||||||
| 				// Default copy the jar right in | 				// Default copy the jar right in | ||||||
|  | @ -228,7 +191,10 @@ public class NestedJars { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Generates a barebones mod for a dependency | 	// Generates a barebones mod for a dependency | ||||||
| 	private static <D> String getMod(D dependency, DependencyMetaExtractor<D> metaExtractor) { | 	private static <D> String generateModForDependency(DependencyInfo<D> info) { | ||||||
|  | 		DependencyMetaExtractor<D> metaExtractor = info.metaExtractor; | ||||||
|  | 		D dependency = info.dependency; | ||||||
|  | 
 | ||||||
| 		JsonObject jsonObject = new JsonObject(); | 		JsonObject jsonObject = new JsonObject(); | ||||||
| 		jsonObject.addProperty("schemaVersion", 1); | 		jsonObject.addProperty("schemaVersion", 1); | ||||||
| 		jsonObject.addProperty("id", (metaExtractor.group(dependency) + "_" + metaExtractor.name(dependency)).replaceAll("\\.", "_").toLowerCase(Locale.ENGLISH)); | 		jsonObject.addProperty("id", (metaExtractor.group(dependency) + "_" + metaExtractor.name(dependency)).replaceAll("\\.", "_").toLowerCase(Locale.ENGLISH)); | ||||||
|  | @ -242,8 +208,26 @@ public class NestedJars { | ||||||
| 		return LoomGradlePlugin.GSON.toJson(jsonObject); | 		return LoomGradlePlugin.GSON.toJson(jsonObject); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static ZipEntryTransformerEntry[] single(ZipEntryTransformerEntry element) { | 	private static class DependencyInfo<D> { | ||||||
| 		return new ZipEntryTransformerEntry[]{element}; | 		final D dependency; | ||||||
|  | 		final DependencyMetaExtractor<D> metaExtractor; | ||||||
|  | 		final File file; | ||||||
|  | 
 | ||||||
|  | 		DependencyInfo(D dependency, DependencyMetaExtractor<D> metaExtractor, File file) { | ||||||
|  | 			this.dependency = dependency; | ||||||
|  | 			this.metaExtractor = metaExtractor; | ||||||
|  | 			this.file = file; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void validateInputs() { | ||||||
|  | 			if (!file.exists()) { | ||||||
|  | 				throw new RuntimeException("Failed to include nested jars, as it could not be found @ " + file.getAbsolutePath()); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (file.isDirectory() || !file.getName().endsWith(".jar")) { | ||||||
|  | 				throw new RuntimeException("Failed to include nested jars, as file was not a jar: " + file.getAbsolutePath()); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private interface DependencyMetaExtractor<D> { | 	private interface DependencyMetaExtractor<D> { | ||||||
|  | @ -0,0 +1,67 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 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.build.nesting; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.Set; | ||||||
|  | 
 | ||||||
|  | import com.google.common.base.Preconditions; | ||||||
|  | import org.gradle.api.Project; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.util.ModUtils; | ||||||
|  | 
 | ||||||
|  | public final class NestedJarPathProvider implements NestedJarProvider { | ||||||
|  | 	private final Set<Object> nestedPaths; | ||||||
|  | 	private Set<File> files = null; | ||||||
|  | 	public NestedJarPathProvider(Set<Object> nestedPaths) { | ||||||
|  | 		this.nestedPaths = nestedPaths; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private Set<File> resolve(Project project) { | ||||||
|  | 		return project.files(nestedPaths).getFiles(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void prepare(Project project) { | ||||||
|  | 		if (files == null) { | ||||||
|  | 			files = resolve(project); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public Collection<File> provide() { | ||||||
|  | 		validateFiles(); | ||||||
|  | 		return files; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private void validateFiles() { | ||||||
|  | 		for (File file : files) { | ||||||
|  | 			Preconditions.checkArgument(file.getName().endsWith(".jar"), String.format("Tried to nest %s but it is not a jar", file.getAbsolutePath())); | ||||||
|  | 			Preconditions.checkArgument(file.exists(), String.format("Tried to nest jar %s but it does not exist", file.getAbsolutePath())); | ||||||
|  | 			Preconditions.checkArgument(ModUtils.isMod(file), String.format("Cannot use nest none mod jar %s", file.getAbsolutePath())); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,40 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 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.build.nesting; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.util.Collection; | ||||||
|  | 
 | ||||||
|  | import org.gradle.api.Project; | ||||||
|  | import org.jetbrains.annotations.ApiStatus; | ||||||
|  | 
 | ||||||
|  | @ApiStatus.Internal | ||||||
|  | public interface NestedJarProvider { | ||||||
|  | 	// provide all the files to be included, they should already be resolved but can be transformed here | ||||||
|  | 	Collection<File> provide(); | ||||||
|  | 
 | ||||||
|  | 	// Setup the files ready to be provided | ||||||
|  | 	default void prepare(Project project) { } | ||||||
|  | } | ||||||
|  | @ -24,13 +24,8 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.configuration; | package net.fabricmc.loom.configuration; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; |  | ||||||
| 
 |  | ||||||
| import org.gradle.api.Project; | 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.artifacts.Configuration; | ||||||
| import org.gradle.api.artifacts.repositories.MavenArtifactRepository; |  | ||||||
| import org.gradle.api.plugins.JavaPlugin; | import org.gradle.api.plugins.JavaPlugin; | ||||||
| import org.gradle.api.plugins.JavaPluginConvention; | import org.gradle.api.plugins.JavaPluginConvention; | ||||||
| import org.gradle.api.tasks.SourceSet; | import org.gradle.api.tasks.SourceSet; | ||||||
|  | @ -38,8 +33,6 @@ import org.gradle.api.tasks.bundling.AbstractArchiveTask; | ||||||
| import org.gradle.api.tasks.javadoc.Javadoc; | import org.gradle.api.tasks.javadoc.Javadoc; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.build.JarRemapper; |  | ||||||
| import net.fabricmc.loom.build.NestedJars; |  | ||||||
| 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; | ||||||
| import net.fabricmc.loom.build.mixin.ScalaApInvoker; | import net.fabricmc.loom.build.mixin.ScalaApInvoker; | ||||||
|  | @ -47,16 +40,8 @@ import net.fabricmc.loom.configuration.ide.SetupIntelijRunConfigs; | ||||||
| import net.fabricmc.loom.configuration.providers.LaunchProvider; | import net.fabricmc.loom.configuration.providers.LaunchProvider; | ||||||
| import net.fabricmc.loom.configuration.providers.MinecraftProvider; | import net.fabricmc.loom.configuration.providers.MinecraftProvider; | ||||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; | import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; | ||||||
| import net.fabricmc.loom.task.AbstractLoomTask; |  | ||||||
| import net.fabricmc.loom.task.RemapAllSourcesTask; |  | ||||||
| import net.fabricmc.loom.task.RemapJarTask; |  | ||||||
| import net.fabricmc.loom.task.RemapSourcesJarTask; |  | ||||||
| import net.fabricmc.loom.util.Constants; | import net.fabricmc.loom.util.Constants; | ||||||
| import net.fabricmc.loom.util.SourceRemapper; |  | ||||||
| 
 | 
 | ||||||
| /** |  | ||||||
|  * Add Minecraft dependencies to compile time. |  | ||||||
|  */ |  | ||||||
| public final class CompileConfiguration { | public final class CompileConfiguration { | ||||||
| 	private CompileConfiguration() { | 	private CompileConfiguration() { | ||||||
| 	} | 	} | ||||||
|  | @ -110,53 +95,18 @@ public final class CompileConfiguration { | ||||||
| 		extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, project); | 		extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, project); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	public static void configureCompile(Project p) { | ||||||
| 	 * Permit to add a Maven repository to a target project. | 		JavaPluginConvention javaModule = (JavaPluginConvention) p.getConvention().getPlugins().get("java"); | ||||||
| 	 * |  | ||||||
| 	 * @param target The target project |  | ||||||
| 	 * @param name   The name of the repository |  | ||||||
| 	 * @param url    The URL of the repository |  | ||||||
| 	 * @return An object containing the name and the URL of the repository that can be modified later |  | ||||||
| 	 */ |  | ||||||
| 	public static MavenArtifactRepository addMavenRepo(Project target, final String name, final String url) { |  | ||||||
| 		return target.getRepositories().maven(repo -> { |  | ||||||
| 			repo.setName(name); |  | ||||||
| 			repo.setUrl(url); |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public static void configureCompile(Project project) { |  | ||||||
| 		JavaPluginConvention javaModule = (JavaPluginConvention) project.getConvention().getPlugins().get("java"); |  | ||||||
| 
 | 
 | ||||||
| 		SourceSet main = javaModule.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); | 		SourceSet main = javaModule.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); | ||||||
| 
 | 
 | ||||||
| 		Javadoc javadoc = (Javadoc) project.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME); | 		Javadoc javadoc = (Javadoc) p.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME); | ||||||
| 		javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); | 		javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); | ||||||
| 
 | 
 | ||||||
| 		project.afterEvaluate(project1 -> { | 		p.afterEvaluate(project -> { | ||||||
| 			LoomGradleExtension extension = project1.getExtensions().getByType(LoomGradleExtension.class); | 			LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
| 
 | 
 | ||||||
| 			project1.getRepositories().flatDir(flatDirectoryArtifactRepository -> { | 			MavenConfiguration.setup(project); | ||||||
| 				flatDirectoryArtifactRepository.dir(extension.getRootProjectBuildCache()); |  | ||||||
| 				flatDirectoryArtifactRepository.setName("UserLocalCacheFiles"); |  | ||||||
| 			}); |  | ||||||
| 
 |  | ||||||
| 			project1.getRepositories().maven(mavenArtifactRepository -> { |  | ||||||
| 				mavenArtifactRepository.setUrl(extension.getRemappedModCache()); |  | ||||||
| 				mavenArtifactRepository.setName("UserLocalRemappedMods"); |  | ||||||
| 			}); |  | ||||||
| 
 |  | ||||||
| 			project1.getRepositories().maven(mavenArtifactRepository -> { |  | ||||||
| 				mavenArtifactRepository.setName("Fabric"); |  | ||||||
| 				mavenArtifactRepository.setUrl("https://maven.fabricmc.net/"); |  | ||||||
| 			}); |  | ||||||
| 
 |  | ||||||
| 			project1.getRepositories().maven(mavenArtifactRepository -> { |  | ||||||
| 				mavenArtifactRepository.setName("Mojang"); |  | ||||||
| 				mavenArtifactRepository.setUrl("https://libraries.minecraft.net/"); |  | ||||||
| 			}); |  | ||||||
| 
 |  | ||||||
| 			project1.getRepositories().mavenCentral(); |  | ||||||
| 
 | 
 | ||||||
| 			LoomDependencyManager dependencyManager = new LoomDependencyManager(); | 			LoomDependencyManager dependencyManager = new LoomDependencyManager(); | ||||||
| 			extension.setDependencyManager(dependencyManager); | 			extension.setDependencyManager(dependencyManager); | ||||||
|  | @ -165,100 +115,19 @@ public final class CompileConfiguration { | ||||||
| 			dependencyManager.addProvider(new MappingsProvider(project)); | 			dependencyManager.addProvider(new MappingsProvider(project)); | ||||||
| 			dependencyManager.addProvider(new LaunchProvider(project)); | 			dependencyManager.addProvider(new LaunchProvider(project)); | ||||||
| 
 | 
 | ||||||
| 			dependencyManager.handleDependencies(project1); | 			dependencyManager.handleDependencies(project); | ||||||
| 
 | 
 | ||||||
| 			project1.getTasks().getByName("idea").finalizedBy(project1.getTasks().getByName("genIdeaWorkspace")); | 			project.getTasks().getByName("idea").finalizedBy(project.getTasks().getByName("genIdeaWorkspace")); | ||||||
| 			project1.getTasks().getByName("eclipse").finalizedBy(project1.getTasks().getByName("genEclipseRuns")); | 			project.getTasks().getByName("eclipse").finalizedBy(project.getTasks().getByName("genEclipseRuns")); | ||||||
| 			project1.getTasks().getByName("cleanEclipse").finalizedBy(project1.getTasks().getByName("cleanEclipseRuns")); | 			project.getTasks().getByName("cleanEclipse").finalizedBy(project.getTasks().getByName("cleanEclipseRuns")); | ||||||
| 
 | 
 | ||||||
| 			SetupIntelijRunConfigs.setup(project1); | 			SetupIntelijRunConfigs.setup(project); | ||||||
| 
 | 
 | ||||||
| 			// Enables the default mod remapper | 			// Enables the default mod remapper | ||||||
| 			if (extension.remapMod) { | 			if (extension.remapMod) { | ||||||
| 				AbstractArchiveTask jarTask = (AbstractArchiveTask) project1.getTasks().getByName("jar"); | 				RemapConfiguration.setupDefaultRemap(project); | ||||||
| 				RemapJarTask remapJarTask = (RemapJarTask) project1.getTasks().findByName("remapJar"); |  | ||||||
| 
 |  | ||||||
| 				assert remapJarTask != null; |  | ||||||
| 
 |  | ||||||
| 				if (!remapJarTask.getInput().isPresent()) { |  | ||||||
| 					jarTask.setClassifier("dev"); |  | ||||||
| 					remapJarTask.setClassifier(""); |  | ||||||
| 					remapJarTask.getInput().set(jarTask.getArchivePath()); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				extension.getUnmappedModCollection().from(jarTask); |  | ||||||
| 				remapJarTask.getAddNestedDependencies().set(true); |  | ||||||
| 				remapJarTask.getRemapAccessWidener().set(true); |  | ||||||
| 
 |  | ||||||
| 				project1.getArtifacts().add("archives", remapJarTask); |  | ||||||
| 				remapJarTask.dependsOn(jarTask); |  | ||||||
| 				project1.getTasks().getByName("build").dependsOn(remapJarTask); |  | ||||||
| 
 |  | ||||||
| 				project.getTasks().withType(RemapJarTask.class).forEach(task -> { |  | ||||||
| 					if (task.getAddNestedDependencies().getOrElse(false)) { |  | ||||||
| 						NestedJars.getRequiredTasks(project1).forEach(task::dependsOn); |  | ||||||
| 					} |  | ||||||
| 				}); |  | ||||||
| 
 |  | ||||||
| 				SourceRemapper remapper = null; |  | ||||||
| 				Task parentTask = project1.getTasks().getByName("build"); |  | ||||||
| 
 |  | ||||||
| 				if (extension.isShareCaches()) { |  | ||||||
| 					Project rootProject = project.getRootProject(); |  | ||||||
| 
 |  | ||||||
| 					if (extension.isRootProject()) { |  | ||||||
| 						SourceRemapper sourceRemapper = new SourceRemapper(rootProject, false); |  | ||||||
| 						JarRemapper jarRemapper = new JarRemapper(); |  | ||||||
| 
 |  | ||||||
| 						remapJarTask.jarRemapper = jarRemapper; |  | ||||||
| 
 |  | ||||||
| 						rootProject.getTasks().register("remapAllSources", RemapAllSourcesTask.class, task -> { |  | ||||||
| 							task.sourceRemapper = sourceRemapper; |  | ||||||
| 							task.doLast(t -> sourceRemapper.remapAll()); |  | ||||||
| 						}); |  | ||||||
| 
 |  | ||||||
| 						parentTask = rootProject.getTasks().getByName("remapAllSources"); |  | ||||||
| 
 |  | ||||||
| 						rootProject.getTasks().register("remapAllJars", AbstractLoomTask.class, task -> { |  | ||||||
| 							task.doLast(t -> { |  | ||||||
| 								try { |  | ||||||
| 									jarRemapper.remap(); |  | ||||||
| 								} catch (IOException e) { |  | ||||||
| 									throw new RuntimeException("Failed to remap jars", e); |  | ||||||
| 								} |  | ||||||
| 							}); |  | ||||||
| 						}); |  | ||||||
| 					} else { |  | ||||||
| 						parentTask = rootProject.getTasks().getByName("remapAllSources"); |  | ||||||
| 						remapper = ((RemapAllSourcesTask) parentTask).sourceRemapper; |  | ||||||
| 
 |  | ||||||
| 						remapJarTask.jarRemapper = ((RemapJarTask) rootProject.getTasks().getByName("remapJar")).jarRemapper; |  | ||||||
| 
 |  | ||||||
| 						project1.getTasks().getByName("build").dependsOn(parentTask); |  | ||||||
| 						project1.getTasks().getByName("build").dependsOn(rootProject.getTasks().getByName("remapAllJars")); |  | ||||||
| 						rootProject.getTasks().getByName("remapAllJars").dependsOn(project1.getTasks().getByName("remapJar")); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				try { |  | ||||||
| 					AbstractArchiveTask sourcesTask = (AbstractArchiveTask) project1.getTasks().getByName("sourcesJar"); |  | ||||||
| 
 |  | ||||||
| 					RemapSourcesJarTask remapSourcesJarTask = (RemapSourcesJarTask) project1.getTasks().findByName("remapSourcesJar"); |  | ||||||
| 					remapSourcesJarTask.setInput(sourcesTask.getArchivePath()); |  | ||||||
| 					remapSourcesJarTask.setOutput(sourcesTask.getArchivePath()); |  | ||||||
| 					remapSourcesJarTask.doLast(task -> project1.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); |  | ||||||
| 					remapSourcesJarTask.dependsOn(project1.getTasks().getByName("sourcesJar")); |  | ||||||
| 
 |  | ||||||
| 					if (extension.isShareCaches()) { |  | ||||||
| 						remapSourcesJarTask.setSourceRemapper(remapper); |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					parentTask.dependsOn(remapSourcesJarTask); |  | ||||||
| 				} catch (UnknownTaskException ignored) { |  | ||||||
| 					// pass |  | ||||||
| 				} |  | ||||||
| 			} else { | 			} else { | ||||||
| 				AbstractArchiveTask jarTask = (AbstractArchiveTask) project1.getTasks().getByName("jar"); | 				AbstractArchiveTask jarTask = (AbstractArchiveTask) project.getTasks().getByName("jar"); | ||||||
| 				extension.getUnmappedModCollection().from(jarTask); | 				extension.getUnmappedModCollection().from(jarTask); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -281,7 +150,7 @@ public final class CompileConfiguration { | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		if (project.getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { | 		if (p.getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { | ||||||
| 			// If loom is applied after kapt, then kapt will use the AP arguments too early for loom to pass the arguments we need for mixin. | 			// If loom is applied after kapt, then kapt will use the AP arguments too early for loom to pass the arguments we need for mixin. | ||||||
| 			throw new IllegalArgumentException("fabric-loom must be applied BEFORE kapt in the plugins { } block."); | 			throw new IllegalArgumentException("fabric-loom must be applied BEFORE kapt in the plugins { } block."); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,57 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in all | ||||||
|  |  * copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package net.fabricmc.loom.configuration; | ||||||
|  | 
 | ||||||
|  | import org.gradle.api.Project; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.LoomGradleExtension; | ||||||
|  | 
 | ||||||
|  | public class MavenConfiguration { | ||||||
|  | 	public static void setup(Project project) { | ||||||
|  | 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
|  | 
 | ||||||
|  | 		project.getRepositories().flatDir(repo -> { | ||||||
|  | 			repo.setName("UserLocalCacheFiles"); | ||||||
|  | 			repo.dir(extension.getRootProjectBuildCache()); | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		project.getRepositories().maven(repo -> { | ||||||
|  | 			repo.setName("UserLocalRemappedMods"); | ||||||
|  | 			repo.setUrl(extension.getRemappedModCache()); | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		project.getRepositories().maven(repo -> { | ||||||
|  | 			repo.setName("Fabric"); | ||||||
|  | 			repo.setUrl("https://maven.fabricmc.net/"); | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		project.getRepositories().maven(repo -> { | ||||||
|  | 			repo.setName("Mojang"); | ||||||
|  | 			repo.setUrl("https://libraries.minecraft.net/"); | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		project.getRepositories().mavenCentral(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,159 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in all | ||||||
|  |  * copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package net.fabricmc.loom.configuration; | ||||||
|  | 
 | ||||||
|  | import java.io.IOException; | ||||||
|  | 
 | ||||||
|  | import com.google.common.base.Preconditions; | ||||||
|  | import org.gradle.api.Project; | ||||||
|  | import org.gradle.api.Task; | ||||||
|  | import org.gradle.api.UnknownTaskException; | ||||||
|  | import org.gradle.api.plugins.JavaPlugin; | ||||||
|  | import org.gradle.api.tasks.bundling.AbstractArchiveTask; | ||||||
|  | import org.jetbrains.annotations.ApiStatus; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.LoomGradleExtension; | ||||||
|  | import net.fabricmc.loom.build.JarRemapper; | ||||||
|  | import net.fabricmc.loom.build.nesting.NestedDependencyProvider; | ||||||
|  | import net.fabricmc.loom.task.AbstractLoomTask; | ||||||
|  | import net.fabricmc.loom.task.RemapAllSourcesTask; | ||||||
|  | import net.fabricmc.loom.task.RemapJarTask; | ||||||
|  | import net.fabricmc.loom.task.RemapSourcesJarTask; | ||||||
|  | import net.fabricmc.loom.util.SourceRemapper; | ||||||
|  | 
 | ||||||
|  | public class RemapConfiguration { | ||||||
|  | 	private static final String DEFAULT_JAR_TASK_NAME = JavaPlugin.JAR_TASK_NAME; | ||||||
|  | 	private static final String DEFAULT_SOURCES_JAR_TASK_NAME = "sourcesJar"; | ||||||
|  | 	private static final String DEFAULT_REMAP_JAR_TASK_NAME = "remapJar"; | ||||||
|  | 	private static final String DEFAULT_REMAP_SOURCES_JAR_TASK_NAME = "remapSourcesJar"; | ||||||
|  | 	private static final String DEFAULT_REMAP_ALL_JARS_TASK_NAME = "remapAllJars"; | ||||||
|  | 	private static final String DEFAULT_REMAP_ALL_SOURCES_TASK_NAME = "remapAllSources"; | ||||||
|  | 
 | ||||||
|  | 	public static void setupDefaultRemap(Project project) { | ||||||
|  | 		setupRemap(project, true, DEFAULT_JAR_TASK_NAME, DEFAULT_SOURCES_JAR_TASK_NAME, DEFAULT_REMAP_JAR_TASK_NAME, DEFAULT_REMAP_SOURCES_JAR_TASK_NAME, DEFAULT_REMAP_ALL_JARS_TASK_NAME, DEFAULT_REMAP_ALL_SOURCES_TASK_NAME); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@ApiStatus.Experimental // This is only an api if you squint really hard, expect it to explode every 5 mins. If you must call in afterEvaluate on all projects | ||||||
|  | 	public static void setupRemap(Project project, String jarTaskName, String sourcesJarTaskName, String remapJarTaskName, String remapSourcesJarTaskName, String remapAllJarsTaskName, String remapAllSourcesTaskName) { | ||||||
|  | 		setupRemap(project, false, jarTaskName, sourcesJarTaskName, remapJarTaskName, remapSourcesJarTaskName, remapAllJarsTaskName, remapAllSourcesTaskName); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// isDefaultRemap is set to true for the standard remap task, some defaults are left out when this is false. | ||||||
|  | 	private static void setupRemap(Project project, boolean isDefaultRemap, String jarTaskName, String sourcesJarTaskName, String remapJarTaskName, String remapSourcesJarTaskName, String remapAllJarsTaskName, String remapAllSourcesTaskName) { | ||||||
|  | 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
|  | 		AbstractArchiveTask jarTask = (AbstractArchiveTask) project.getTasks().getByName(jarTaskName); | ||||||
|  | 		RemapJarTask remapJarTask = (RemapJarTask) project.getTasks().findByName(remapJarTaskName); | ||||||
|  | 
 | ||||||
|  | 		assert remapJarTask != null; | ||||||
|  | 
 | ||||||
|  | 		if (!remapJarTask.getInput().isPresent() && isDefaultRemap) { | ||||||
|  | 			jarTask.setClassifier("dev"); | ||||||
|  | 			remapJarTask.setClassifier(""); | ||||||
|  | 			remapJarTask.getInput().set(jarTask.getArchivePath()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (isDefaultRemap) { | ||||||
|  | 			extension.getUnmappedModCollection().from(jarTask); | ||||||
|  | 			remapJarTask.getAddNestedDependencies().set(true); | ||||||
|  | 			remapJarTask.getRemapAccessWidener().set(true); | ||||||
|  | 
 | ||||||
|  | 			project.getArtifacts().add("archives", remapJarTask); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		remapJarTask.dependsOn(jarTask); | ||||||
|  | 		project.getTasks().getByName("build").dependsOn(remapJarTask); | ||||||
|  | 
 | ||||||
|  | 		// TODO this might be wrong? | ||||||
|  | 		project.getTasks().withType(RemapJarTask.class).forEach(task -> { | ||||||
|  | 			if (task.getAddNestedDependencies().getOrElse(false)) { | ||||||
|  | 				NestedDependencyProvider.getRequiredTasks(project).forEach(task::dependsOn); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		SourceRemapper remapper = null; | ||||||
|  | 		// TODO what is this for? | ||||||
|  | 		Task parentTask = project.getTasks().getByName("build"); | ||||||
|  | 
 | ||||||
|  | 		if (extension.isShareCaches()) { | ||||||
|  | 			Project rootProject = project.getRootProject(); | ||||||
|  | 
 | ||||||
|  | 			if (extension.isRootProject()) { | ||||||
|  | 				SourceRemapper sourceRemapper = new SourceRemapper(rootProject, false); | ||||||
|  | 				JarRemapper jarRemapper = new JarRemapper(); | ||||||
|  | 
 | ||||||
|  | 				remapJarTask.jarRemapper = jarRemapper; | ||||||
|  | 
 | ||||||
|  | 				rootProject.getTasks().register(remapAllSourcesTaskName, RemapAllSourcesTask.class, task -> { | ||||||
|  | 					task.sourceRemapper = sourceRemapper; | ||||||
|  | 					task.doLast(t -> sourceRemapper.remapAll()); | ||||||
|  | 				}); | ||||||
|  | 
 | ||||||
|  | 				parentTask = rootProject.getTasks().getByName(remapAllSourcesTaskName); | ||||||
|  | 
 | ||||||
|  | 				rootProject.getTasks().register(remapAllJarsTaskName, AbstractLoomTask.class, task -> { | ||||||
|  | 					task.doLast(t -> { | ||||||
|  | 						try { | ||||||
|  | 							jarRemapper.remap(); | ||||||
|  | 						} catch (IOException e) { | ||||||
|  | 							throw new RuntimeException("Failed to remap jars", e); | ||||||
|  | 						} | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  | 			} else { | ||||||
|  | 				parentTask = rootProject.getTasks().getByName(remapAllSourcesTaskName); | ||||||
|  | 				remapper = ((RemapAllSourcesTask) parentTask).sourceRemapper; | ||||||
|  | 				Preconditions.checkNotNull(remapper); | ||||||
|  | 
 | ||||||
|  | 				remapJarTask.jarRemapper = ((RemapJarTask) rootProject.getTasks().getByName(remapJarTaskName)).jarRemapper; | ||||||
|  | 
 | ||||||
|  | 				project.getTasks().getByName("build").dependsOn(parentTask); | ||||||
|  | 				project.getTasks().getByName("build").dependsOn(rootProject.getTasks().getByName(remapAllJarsTaskName)); | ||||||
|  | 				rootProject.getTasks().getByName(remapAllJarsTaskName).dependsOn(project.getTasks().getByName(remapJarTaskName)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try { | ||||||
|  | 			AbstractArchiveTask sourcesTask = (AbstractArchiveTask) project.getTasks().getByName(sourcesJarTaskName); | ||||||
|  | 
 | ||||||
|  | 			RemapSourcesJarTask remapSourcesJarTask = (RemapSourcesJarTask) project.getTasks().findByName(remapSourcesJarTaskName); | ||||||
|  | 			Preconditions.checkNotNull(remapSourcesJarTask, "Could not find " + remapSourcesJarTaskName + " in " + project.getName()); | ||||||
|  | 			remapSourcesJarTask.setInput(sourcesTask.getArchivePath()); | ||||||
|  | 			remapSourcesJarTask.setOutput(sourcesTask.getArchivePath()); | ||||||
|  | 			remapSourcesJarTask.dependsOn(project.getTasks().getByName(sourcesJarTaskName)); | ||||||
|  | 
 | ||||||
|  | 			if (isDefaultRemap) { | ||||||
|  | 				remapSourcesJarTask.doLast(task -> project.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (extension.isShareCaches()) { | ||||||
|  | 				remapSourcesJarTask.setSourceRemapper(remapper); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			parentTask.dependsOn(remapSourcesJarTask); | ||||||
|  | 		} catch (UnknownTaskException ignored) { | ||||||
|  | 			// pass | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -30,11 +30,15 @@ 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.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.LinkedHashSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
| 
 | 
 | ||||||
| import com.google.common.base.Preconditions; | import com.google.common.base.Preconditions; | ||||||
| import org.gradle.api.Action; | import org.gradle.api.Action; | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
|  | import org.gradle.api.artifacts.Configuration; | ||||||
| import org.gradle.api.file.FileCollection; | import org.gradle.api.file.FileCollection; | ||||||
| import org.gradle.api.file.RegularFileProperty; | import org.gradle.api.file.RegularFileProperty; | ||||||
| import org.gradle.api.provider.Property; | import org.gradle.api.provider.Property; | ||||||
|  | @ -42,49 +46,64 @@ import org.gradle.api.tasks.Input; | ||||||
| import org.gradle.api.tasks.InputFile; | import org.gradle.api.tasks.InputFile; | ||||||
| import org.gradle.api.tasks.TaskAction; | import org.gradle.api.tasks.TaskAction; | ||||||
| import org.gradle.jvm.tasks.Jar; | import org.gradle.jvm.tasks.Jar; | ||||||
|  | import org.jetbrains.annotations.ApiStatus; | ||||||
| import org.zeroturnaround.zip.ZipUtil; | import org.zeroturnaround.zip.ZipUtil; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.build.JarRemapper; | import net.fabricmc.loom.build.JarRemapper; | ||||||
| import net.fabricmc.loom.build.MixinRefmapHelper; | import net.fabricmc.loom.build.MixinRefmapHelper; | ||||||
| import net.fabricmc.loom.build.NestedJars; | import net.fabricmc.loom.build.nesting.NestedJarPathProvider; | ||||||
|  | import net.fabricmc.loom.build.nesting.JarNester; | ||||||
|  | import net.fabricmc.loom.build.nesting.MergedNestedJarProvider; | ||||||
|  | import net.fabricmc.loom.build.nesting.NestedDependencyProvider; | ||||||
|  | import net.fabricmc.loom.build.nesting.NestedJarProvider; | ||||||
| import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; | import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; | ||||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; | import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; | ||||||
|  | import net.fabricmc.loom.util.Constants; | ||||||
| import net.fabricmc.loom.util.TinyRemapperMappingsHelper; | import net.fabricmc.loom.util.TinyRemapperMappingsHelper; | ||||||
| import net.fabricmc.loom.util.ZipReprocessorUtil; |  | ||||||
| import net.fabricmc.loom.util.gradle.GradleSupport; | import net.fabricmc.loom.util.gradle.GradleSupport; | ||||||
| import net.fabricmc.stitch.util.Pair; | import net.fabricmc.stitch.util.Pair; | ||||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; |  | ||||||
| import net.fabricmc.tinyremapper.TinyRemapper; | import net.fabricmc.tinyremapper.TinyRemapper; | ||||||
| import net.fabricmc.tinyremapper.TinyUtils; | import net.fabricmc.tinyremapper.TinyUtils; | ||||||
| 
 | 
 | ||||||
| public class RemapJarTask extends Jar { | public class RemapJarTask extends Jar { | ||||||
| 	private final RegularFileProperty input; | 	private final RegularFileProperty input; | ||||||
| 	private final Property<Boolean> addNestedDependencies; | 	private final Property<Boolean> addNestedDependencies; | ||||||
|  | 	private final Property<Boolean> addDefaultNestedDependencies; | ||||||
| 	private final Property<Boolean> remapAccessWidener; | 	private final Property<Boolean> remapAccessWidener; | ||||||
| 	private final List<Action<TinyRemapper.Builder>> remapOptions = new ArrayList<>(); | 	private final List<Action<TinyRemapper.Builder>> remapOptions = new ArrayList<>(); | ||||||
| 	public JarRemapper jarRemapper; | 	public JarRemapper jarRemapper; | ||||||
| 	private FileCollection classpath; | 	private FileCollection classpath; | ||||||
|  | 	private final Set<Object> nestedPaths = new LinkedHashSet<>(); | ||||||
| 
 | 
 | ||||||
| 	public RemapJarTask() { | 	public RemapJarTask() { | ||||||
| 		super(); | 		super(); | ||||||
| 		input = GradleSupport.getfileProperty(getProject()); | 		input = GradleSupport.getfileProperty(getProject()); | ||||||
| 		addNestedDependencies = getProject().getObjects().property(Boolean.class); | 		addNestedDependencies = getProject().getObjects().property(Boolean.class); | ||||||
|  | 		addDefaultNestedDependencies = getProject().getObjects().property(Boolean.class); | ||||||
| 		remapAccessWidener = getProject().getObjects().property(Boolean.class); | 		remapAccessWidener = getProject().getObjects().property(Boolean.class); | ||||||
| 		// false by default, I have no idea why I have to do it for this property and not the other one | 		// false by default, I have no idea why I have to do it for this property and not the other one | ||||||
| 		remapAccessWidener.set(false); | 		remapAccessWidener.set(false); | ||||||
|  | 		addDefaultNestedDependencies.set(true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@TaskAction | 	@TaskAction | ||||||
| 	public void doTask() throws Throwable { | 	public void doTask() throws Throwable { | ||||||
|  | 		boolean singleRemap = false; | ||||||
|  | 
 | ||||||
| 		if (jarRemapper == null) { | 		if (jarRemapper == null) { | ||||||
| 			doSingleRemap(); | 			singleRemap = true; | ||||||
| 		} else { | 			jarRemapper = new JarRemapper(); | ||||||
| 			scheduleRemap(); | 		} | ||||||
|  | 
 | ||||||
|  | 		scheduleRemap(singleRemap || getProject().getExtensions().getByType(LoomGradleExtension.class).isRootProject()); | ||||||
|  | 
 | ||||||
|  | 		if (singleRemap) { | ||||||
|  | 			jarRemapper.remap(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void doSingleRemap() throws Throwable { | 	public void scheduleRemap(boolean isMainRemapTask) throws Throwable { | ||||||
| 		Project project = getProject(); | 		Project project = getProject(); | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
| 		Path input = this.getInput().getAsFile().get().toPath(); | 		Path input = this.getInput().getAsFile().get().toPath(); | ||||||
|  | @ -99,86 +118,7 @@ public class RemapJarTask extends Jar { | ||||||
| 		String fromM = "named"; | 		String fromM = "named"; | ||||||
| 		String toM = "intermediary"; | 		String toM = "intermediary"; | ||||||
| 
 | 
 | ||||||
| 		Path[] classpath = getRemapClasspath(); | 		if (isMainRemapTask) { | ||||||
| 
 |  | ||||||
| 		TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper(); |  | ||||||
| 
 |  | ||||||
| 		remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)); |  | ||||||
| 
 |  | ||||||
| 		for (File mixinMapFile : extension.getAllMixinMappings()) { |  | ||||||
| 			if (mixinMapFile.exists()) { |  | ||||||
| 				remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapFile.toPath(), fromM, toM)); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// Apply any requested options to tiny remapper |  | ||||||
| 		for (Action<TinyRemapper.Builder> remapOption : this.remapOptions) { |  | ||||||
| 			remapOption.execute(remapperBuilder); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		project.getLogger().info(":remapping " + input.getFileName()); |  | ||||||
| 
 |  | ||||||
| 		StringBuilder rc = new StringBuilder("Remap classpath: "); |  | ||||||
| 
 |  | ||||||
| 		for (Path p : classpath) { |  | ||||||
| 			rc.append("\n - ").append(p.toString()); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		project.getLogger().debug(rc.toString()); |  | ||||||
| 
 |  | ||||||
| 		TinyRemapper remapper = remapperBuilder.build(); |  | ||||||
| 
 |  | ||||||
| 		try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) { |  | ||||||
| 			outputConsumer.addNonClassFiles(input); |  | ||||||
| 			remapper.readClassPath(classpath); |  | ||||||
| 			remapper.readInputs(input); |  | ||||||
| 			remapper.apply(outputConsumer); |  | ||||||
| 		} catch (Exception e) { |  | ||||||
| 			remapper.finish(); |  | ||||||
| 			throw new RuntimeException("Failed to remap " + input + " to " + output, e); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (getRemapAccessWidener().getOrElse(false) && extension.accessWidener != null) { |  | ||||||
| 			extension.getJarProcessorManager().getByType(AccessWidenerJarProcessor.class).remapAccessWidener(output, remapper.getRemapper()); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		remapper.finish(); |  | ||||||
| 
 |  | ||||||
| 		if (!Files.exists(output)) { |  | ||||||
| 			throw new RuntimeException("Failed to remap " + input + " to " + output + " - file missing!"); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (MixinRefmapHelper.addRefmapName(extension.getRefmapName(), output)) { |  | ||||||
| 			project.getLogger().debug("Transformed mixin reference maps in output JAR!"); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (getAddNestedDependencies().getOrElse(false)) { |  | ||||||
| 			if (NestedJars.addNestedJars(project, output)) { |  | ||||||
| 				project.getLogger().debug("Added nested jar paths to mod json"); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (isReproducibleFileOrder() || isPreserveFileTimestamps()) { |  | ||||||
| 			ZipReprocessorUtil.reprocessZip(output.toFile(), isReproducibleFileOrder(), isPreserveFileTimestamps()); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public void scheduleRemap() throws Throwable { |  | ||||||
| 		Project project = getProject(); |  | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); |  | ||||||
| 		Path input = this.getInput().getAsFile().get().toPath(); |  | ||||||
| 		Path output = this.getArchivePath().toPath(); |  | ||||||
| 
 |  | ||||||
| 		if (!Files.exists(input)) { |  | ||||||
| 			throw new FileNotFoundException(input.toString()); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); |  | ||||||
| 
 |  | ||||||
| 		String fromM = "named"; |  | ||||||
| 		String toM = "intermediary"; |  | ||||||
| 
 |  | ||||||
| 		if (extension.isRootProject()) { |  | ||||||
| 			jarRemapper.addToClasspath(getRemapClasspath()); | 			jarRemapper.addToClasspath(getRemapClasspath()); | ||||||
| 
 | 
 | ||||||
| 			jarRemapper.addMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)); | 			jarRemapper.addMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)); | ||||||
|  | @ -193,6 +133,9 @@ public class RemapJarTask extends Jar { | ||||||
| 		// Add remap options to the jar remapper | 		// Add remap options to the jar remapper | ||||||
| 		jarRemapper.addOptions(this.remapOptions); | 		jarRemapper.addOptions(this.remapOptions); | ||||||
| 
 | 
 | ||||||
|  | 		NestedJarProvider nestedJarProvider = getNestedJarProvider(); | ||||||
|  | 		nestedJarProvider.prepare(getProject()); | ||||||
|  | 
 | ||||||
| 		jarRemapper.scheduleRemap(input, output) | 		jarRemapper.scheduleRemap(input, output) | ||||||
| 				.supplyAccessWidener((remapData, remapper) -> { | 				.supplyAccessWidener((remapData, remapper) -> { | ||||||
| 					if (getRemapAccessWidener().getOrElse(false) && extension.accessWidener != null) { | 					if (getRemapAccessWidener().getOrElse(false) && extension.accessWidener != null) { | ||||||
|  | @ -223,9 +166,7 @@ public class RemapJarTask extends Jar { | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					if (getAddNestedDependencies().getOrElse(false)) { | 					if (getAddNestedDependencies().getOrElse(false)) { | ||||||
| 						if (NestedJars.addNestedJars(project, output)) { | 						JarNester.nestJars(nestedJarProvider.provide(), output.toFile(), project.getLogger()); | ||||||
| 							project.getLogger().debug("Added nested jar paths to mod json"); |  | ||||||
| 						} |  | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					if (accessWidener != null) { | 					if (accessWidener != null) { | ||||||
|  | @ -235,6 +176,25 @@ public class RemapJarTask extends Jar { | ||||||
| 				}); | 				}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private NestedJarProvider getNestedJarProvider() { | ||||||
|  | 		Configuration includeConfiguration = getProject().getConfigurations().getByName(Constants.Configurations.INCLUDE); | ||||||
|  | 
 | ||||||
|  | 		if (!addDefaultNestedDependencies.getOrElse(true)) { | ||||||
|  | 			return new NestedJarPathProvider(nestedPaths); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		NestedJarProvider baseProvider = NestedDependencyProvider.createNestedDependencyProviderFromConfiguration(getProject(), includeConfiguration); | ||||||
|  | 
 | ||||||
|  | 		if (nestedPaths.isEmpty()) { | ||||||
|  | 			return baseProvider; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return new MergedNestedJarProvider( | ||||||
|  | 				baseProvider, | ||||||
|  | 				new NestedJarPathProvider(nestedPaths) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private Path[] getRemapClasspath() { | 	private Path[] getRemapClasspath() { | ||||||
| 		FileCollection files = this.classpath; | 		FileCollection files = this.classpath; | ||||||
| 
 | 
 | ||||||
|  | @ -258,6 +218,11 @@ public class RemapJarTask extends Jar { | ||||||
| 		return addNestedDependencies; | 		return addNestedDependencies; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Input | ||||||
|  | 	public Property<Boolean> getAddDefaultNestedDependencies() { | ||||||
|  | 		return addDefaultNestedDependencies; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@Input | 	@Input | ||||||
| 	public Property<Boolean> getRemapAccessWidener() { | 	public Property<Boolean> getRemapAccessWidener() { | ||||||
| 		return remapAccessWidener; | 		return remapAccessWidener; | ||||||
|  | @ -276,4 +241,12 @@ public class RemapJarTask extends Jar { | ||||||
| 
 | 
 | ||||||
| 		return this; | 		return this; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	@ApiStatus.Experimental // This only allows mod jars, proceed with care when trying to pass in configurations with projects, or something that depends on a task. | ||||||
|  | 	public RemapJarTask include(Object... paths) { | ||||||
|  | 		Collections.addAll(nestedPaths, paths); | ||||||
|  | 		this.addNestedDependencies.set(true); | ||||||
|  | 
 | ||||||
|  | 		return this; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										42
									
								
								src/main/java/net/fabricmc/loom/util/ModUtils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/main/java/net/fabricmc/loom/util/ModUtils.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in all | ||||||
|  |  * copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package net.fabricmc.loom.util; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.zip.ZipFile; | ||||||
|  | 
 | ||||||
|  | public final class ModUtils { | ||||||
|  | 	private ModUtils() { | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public static boolean isMod(File input) { | ||||||
|  | 		try (ZipFile zipFile = new ZipFile(input)) { | ||||||
|  | 			return zipFile.getEntry("fabric.mod.json") != null; | ||||||
|  | 		} catch (IOException e) { | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -58,9 +58,4 @@ class MultiProjectTest extends Specification implements ProjectTestTrait, Archiv | ||||||
| 			'6.8.3' 			| _ | 			'6.8.3' 			| _ | ||||||
| 			'7.0-milestone-2'	| _ | 			'7.0-milestone-2'	| _ | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	@Override |  | ||||||
| 	String warningMode(String gradleVersion) { |  | ||||||
| 		"none" // TODO fix this! |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -88,7 +88,7 @@ trait ProjectTestTrait { | ||||||
| 			return "all" | 			return "all" | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		System.getenv().TEST_WARNING_MODE ?: 'all' | 		'fail' | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	String gradleHomeDirectory(String gradleVersion) { | 	String gradleHomeDirectory(String gradleVersion) { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,6 @@ | ||||||
|  | { | ||||||
|  |   "schemaVersion": 1, | ||||||
|  |   "id": "modid", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "name": "Example Mod" | ||||||
|  | } | ||||||
		Loading…
	
		Reference in a new issue