working source code remapping for mod dependencies
This commit is contained in:
		
							parent
							
								
									530896e41a
								
							
						
					
					
						commit
						d9b8c90b5f
					
				
					 7 changed files with 129 additions and 23 deletions
				
			
		|  | @ -35,6 +35,7 @@ import java.nio.file.FileSystem; | |||
| import java.nio.file.FileSystems; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.function.Consumer; | ||||
| 
 | ||||
| //TODO fix local mappings | ||||
| //TODO possibly use maven for mappings, can fix above at the same time | ||||
|  | @ -52,13 +53,13 @@ public class MappingsProvider extends DependencyProvider { | |||
| 	public File MAPPINGS_MIXIN_EXPORT; | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension) throws Exception { | ||||
| 	public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception { | ||||
| 		MinecraftProvider minecraftProvider = getDependencyManager().getProvider(MinecraftProvider.class); | ||||
| 
 | ||||
| 		project.getLogger().lifecycle(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")"); | ||||
| 
 | ||||
| 		String version = dependency.getResolvedVersion(); | ||||
| 		File mappingsJar = dependency.resolveFile(); | ||||
| 		File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + dependency)); | ||||
| 
 | ||||
| 		this.mappingsName = dependency.getDependency().getName(); | ||||
| 		this.minecraftVersion = version.substring(0, version.lastIndexOf('.')); | ||||
|  | @ -95,7 +96,7 @@ public class MappingsProvider extends DependencyProvider { | |||
| 
 | ||||
| 		mappedProvider = new MinecraftMappedProvider(); | ||||
| 		mappedProvider.initFiles(project, minecraftProvider, this); | ||||
| 		mappedProvider.provide(dependency, project, extension); | ||||
| 		mappedProvider.provide(dependency, project, extension, postPopulationScheduler); | ||||
| 	} | ||||
| 
 | ||||
| 	public void initFiles(Project project) { | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ import org.gradle.api.Project; | |||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.Collection; | ||||
| import java.util.function.Consumer; | ||||
| 
 | ||||
| public class MinecraftMappedProvider extends DependencyProvider { | ||||
|     public File MINECRAFT_MAPPED_JAR; | ||||
|  | @ -40,7 +41,7 @@ public class MinecraftMappedProvider extends DependencyProvider { | |||
|     private MinecraftProvider minecraftProvider; | ||||
| 
 | ||||
|     @Override | ||||
|     public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension) throws Exception { | ||||
|     public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception { | ||||
|         if (!extension.getMappingsProvider().MAPPINGS_TINY.exists()) { | ||||
|             throw new RuntimeException("mappings file not found"); | ||||
|         } | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ import java.io.IOException; | |||
| import java.net.URL; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.Optional; | ||||
| import java.util.function.Consumer; | ||||
| 
 | ||||
| public class MinecraftProvider extends DependencyProvider { | ||||
| 
 | ||||
|  | @ -55,7 +56,7 @@ public class MinecraftProvider extends DependencyProvider { | |||
| 	Gson gson = new Gson(); | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension) throws Exception { | ||||
| 	public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception { | ||||
| 		minecraftVersion = dependency.getDependency().getVersion(); | ||||
| 
 | ||||
| 		initFiles(project); | ||||
|  |  | |||
|  | @ -24,27 +24,33 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.providers; | ||||
| 
 | ||||
| import com.google.common.io.Files; | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| import net.fabricmc.loom.util.DependencyProvider; | ||||
| import net.fabricmc.loom.util.ModProcessor; | ||||
| import net.fabricmc.loom.util.SourceRemapper; | ||||
| import org.gradle.api.Project; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.Optional; | ||||
| import java.util.function.Consumer; | ||||
| 
 | ||||
| public class ModRemapperProvider extends DependencyProvider { | ||||
| 	@Override | ||||
| 	public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension) { | ||||
| 		File input = dependency.resolveFile(); | ||||
| 	public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) { | ||||
| 		// Provide JAR | ||||
| 		File input = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + dependency)); | ||||
| 
 | ||||
| 		project.getLogger().lifecycle("Providing " + dependency.getDepString()); | ||||
| 		project.getLogger().lifecycle(":providing " + dependency.getDepString()); | ||||
| 
 | ||||
| 		MappingsProvider mappingsProvider = getDependencyManager().getProvider(MappingsProvider.class); | ||||
| 		String verSuffix = ".mapped." + mappingsProvider.mappingsName + "." + mappingsProvider.mappingsVersion; | ||||
| 
 | ||||
| 		String outputName = input.getName().substring(0, input.getName().length() - 4) + verSuffix + ".jar";//TODO use the hash of the input file or something? | ||||
| 		String outputNamePrefix = input.getName().substring(0, input.getName().length() - 4) + verSuffix;//TODO use the hash of the input file or something? | ||||
| 		File modStore = extension.getRemappedModCache(); | ||||
| 		File output = new File(modStore, outputName); | ||||
| 		File output = new File(modStore, outputNamePrefix + ".jar"); | ||||
| 		if(output.exists()){ | ||||
| 			output.delete(); | ||||
| 		} | ||||
|  | @ -58,6 +64,20 @@ public class ModRemapperProvider extends DependencyProvider { | |||
| 		project.getDependencies().add("compile", project.getDependencies().module( | ||||
| 				dependency.getDepString() + verSuffix | ||||
| 		)); | ||||
| 
 | ||||
| 		postPopulationScheduler.accept(() -> { | ||||
| 			// Provide sources JAR, if present | ||||
| 			Optional<File> sourcesFile = dependency.resolveFile("sources"); | ||||
| 			if (sourcesFile.isPresent()) { | ||||
| 				project.getLogger().lifecycle(":providing " + dependency.getDepString() + " sources"); | ||||
| 
 | ||||
| 				try { | ||||
| 					SourceRemapper.remapSources(project, sourcesFile.get(), new File(modStore, outputNamePrefix + "-sources.jar"), true); | ||||
| 				} catch (Exception e) { | ||||
| 					e.printStackTrace(); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
|  |  | |||
|  | @ -24,20 +24,33 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.util; | ||||
| 
 | ||||
| import com.google.common.collect.ImmutableSet; | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
| import org.gradle.api.artifacts.Dependency; | ||||
| import org.gradle.api.artifacts.ResolvedArtifact; | ||||
| import org.gradle.api.artifacts.ResolvedDependency; | ||||
| import org.gradle.api.artifacts.query.ArtifactResolutionQuery; | ||||
| import org.gradle.api.artifacts.result.ArtifactResolutionResult; | ||||
| import org.gradle.api.artifacts.result.ArtifactResult; | ||||
| import org.gradle.api.artifacts.result.ComponentArtifactsResult; | ||||
| import org.gradle.api.artifacts.result.ResolvedArtifactResult; | ||||
| import org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier; | ||||
| import org.gradle.jvm.JvmLibrary; | ||||
| import org.gradle.language.base.artifact.SourcesArtifact; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.HashSet; | ||||
| import java.util.Optional; | ||||
| import java.util.Set; | ||||
| import java.util.function.Consumer; | ||||
| 
 | ||||
| public abstract class DependencyProvider { | ||||
| 
 | ||||
| 	private LoomDependencyManager dependencyManager; | ||||
| 
 | ||||
| 	public abstract void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension) throws Exception; | ||||
| 	public abstract void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception; | ||||
| 
 | ||||
| 	public abstract String getTargetConfig(); | ||||
| 
 | ||||
|  | @ -61,10 +74,12 @@ public abstract class DependencyProvider { | |||
| 	} | ||||
| 
 | ||||
| 	public static class DependencyInfo { | ||||
| 		final Project project; | ||||
| 		final Dependency dependency; | ||||
| 		final Configuration sourceConfiguration; | ||||
| 
 | ||||
| 		public DependencyInfo(Dependency dependency, Configuration sourceConfiguration) { | ||||
| 		public DependencyInfo(Project project, Dependency dependency, Configuration sourceConfiguration) { | ||||
| 			this.project = project; | ||||
| 			this.dependency = dependency; | ||||
| 			this.sourceConfiguration = sourceConfiguration; | ||||
| 		} | ||||
|  | @ -87,17 +102,68 @@ public abstract class DependencyProvider { | |||
| 			return sourceConfiguration; | ||||
| 		} | ||||
| 
 | ||||
| 		public Set<File> resolve(){ | ||||
| 		// TODO: Can this be done with stable APIs only? | ||||
| 		@SuppressWarnings("UnstableApiUsage") | ||||
| 		public Set<File> resolve(String classifier) { | ||||
| 			if (classifier.isEmpty()) { | ||||
| 				return sourceConfiguration.files(dependency); | ||||
| 			} else if ("sources".equals(classifier)) { | ||||
| 				for (ResolvedArtifact rd : sourceConfiguration.getResolvedConfiguration().getResolvedArtifacts()) { | ||||
| 					if (rd.getModuleVersion().getId().getGroup().equals(dependency.getGroup()) | ||||
| 							&& rd.getModuleVersion().getId().getName().equals(dependency.getName()) | ||||
| 							&& rd.getModuleVersion().getId().getVersion().equals(dependency.getVersion())) { | ||||
| 
 | ||||
| 						ImmutableSet.Builder<File> files = ImmutableSet.builder(); | ||||
| 
 | ||||
| 						ArtifactResolutionQuery query = project.getDependencies().createArtifactResolutionQuery(); | ||||
| 						query.forComponents(DefaultModuleComponentIdentifier.newId(rd.getModuleVersion().getId())); | ||||
| 						//noinspection unchecked | ||||
| 						query.withArtifacts(JvmLibrary.class, SourcesArtifact.class); | ||||
| 						for (ComponentArtifactsResult cresult : query.execute().getResolvedComponents()) { | ||||
| 							for (ArtifactResult result : cresult.getArtifacts(SourcesArtifact.class)) { | ||||
| 								if (result instanceof ResolvedArtifactResult) { | ||||
| 									files.add(((ResolvedArtifactResult) result).getFile()); | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 
 | ||||
| 		public File resolveFile(){ | ||||
| 			Set<File> files = resolve(); | ||||
| 			if(files.size() != 1){ | ||||
| 				throw new RuntimeException(dependency + " resolves to more than one file"); | ||||
| 						return files.build(); | ||||
| 					} | ||||
| 			File file = files.stream().findFirst().orElse(null); | ||||
| 			return file; | ||||
| 				} | ||||
| 
 | ||||
| 				return ImmutableSet.of(); | ||||
| 			} else { | ||||
| 				project.getLogger().warn("Unsupported classifier '" + classifier + "'"); | ||||
| 				return ImmutableSet.of(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		public Optional<File> resolveFile() { | ||||
| 			return resolveFile(""); | ||||
| 		} | ||||
| 
 | ||||
| 		public Optional<File> resolveFile(String classifier) { | ||||
| 			Set<File> files = resolve(classifier); | ||||
| 			if (files.isEmpty()) { | ||||
| 				return Optional.empty(); | ||||
| 			} else if (files.size() > 1) { | ||||
| 				StringBuilder builder = new StringBuilder(this.toString()); | ||||
| 				if (!classifier.isEmpty()) { | ||||
| 					builder.append(" [").append(classifier).append("]"); | ||||
| 				} | ||||
| 				builder.append(" resolves to more than one file:"); | ||||
| 				for (File f : files) { | ||||
| 					builder.append("\n\t-").append(f.getAbsolutePath()); | ||||
| 				} | ||||
| 				throw new RuntimeException(builder.toString()); | ||||
| 			} else { | ||||
| 				return files.stream().findFirst(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public String toString() { | ||||
| 			return getDepString(); | ||||
| 		} | ||||
| 
 | ||||
| 		public String getDepString(){ | ||||
|  |  | |||
|  | @ -61,6 +61,8 @@ public class LoomDependencyManager { | |||
| 	} | ||||
| 
 | ||||
| 	public void handleDependencies(Project project){ | ||||
| 		List<Runnable> afterTasks = new ArrayList<>(); | ||||
| 
 | ||||
| 		project.getLogger().lifecycle(":setting up loom dependencies"); | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		Set<String> targetConfigs = new LinkedHashSet<>(); | ||||
|  | @ -72,9 +74,9 @@ public class LoomDependencyManager { | |||
| 			configuration.getDependencies().forEach(dependency -> { | ||||
| 				for(DependencyProvider provider : dependencyProviderList){ | ||||
| 					if(provider.getTargetConfig().equals(config)){ | ||||
| 						DependencyProvider.DependencyInfo info = new DependencyProvider.DependencyInfo(dependency, configuration); | ||||
| 						DependencyProvider.DependencyInfo info = new DependencyProvider.DependencyInfo(project, dependency, configuration); | ||||
| 						try { | ||||
| 							provider.provide(info, project, extension); | ||||
| 							provider.provide(info, project, extension, afterTasks::add); | ||||
| 						} catch (Exception e) { | ||||
| 							throw new RuntimeException("Failed to provide", e); | ||||
| 						} | ||||
|  | @ -88,6 +90,10 @@ public class LoomDependencyManager { | |||
| 		} else { | ||||
| 			project.getLogger().warn("fabric-installer.json not found in classpath!"); | ||||
| 		} | ||||
| 
 | ||||
| 		for (Runnable runnable : afterTasks) { | ||||
| 			runnable.run(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static void handleInstallerJson(JsonObject jsonObject, Project project){ | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ import org.cadixdev.lorenz.io.TextMappingsReader; | |||
| import org.cadixdev.mercury.Mercury; | ||||
| import org.cadixdev.mercury.remapper.MercuryRemapper; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.internal.impldep.aQute.bnd.build.Run; | ||||
| import org.objectweb.asm.commons.Remapper; | ||||
| import org.zeroturnaround.zip.ZipUtil; | ||||
| 
 | ||||
|  | @ -104,10 +105,20 @@ public class SourceRemapper { | |||
| 			ZipUtil.unpack(source, srcPath.toFile()); | ||||
| 		} | ||||
| 
 | ||||
| 		if (!destination.isDirectory() && destination.exists()) { | ||||
| 			if (!destination.delete()) { | ||||
| 				throw new RuntimeException("Could not delete " + destination.getName() + "!"); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		StitchUtil.FileSystemDelegate dstFs = destination.isDirectory() ? null : StitchUtil.getJarFileSystem(destination, true); | ||||
| 		Path dstPath = dstFs != null ? dstFs.get().getPath("/") : destination.toPath(); | ||||
| 
 | ||||
| 		try { | ||||
| 			mercury.rewrite(srcPath, dstPath); | ||||
| 		} catch (Exception e) { | ||||
| 			project.getLogger().warn("Could not remap " + source.getName() + " fully!", e); | ||||
| 		} | ||||
| 
 | ||||
| 		if (dstFs != null) { | ||||
| 			dstFs.close(); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue