Respect reproducibleFileOrder and preserveFileTimestamps (#304)
* Respect reproducibleFileOrder and preserveFileTimestamps * Also Respect On Sources Jars * java 8 * checkstyle * Please Rerun Actions
This commit is contained in:
		
							parent
							
								
									9f6c8486fb
								
							
						
					
					
						commit
						7e5053b0c5
					
				
					 5 changed files with 104 additions and 13 deletions
				
			
		|  | @ -48,6 +48,7 @@ import net.fabricmc.loom.util.GradleSupport; | ||||||
| import net.fabricmc.loom.util.MixinRefmapHelper; | 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.ZipReprocessorUtil; | ||||||
| import net.fabricmc.loom.util.accesswidener.AccessWidenerJarProcessor; | import net.fabricmc.loom.util.accesswidener.AccessWidenerJarProcessor; | ||||||
| import net.fabricmc.loom.util.JarRemapper; | import net.fabricmc.loom.util.JarRemapper; | ||||||
| import net.fabricmc.stitch.util.Pair; | import net.fabricmc.stitch.util.Pair; | ||||||
|  | @ -151,16 +152,9 @@ public class RemapJarTask extends Jar { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/*try { | 		if (isReproducibleFileOrder() || isPreserveFileTimestamps()) { | ||||||
| 			if (modJar.exists()) { | 			ZipReprocessorUtil.reprocessZip(output.toFile(), isReproducibleFileOrder(), isPreserveFileTimestamps()); | ||||||
| 				Files.move(modJar, modJarUnmappedCopy); | 		} | ||||||
| 				extension.addUnmappedMod(modJarUnmappedCopy); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			Files.move(modJarOutput, modJar); |  | ||||||
| 		} catch (IOException e) { |  | ||||||
| 			throw new RuntimeException(e); |  | ||||||
| 		}*/ |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void scheduleRemap() throws Throwable { | 	public void scheduleRemap() throws Throwable { | ||||||
|  |  | ||||||
|  | @ -26,6 +26,8 @@ package net.fabricmc.loom.task; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| 
 | 
 | ||||||
|  | import org.gradle.api.model.ObjectFactory; | ||||||
|  | import org.gradle.api.provider.Property; | ||||||
| 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.Internal; | ||||||
|  | @ -33,19 +35,29 @@ import org.gradle.api.tasks.OutputFile; | ||||||
| import org.gradle.api.tasks.TaskAction; | import org.gradle.api.tasks.TaskAction; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.util.SourceRemapper; | import net.fabricmc.loom.util.SourceRemapper; | ||||||
|  | import net.fabricmc.loom.util.ZipReprocessorUtil; | ||||||
| 
 | 
 | ||||||
| public class RemapSourcesJarTask extends AbstractLoomTask { | 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; | 	private SourceRemapper sourceRemapper = null; | ||||||
|  | 	private final Property<Boolean> archivePreserveFileTimestamps; | ||||||
|  | 	private final Property<Boolean> archiveReproducibleFileOrder; | ||||||
|  | 
 | ||||||
|  | 	public RemapSourcesJarTask() { | ||||||
|  | 		ObjectFactory objectFactory = getProject().getObjects(); | ||||||
|  | 		archivePreserveFileTimestamps = objectFactory.property(Boolean.class); | ||||||
|  | 		archiveReproducibleFileOrder = objectFactory.property(Boolean.class); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	@TaskAction | 	@TaskAction | ||||||
| 	public void remap() throws Exception { | 	public void remap() throws Exception { | ||||||
| 		if (sourceRemapper == null) { | 		if (sourceRemapper == null) { | ||||||
| 			SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named")); | 			SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named")); | ||||||
|  | 			ZipReprocessorUtil.reprocessZip(getOutput(), archivePreserveFileTimestamps.getOrElse(true), archiveReproducibleFileOrder.getOrElse(false)); | ||||||
| 		} else { | 		} else { | ||||||
| 			sourceRemapper.scheduleRemapSources(getInput(), getOutput()); | 			sourceRemapper.scheduleRemapSources(getInput(), getOutput(), archivePreserveFileTimestamps.getOrElse(true), archiveReproducibleFileOrder.getOrElse(false)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -164,7 +164,7 @@ public class ModCompileRemapper { | ||||||
| 
 | 
 | ||||||
| 		if (!remappedSources.exists() || sources.lastModified() <= 0 || sources.lastModified() > remappedSources.lastModified() || refreshDeps) { | 		if (!remappedSources.exists() || sources.lastModified() <= 0 || sources.lastModified() > remappedSources.lastModified() || refreshDeps) { | ||||||
| 			try { | 			try { | ||||||
| 				sourceRemapper.scheduleRemapSources(sources, remappedSources); | 				sourceRemapper.scheduleRemapSources(sources, remappedSources, false, true); // Depenedency sources are used in ide only so don't need to be reproducable | ||||||
| 
 | 
 | ||||||
| 				// Set the remapped sources creation date to match the sources if we're likely succeeded in making it | 				// Set the remapped sources creation date to match the sources if we're likely succeeded in making it | ||||||
| 				remappedSources.setLastModified(sources.lastModified()); | 				remappedSources.setLastModified(sources.lastModified()); | ||||||
|  |  | ||||||
|  | @ -62,15 +62,21 @@ public class SourceRemapper { | ||||||
| 
 | 
 | ||||||
| 	public static void remapSources(Project project, File input, File output, boolean named) throws Exception { | 	public static void remapSources(Project project, File input, File output, boolean named) throws Exception { | ||||||
| 		SourceRemapper sourceRemapper = new SourceRemapper(project, named); | 		SourceRemapper sourceRemapper = new SourceRemapper(project, named); | ||||||
| 		sourceRemapper.scheduleRemapSources(input, output); | 		sourceRemapper.scheduleRemapSources(input, output, false, true); | ||||||
| 		sourceRemapper.remapAll(); | 		sourceRemapper.remapAll(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Deprecated | ||||||
| 	public void scheduleRemapSources(File source, File destination) throws Exception { | 	public void scheduleRemapSources(File source, File destination) throws Exception { | ||||||
|  | 		scheduleRemapSources(source, destination, false, true); // Not reproducable by default, old behavior | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void scheduleRemapSources(File source, File destination, boolean reproducibleFileOrder, boolean preserveFileTimestamps) throws Exception { | ||||||
| 		remapTasks.add((logger) -> { | 		remapTasks.add((logger) -> { | ||||||
| 			try { | 			try { | ||||||
| 				logger.progress("remapping sources - " + source.getName()); | 				logger.progress("remapping sources - " + source.getName()); | ||||||
| 				remapSourcesInner(source, destination); | 				remapSourcesInner(source, destination); | ||||||
|  | 				ZipReprocessorUtil.reprocessZip(destination, reproducibleFileOrder, preserveFileTimestamps); | ||||||
| 			} catch (Exception e) { | 			} catch (Exception e) { | ||||||
| 				throw new RuntimeException("Failed to remap sources for " + source, e); | 				throw new RuntimeException("Failed to remap sources for " + source, e); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
							
								
								
									
										79
									
								
								src/main/java/net/fabricmc/loom/util/ZipReprocessorUtil.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/main/java/net/fabricmc/loom/util/ZipReprocessorUtil.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | ||||||
|  | /* | ||||||
|  |  * 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.ByteArrayOutputStream; | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.FileOutputStream; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.util.zip.ZipEntry; | ||||||
|  | import java.util.zip.ZipFile; | ||||||
|  | import java.util.zip.ZipOutputStream; | ||||||
|  | 
 | ||||||
|  | public class ZipReprocessorUtil { | ||||||
|  | 	private ZipReprocessorUtil() { } | ||||||
|  | 
 | ||||||
|  | 	public static void reprocessZip(File file, boolean reproducibleFileOrder, boolean preserveFileTimestamps) throws IOException { | ||||||
|  | 		if (!reproducibleFileOrder && preserveFileTimestamps) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try (ZipFile zipFile = new ZipFile(file)) { | ||||||
|  | 			ZipEntry[] entries; | ||||||
|  | 
 | ||||||
|  | 			if (reproducibleFileOrder) { | ||||||
|  | 				entries = zipFile.stream().sorted((a, b) -> a.getName().compareTo(b.getName())).toArray(ZipEntry[]::new); | ||||||
|  | 			} else { | ||||||
|  | 				entries = zipFile.stream().toArray(ZipEntry[]::new); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			ByteArrayOutputStream outZip = new ByteArrayOutputStream(zipFile.size()); | ||||||
|  | 
 | ||||||
|  | 			try (ZipOutputStream zipOutputStream = new ZipOutputStream(outZip)) { | ||||||
|  | 				for (ZipEntry entry : entries) { | ||||||
|  | 					if (!preserveFileTimestamps) { | ||||||
|  | 						entry.setTime(0); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					zipOutputStream.putNextEntry(entry); | ||||||
|  | 					InputStream inputStream = zipFile.getInputStream(entry); | ||||||
|  | 					byte[] buf = new byte[1024]; | ||||||
|  | 					int length; | ||||||
|  | 
 | ||||||
|  | 					while ((length = inputStream.read(buf)) > 0) { | ||||||
|  | 						zipOutputStream.write(buf, 0, length); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					zipOutputStream.closeEntry(); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { | ||||||
|  | 				outZip.writeTo(fileOutputStream); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in a new issue