First pass on "shareCaches".
This commit is contained in:
		
							parent
							
								
									2d7421d4ed
								
							
						
					
					
						commit
						32eb0bd3c8
					
				
					 9 changed files with 411 additions and 10 deletions
				
			
		|  | @ -24,6 +24,7 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom; | package net.fabricmc.loom; | ||||||
| 
 | 
 | ||||||
|  | import java.io.IOException; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Optional; | import java.util.Optional; | ||||||
|  | @ -54,6 +55,8 @@ import net.fabricmc.loom.providers.MinecraftProvider; | ||||||
| import net.fabricmc.loom.providers.MappingsCache; | import net.fabricmc.loom.providers.MappingsCache; | ||||||
| import net.fabricmc.loom.task.RemapJarTask; | import net.fabricmc.loom.task.RemapJarTask; | ||||||
| import net.fabricmc.loom.task.RemapSourcesJarTask; | import net.fabricmc.loom.task.RemapSourcesJarTask; | ||||||
|  | import net.fabricmc.loom.task.shared.RemapAllJarsTask; | ||||||
|  | import net.fabricmc.loom.task.shared.RemapAllSourcesTask; | ||||||
| import net.fabricmc.loom.util.Constants; | import net.fabricmc.loom.util.Constants; | ||||||
| import net.fabricmc.loom.util.GroovyXmlUtil; | import net.fabricmc.loom.util.GroovyXmlUtil; | ||||||
| import net.fabricmc.loom.util.LoomDependencyManager; | import net.fabricmc.loom.util.LoomDependencyManager; | ||||||
|  | @ -64,7 +67,9 @@ import net.fabricmc.loom.util.mixin.JavaApInvoker; | ||||||
| import net.fabricmc.loom.util.mixin.KaptApInvoker; | import net.fabricmc.loom.util.mixin.KaptApInvoker; | ||||||
| import net.fabricmc.loom.util.mixin.ScalaApInvoker; | import net.fabricmc.loom.util.mixin.ScalaApInvoker; | ||||||
| import net.fabricmc.loom.util.FabricApiExtension; | import net.fabricmc.loom.util.FabricApiExtension; | ||||||
|  | import net.fabricmc.loom.util.SourceRemapper; | ||||||
| import net.fabricmc.loom.util.DownloadUtil; | import net.fabricmc.loom.util.DownloadUtil; | ||||||
|  | import net.fabricmc.loom.util.JarRemapper; | ||||||
| 
 | 
 | ||||||
| public class AbstractPlugin implements Plugin<Project> { | public class AbstractPlugin implements Plugin<Project> { | ||||||
| 	protected Project project; | 	protected Project project; | ||||||
|  | @ -268,6 +273,48 @@ public class AbstractPlugin implements Plugin<Project> { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				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", RemapAllJarsTask.class, task -> { | ||||||
|  | 							task.doLast(t -> { | ||||||
|  | 								try { | ||||||
|  | 									jarRemapper.remap(); | ||||||
|  | 								} catch (IOException e) { | ||||||
|  | 									throw new RuntimeException("Failed to remap jars", e); | ||||||
|  | 								} | ||||||
|  | 							}); | ||||||
|  | 						}); | ||||||
|  | 
 | ||||||
|  | 						for (Project subProject : rootProject.getAllprojects()) { | ||||||
|  | 							subProject.getTasks().getByName("build").dependsOn(parentTask); | ||||||
|  | 							subProject.getTasks().getByName("build").dependsOn(rootProject.getTasks().getByName("remapAllJars")); | ||||||
|  | 							rootProject.getTasks().getByName("remapAllJars").dependsOn(subProject.getTasks().getByName("remapJar")); | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						parentTask = rootProject.getTasks().getByName("remapAllSources"); | ||||||
|  | 						remapper = ((RemapAllSourcesTask) parentTask).sourceRemapper; | ||||||
|  | 
 | ||||||
|  | 						remapJarTask.jarRemapper = ((RemapJarTask) rootProject.getTasks().getByName("remapJar")).jarRemapper; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				try { | 				try { | ||||||
| 					AbstractArchiveTask sourcesTask = (AbstractArchiveTask) project1.getTasks().getByName("sourcesJar"); | 					AbstractArchiveTask sourcesTask = (AbstractArchiveTask) project1.getTasks().getByName("sourcesJar"); | ||||||
| 
 | 
 | ||||||
|  | @ -276,7 +323,12 @@ public class AbstractPlugin implements Plugin<Project> { | ||||||
| 					remapSourcesJarTask.setOutput(sourcesTask.getArchivePath()); | 					remapSourcesJarTask.setOutput(sourcesTask.getArchivePath()); | ||||||
| 					remapSourcesJarTask.doLast(task -> project1.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); | 					remapSourcesJarTask.doLast(task -> project1.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); | ||||||
| 					remapSourcesJarTask.dependsOn(project1.getTasks().getByName("sourcesJar")); | 					remapSourcesJarTask.dependsOn(project1.getTasks().getByName("sourcesJar")); | ||||||
| 					project1.getTasks().getByName("build").dependsOn(remapSourcesJarTask); | 
 | ||||||
|  | 					if (extension.isShareCaches()) { | ||||||
|  | 						remapSourcesJarTask.setSourceRemapper(remapper); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					parentTask.dependsOn(remapSourcesJarTask); | ||||||
| 				} catch (UnknownTaskException e) { | 				} catch (UnknownTaskException e) { | ||||||
| 					// pass | 					// pass | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -61,6 +61,7 @@ public class LoomGradleExtension { | ||||||
| 	public String customManifest = null; | 	public String customManifest = null; | ||||||
| 	public File accessWidener = null; | 	public File accessWidener = null; | ||||||
| 	public Function<String, Object> intermediaryUrl = mcVer -> "https://maven.fabricmc.net/net/fabricmc/intermediary/" + mcVer + "/intermediary-" + mcVer + "-v2.jar"; | 	public Function<String, Object> intermediaryUrl = mcVer -> "https://maven.fabricmc.net/net/fabricmc/intermediary/" + mcVer + "/intermediary-" + mcVer + "-v2.jar"; | ||||||
|  | 	public boolean shareCaches = false; | ||||||
| 
 | 
 | ||||||
| 	private List<Path> unmappedModsBuilt = new ArrayList<>(); | 	private List<Path> unmappedModsBuilt = new ArrayList<>(); | ||||||
| 
 | 
 | ||||||
|  | @ -338,4 +339,24 @@ public class LoomGradleExtension { | ||||||
| 		//Done like this to work around this possibly not being a java string... | 		//Done like this to work around this possibly not being a java string... | ||||||
| 		return s -> intermediaryUrl.apply(s).toString(); | 		return s -> intermediaryUrl.apply(s).toString(); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	public boolean isRootProject() { | ||||||
|  | 		return project.getRootProject() == project; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public LoomGradleExtension getRootGradleExtension() { | ||||||
|  | 		if (isRootProject()) { | ||||||
|  | 			return this; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return project.getRootProject().getExtensions().getByType(LoomGradleExtension.class); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public LoomGradleExtension getSharedGradleExtension() { | ||||||
|  | 		return isShareCaches() ? getRootGradleExtension() : this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public boolean isShareCaches() { | ||||||
|  | 		return shareCaches; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -120,6 +120,10 @@ public class MinecraftProvider extends DependencyProvider { | ||||||
| 	private void downloadMcJson(boolean offline) throws IOException { | 	private void downloadMcJson(boolean offline) throws IOException { | ||||||
| 		File manifests = new File(getExtension().getUserCache(), "version_manifest.json"); | 		File manifests = new File(getExtension().getUserCache(), "version_manifest.json"); | ||||||
| 
 | 
 | ||||||
|  | 		if (getExtension().isShareCaches() && !getExtension().isRootProject() && manifests.exists() && !isRefreshDeps()) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if (offline) { | 		if (offline) { | ||||||
| 			if (manifests.exists()) { | 			if (manifests.exists()) { | ||||||
| 				//If there is the manifests already we'll presume that's good enough | 				//If there is the manifests already we'll presume that's good enough | ||||||
|  | @ -171,6 +175,10 @@ public class MinecraftProvider extends DependencyProvider { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void downloadJars(Logger logger) throws IOException { | 	private void downloadJars(Logger logger) throws IOException { | ||||||
|  | 		if (getExtension().isShareCaches() && !getExtension().isRootProject() && minecraftClientJar.exists() && minecraftServerJar.exists() && !isRefreshDeps()) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		DownloadUtil.downloadIfChanged(new URL(versionInfo.downloads.get("client").url), minecraftClientJar, logger); | 		DownloadUtil.downloadIfChanged(new URL(versionInfo.downloads.get("client").url), minecraftClientJar, logger); | ||||||
| 		DownloadUtil.downloadIfChanged(new URL(versionInfo.downloads.get("server").url), minecraftServerJar, logger); | 		DownloadUtil.downloadIfChanged(new URL(versionInfo.downloads.get("server").url), minecraftServerJar, logger); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ package net.fabricmc.loom.task; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||||
|  | 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.LinkedHashSet; | import java.util.LinkedHashSet; | ||||||
|  | @ -38,6 +39,7 @@ 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.zeroturnaround.zip.ZipUtil; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.providers.MappingsProvider; | import net.fabricmc.loom.providers.MappingsProvider; | ||||||
|  | @ -46,6 +48,8 @@ import net.fabricmc.loom.util.MixinRefmapHelper; | ||||||
| import net.fabricmc.loom.util.NestedJars; | import net.fabricmc.loom.util.NestedJars; | ||||||
| import net.fabricmc.loom.util.TinyRemapperMappingsHelper; | import net.fabricmc.loom.util.TinyRemapperMappingsHelper; | ||||||
| import net.fabricmc.loom.util.accesswidener.AccessWidenerJarProcessor; | import net.fabricmc.loom.util.accesswidener.AccessWidenerJarProcessor; | ||||||
|  | import net.fabricmc.loom.util.JarRemapper; | ||||||
|  | import net.fabricmc.stitch.util.Pair; | ||||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; | 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; | ||||||
|  | @ -54,6 +58,7 @@ public class RemapJarTask extends Jar { | ||||||
| 	private RegularFileProperty input; | 	private RegularFileProperty input; | ||||||
| 	private Property<Boolean> addNestedDependencies; | 	private Property<Boolean> addNestedDependencies; | ||||||
| 	private Property<Boolean> remapAccessWidener; | 	private Property<Boolean> remapAccessWidener; | ||||||
|  | 	public JarRemapper jarRemapper; | ||||||
| 
 | 
 | ||||||
| 	public RemapJarTask() { | 	public RemapJarTask() { | ||||||
| 		super(); | 		super(); | ||||||
|  | @ -66,6 +71,14 @@ public class RemapJarTask extends Jar { | ||||||
| 
 | 
 | ||||||
| 	@TaskAction | 	@TaskAction | ||||||
| 	public void doTask() throws Throwable { | 	public void doTask() throws Throwable { | ||||||
|  | 		if (jarRemapper == null) { | ||||||
|  | 			doSingleRemap(); | ||||||
|  | 		} else { | ||||||
|  | 			scheduleRemap(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void doSingleRemap() 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(); | ||||||
|  | @ -150,6 +163,81 @@ public class RemapJarTask extends Jar { | ||||||
| 		}*/ | 		}*/ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	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()) { | ||||||
|  | 			Set<File> classpathFiles = new LinkedHashSet<>( | ||||||
|  | 					project.getConfigurations().getByName("compileClasspath").getFiles() | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			Path[] classpath = classpathFiles.stream() | ||||||
|  | 					.map(File::toPath) | ||||||
|  | 					.filter(Files::exists) | ||||||
|  | 					.toArray(Path[]::new); | ||||||
|  | 
 | ||||||
|  | 			jarRemapper.addToClasspath(classpath); | ||||||
|  | 
 | ||||||
|  | 			jarRemapper.addMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		File mixinMapFile = mappingsProvider.mappingsMixinExport; | ||||||
|  | 		Path mixinMapPath = mixinMapFile.toPath(); | ||||||
|  | 
 | ||||||
|  | 		if (mixinMapFile.exists()) { | ||||||
|  | 			jarRemapper.addMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		jarRemapper.scheduleRemap(input, output) | ||||||
|  | 				.supplyAccessWidener((remapData, remapper) -> { | ||||||
|  | 					if (getRemapAccessWidener().getOrElse(false) && extension.accessWidener != null) { | ||||||
|  | 						AccessWidenerJarProcessor accessWidenerJarProcessor = extension.getJarProcessorManager().getByType(AccessWidenerJarProcessor.class); | ||||||
|  | 						byte[] data; | ||||||
|  | 
 | ||||||
|  | 						try { | ||||||
|  | 							data = accessWidenerJarProcessor.getRemappedAccessWidener(remapper); | ||||||
|  | 						} catch (IOException e) { | ||||||
|  | 							throw new RuntimeException("Failed to remap access widener"); | ||||||
|  | 						} | ||||||
|  | 
 | ||||||
|  | 						return Pair.of(accessWidenerJarProcessor.getAccessWidenerPath(remapData.output), data); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					return null; | ||||||
|  | 				}) | ||||||
|  | 				.complete((data, accessWidener) -> { | ||||||
|  | 					if (!Files.exists(output)) { | ||||||
|  | 						throw new RuntimeException("Failed to remap " + input + " to " + output + " - file missing!"); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					if (MixinRefmapHelper.addRefmapName(extension.getRefmapName(), extension.getMixinJsonVersion(), 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 (accessWidener != null) { | ||||||
|  | 						ZipUtil.replaceEntry(data.output.toFile(), accessWidener.getLeft(), accessWidener.getRight()); | ||||||
|  | 					} | ||||||
|  | 				}); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@InputFile | 	@InputFile | ||||||
| 	public RegularFileProperty getInput() { | 	public RegularFileProperty getInput() { | ||||||
| 		return input; | 		return input; | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ import java.io.File; | ||||||
| 
 | 
 | ||||||
| import org.gradle.api.tasks.Input; | import org.gradle.api.tasks.Input; | ||||||
| import org.gradle.api.tasks.InputFile; | import org.gradle.api.tasks.InputFile; | ||||||
|  | import org.gradle.api.tasks.Internal; | ||||||
| import org.gradle.api.tasks.OutputFile; | import org.gradle.api.tasks.OutputFile; | ||||||
| import org.gradle.api.tasks.TaskAction; | import org.gradle.api.tasks.TaskAction; | ||||||
| 
 | 
 | ||||||
|  | @ -37,10 +38,34 @@ public class RemapSourcesJarTask extends AbstractLoomTask { | ||||||
| 	private Object input; | 	private Object input; | ||||||
| 	private Object output; | 	private Object output; | ||||||
| 	private String direction = "intermediary"; | 	private String direction = "intermediary"; | ||||||
|  | 	private SourceRemapper sourceRemapper = null; | ||||||
| 
 | 
 | ||||||
| 	@TaskAction | 	@TaskAction | ||||||
| 	public void remap() throws Exception { | 	public void remap() throws Exception { | ||||||
| 		SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named")); | 		if (sourceRemapper == null) { | ||||||
|  | 			SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named")); | ||||||
|  | 		} else { | ||||||
|  | 			sourceRemapper.scheduleRemapSources(getInput(), getOutput()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public String getDirection() { | ||||||
|  | 		return direction; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public RemapSourcesJarTask setDirection(String direction) { | ||||||
|  | 		this.direction = direction; | ||||||
|  | 		return this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Internal | ||||||
|  | 	public SourceRemapper getSourceRemapper() { | ||||||
|  | 		return sourceRemapper; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public RemapSourcesJarTask setSourceRemapper(SourceRemapper sourceRemapper) { | ||||||
|  | 		this.sourceRemapper = sourceRemapper; | ||||||
|  | 		return this; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@InputFile | 	@InputFile | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | /* | ||||||
|  |  * 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.task.shared; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.task.AbstractLoomTask; | ||||||
|  | 
 | ||||||
|  | public class RemapAllJarsTask extends AbstractLoomTask { | ||||||
|  | } | ||||||
|  | @ -0,0 +1,32 @@ | ||||||
|  | /* | ||||||
|  |  * 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.task.shared; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.task.AbstractLoomTask; | ||||||
|  | import net.fabricmc.loom.util.SourceRemapper; | ||||||
|  | 
 | ||||||
|  | public class RemapAllSourcesTask extends AbstractLoomTask { | ||||||
|  | 	public SourceRemapper sourceRemapper; | ||||||
|  | } | ||||||
							
								
								
									
										141
									
								
								src/main/java/net/fabricmc/loom/util/JarRemapper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/main/java/net/fabricmc/loom/util/JarRemapper.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,141 @@ | ||||||
|  | /* | ||||||
|  |  * 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.IOException; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.function.BiConsumer; | ||||||
|  | import java.util.function.BiFunction; | ||||||
|  | 
 | ||||||
|  | import org.objectweb.asm.commons.Remapper; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.stitch.util.Pair; | ||||||
|  | import net.fabricmc.tinyremapper.IMappingProvider; | ||||||
|  | import net.fabricmc.tinyremapper.InputTag; | ||||||
|  | import net.fabricmc.tinyremapper.OutputConsumerPath; | ||||||
|  | import net.fabricmc.tinyremapper.TinyRemapper; | ||||||
|  | 
 | ||||||
|  | public class JarRemapper { | ||||||
|  | 	private final List<IMappingProvider> mappingProviders = new ArrayList<>(); | ||||||
|  | 	private final Set<Path> classPath = new HashSet<>(); | ||||||
|  | 	private final List<RemapData> remapData = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 	public void addMappings(IMappingProvider mappingProvider) { | ||||||
|  | 		mappingProviders.add(mappingProvider); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void addToClasspath(Path... paths) { | ||||||
|  | 		classPath.addAll(Arrays.asList(paths)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public RemapData scheduleRemap(Path input, Path output) { | ||||||
|  | 		RemapData data = new RemapData(input, output); | ||||||
|  | 		remapData.add(data); | ||||||
|  | 		return data; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void remap() throws IOException { | ||||||
|  | 		TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper(); | ||||||
|  | 		mappingProviders.forEach(remapperBuilder::withMappings); | ||||||
|  | 
 | ||||||
|  | 		TinyRemapper remapper = remapperBuilder.build(); | ||||||
|  | 
 | ||||||
|  | 		Path[] remapClasspath = classPath.stream() | ||||||
|  | 				.filter(path -> | ||||||
|  | 						remapData.stream().noneMatch(remapData -> remapData.input.equals(path)) | ||||||
|  | 				) | ||||||
|  | 				.toArray(Path[]::new); | ||||||
|  | 
 | ||||||
|  | 		remapper.readClassPathAsync(remapClasspath); | ||||||
|  | 
 | ||||||
|  | 		for (RemapData data : remapData) { | ||||||
|  | 			InputTag tag = remapper.createInputTag(); | ||||||
|  | 			data.tag = tag; | ||||||
|  | 			remapper.readInputsAsync(tag, data.input); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		List<OutputConsumerPath> outputConsumers = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 		for (RemapData data : remapData) { | ||||||
|  | 			OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(data.output).build(); | ||||||
|  | 			outputConsumers.add(outputConsumer); | ||||||
|  | 
 | ||||||
|  | 			outputConsumer.addNonClassFiles(data.input); | ||||||
|  | 
 | ||||||
|  | 			data.processAccessWidener(remapper.getRemapper()); | ||||||
|  | 			remapper.apply(outputConsumer, data.tag); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		remapper.finish(); | ||||||
|  | 
 | ||||||
|  | 		for (OutputConsumerPath outputConsumer : outputConsumers) { | ||||||
|  | 			outputConsumer.close(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		remapData.forEach(RemapData::complete); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public static class RemapData { | ||||||
|  | 		public final Path input; | ||||||
|  | 		public final Path output; | ||||||
|  | 		BiFunction<RemapData, Remapper, Pair<String, byte[]>> accesWidenerSupplier; | ||||||
|  | 		BiConsumer<RemapData, Pair<String, byte[]>> onComplete; | ||||||
|  | 
 | ||||||
|  | 		private InputTag tag; | ||||||
|  | 		private Pair<String, byte[]> accessWidener; | ||||||
|  | 
 | ||||||
|  | 		public RemapData(Path input, Path output) { | ||||||
|  | 			this.input = input; | ||||||
|  | 			this.output = output; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public RemapData complete(BiConsumer<RemapData, Pair<String, byte[]>> onComplete) { | ||||||
|  | 			this.onComplete = onComplete; | ||||||
|  | 			return this; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public RemapData supplyAccessWidener(BiFunction<RemapData, Remapper, Pair<String, byte[]>> beforeFinish) { | ||||||
|  | 			this.accesWidenerSupplier = beforeFinish; | ||||||
|  | 			return this; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void complete() { | ||||||
|  | 			if (onComplete != null) { | ||||||
|  | 				onComplete.accept(this, accessWidener); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void processAccessWidener(Remapper remapper) { | ||||||
|  | 			if (accesWidenerSupplier != null) { | ||||||
|  | 				accessWidener = accesWidenerSupplier.apply(this, remapper); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -124,13 +124,7 @@ public class AccessWidenerJarProcessor implements JarProcessor { | ||||||
| 
 | 
 | ||||||
| 	//Called when remapping the mod | 	//Called when remapping the mod | ||||||
| 	public void remapAccessWidener(Path modJarPath, Remapper asmRemapper) throws IOException { | 	public void remapAccessWidener(Path modJarPath, Remapper asmRemapper) throws IOException { | ||||||
| 		AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, asmRemapper, "intermediary"); | 		byte[] bytes = getRemappedAccessWidener(asmRemapper); | ||||||
| 		AccessWidener remapped = remapper.remap(); |  | ||||||
| 
 |  | ||||||
| 		StringWriter writer = new StringWriter(); |  | ||||||
| 		remapped.write(writer); |  | ||||||
| 		byte[] bytes = writer.toString().getBytes(); |  | ||||||
| 		writer.close(); |  | ||||||
| 
 | 
 | ||||||
| 		String path = getAccessWidenerPath(modJarPath); | 		String path = getAccessWidenerPath(modJarPath); | ||||||
| 
 | 
 | ||||||
|  | @ -145,7 +139,17 @@ public class AccessWidenerJarProcessor implements JarProcessor { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private String getAccessWidenerPath(Path modJarPath) { | 	public byte[] getRemappedAccessWidener(Remapper asmRemapper) throws IOException { | ||||||
|  | 		AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, asmRemapper, "intermediary"); | ||||||
|  | 		AccessWidener remapped = remapper.remap(); | ||||||
|  | 
 | ||||||
|  | 		try (StringWriter writer = new StringWriter()) { | ||||||
|  | 			remapped.write(writer); | ||||||
|  | 			return writer.toString().getBytes(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public String getAccessWidenerPath(Path modJarPath) { | ||||||
| 		byte[] modJsonBytes = ZipUtil.unpackEntry(modJarPath.toFile(), "fabric.mod.json"); | 		byte[] modJsonBytes = ZipUtil.unpackEntry(modJarPath.toFile(), "fabric.mod.json"); | ||||||
| 
 | 
 | ||||||
| 		if (modJsonBytes == null) { | 		if (modJsonBytes == null) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue