Add server only jar configuration option. (#574)
* Add server only option. * Fix crash. * Fix unpick jar task name. * Revert test memory change * Dont add client only libraries. * Fixes * Move option to the extension
This commit is contained in:
		
							parent
							
								
									d71af0cfd7
								
							
						
					
					
						commit
						e9d1f005d9
					
				
					 21 changed files with 551 additions and 117 deletions
				
			
		|  | @ -38,6 +38,7 @@ import net.fabricmc.loom.api.decompilers.DecompilerOptions; | |||
| import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; | ||||
| import net.fabricmc.loom.configuration.ide.RunConfigSettings; | ||||
| import net.fabricmc.loom.configuration.processors.JarProcessor; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; | ||||
| import net.fabricmc.loom.util.DeprecationHelper; | ||||
| 
 | ||||
| /** | ||||
|  | @ -138,4 +139,17 @@ public interface LoomGradleExtensionAPI { | |||
| 	 * @return the property controlling interface injection. | ||||
| 	 */ | ||||
| 	Property<Boolean> getEnableInterfaceInjection(); | ||||
| 
 | ||||
| 	@ApiStatus.Experimental | ||||
| 	Property<MinecraftJarConfiguration> getMinecraftJarConfiguration(); | ||||
| 
 | ||||
| 	@ApiStatus.Experimental | ||||
| 	default void serverOnlyMinecraftJar() { | ||||
| 		getMinecraftJarConfiguration().set(MinecraftJarConfiguration.SERVER_ONLY); | ||||
| 	} | ||||
| 
 | ||||
| 	@ApiStatus.Experimental | ||||
| 	default void splitMinecraftJar() { | ||||
| 		getMinecraftJarConfiguration().set(MinecraftJarConfiguration.SPLIT); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -42,18 +42,13 @@ import net.fabricmc.loom.build.mixin.KaptApInvoker; | |||
| import net.fabricmc.loom.build.mixin.ScalaApInvoker; | ||||
| import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor; | ||||
| import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerJarProcessor; | ||||
| import net.fabricmc.loom.configuration.decompile.MergedDecompileConfiguration; | ||||
| import net.fabricmc.loom.configuration.decompile.SplitDecompileConfiguration; | ||||
| import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; | ||||
| import net.fabricmc.loom.configuration.processors.JarProcessorManager; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.ProcessedNamedMinecraftProvider; | ||||
| import net.fabricmc.loom.extension.MixinExtension; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| 
 | ||||
|  | @ -190,11 +185,10 @@ public final class CompileConfiguration { | |||
| 	// This is not thread safe across projects synchronize it here just to be sure, might be possible to move this further down, but for now this will do. | ||||
| 	private static synchronized void setupMinecraft(Project project) throws Exception { | ||||
| 		final LoomGradleExtension extension = LoomGradleExtension.get(project); | ||||
| 
 | ||||
| 		boolean split = project.getProperties().get("fabric.loom.experimental.splitMcJars") != null; | ||||
| 		final MinecraftJarConfiguration jarConfiguration = extension.getMinecraftJarConfiguration().get(); | ||||
| 
 | ||||
| 		// Provide the vanilla mc jars -- TODO share across projects. | ||||
| 		final MinecraftProvider minecraftProvider = split ? new SplitMinecraftProvider(project) : new MergedMinecraftProvider(project); | ||||
| 		final MinecraftProvider minecraftProvider = jarConfiguration.getMinecraftProviderFunction().apply(project); | ||||
| 		extension.setMinecraftProvider(minecraftProvider); | ||||
| 		minecraftProvider.provide(); | ||||
| 
 | ||||
|  | @ -204,26 +198,14 @@ public final class CompileConfiguration { | |||
| 		mappingsProvider.applyToProject(project, mappingsDep); | ||||
| 
 | ||||
| 		// Provide the remapped mc jars | ||||
| 		final IntermediaryMinecraftProvider<?> intermediaryMinecraftProvider; | ||||
| 		NamedMinecraftProvider<?> namedMinecraftProvider; | ||||
| 
 | ||||
| 		if (split) { | ||||
| 			intermediaryMinecraftProvider = new IntermediaryMinecraftProvider.SplitImpl(project, (SplitMinecraftProvider) minecraftProvider); | ||||
| 			namedMinecraftProvider = new NamedMinecraftProvider.SplitImpl(project, (SplitMinecraftProvider) minecraftProvider); | ||||
| 		} else { | ||||
| 			intermediaryMinecraftProvider = new IntermediaryMinecraftProvider.MergedImpl(project, (MergedMinecraftProvider) minecraftProvider); | ||||
| 			namedMinecraftProvider = new NamedMinecraftProvider.MergedImpl(project, (MergedMinecraftProvider) minecraftProvider); | ||||
| 		} | ||||
| 		final IntermediaryMinecraftProvider<?> intermediaryMinecraftProvider = jarConfiguration.getIntermediaryMinecraftProviderBiFunction().apply(project, minecraftProvider); | ||||
| 		NamedMinecraftProvider<?> namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(project, minecraftProvider); | ||||
| 
 | ||||
| 		final JarProcessorManager jarProcessorManager = createJarProcessorManager(project); | ||||
| 
 | ||||
| 		if (jarProcessorManager.active()) { | ||||
| 			// Wrap the named MC provider for one that will provide the processed jars | ||||
| 			if (split) { | ||||
| 				namedMinecraftProvider = new ProcessedNamedMinecraftProvider.SplitImpl((NamedMinecraftProvider.SplitImpl) namedMinecraftProvider, jarProcessorManager); | ||||
| 			} else { | ||||
| 				namedMinecraftProvider = new ProcessedNamedMinecraftProvider.MergedImpl((NamedMinecraftProvider.MergedImpl) namedMinecraftProvider, jarProcessorManager); | ||||
| 			} | ||||
| 			namedMinecraftProvider = jarConfiguration.getProcessedNamedMinecraftProviderBiFunction().apply(namedMinecraftProvider, jarProcessorManager); | ||||
| 		} | ||||
| 
 | ||||
| 		extension.setIntermediaryMinecraftProvider(intermediaryMinecraftProvider); | ||||
|  | @ -289,13 +271,8 @@ public final class CompileConfiguration { | |||
| 	private static void configureDecompileTasks(Project project) { | ||||
| 		final LoomGradleExtension extension = LoomGradleExtension.get(project); | ||||
| 
 | ||||
| 		if (extension.getNamedMinecraftProvider() instanceof MappedMinecraftProvider.Merged mergedMappedMinecraftProvider) { | ||||
| 			new MergedDecompileConfiguration(project, mergedMappedMinecraftProvider).afterEvaluation(); | ||||
| 		} else if (extension.getNamedMinecraftProvider() instanceof MappedMinecraftProvider.Split splitMinecraftProvider) { | ||||
| 			new SplitDecompileConfiguration(project, splitMinecraftProvider).afterEvaluation(); | ||||
| 		} else { | ||||
| 			throw new UnsupportedOperationException(); | ||||
| 		} | ||||
| 		extension.getMinecraftJarConfiguration().get().getDecompileConfigurationBiFunction() | ||||
| 				.apply(project, extension.getNamedMinecraftProvider()).afterEvaluation(); | ||||
| 	} | ||||
| 
 | ||||
| 	private static void extendsFrom(String a, String b, Project project) { | ||||
|  |  | |||
|  | @ -0,0 +1,59 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2022 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.decompile; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.tasks.TaskProvider; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; | ||||
| import net.fabricmc.loom.task.UnpickJarTask; | ||||
| 
 | ||||
| public abstract class DecompileConfiguration<T extends MappedMinecraftProvider> { | ||||
| 	protected final Project project; | ||||
| 	protected final T minecraftProvider; | ||||
| 	protected final LoomGradleExtension extension; | ||||
| 	protected final MappingsProviderImpl mappingsProvider; | ||||
| 
 | ||||
| 	public DecompileConfiguration(Project project, T minecraftProvider) { | ||||
| 		this.project = project; | ||||
| 		this.minecraftProvider = minecraftProvider; | ||||
| 		this.extension = LoomGradleExtension.get(project); | ||||
| 		this.mappingsProvider = extension.getMappingsProvider(); | ||||
| 	} | ||||
| 
 | ||||
| 	public abstract void afterEvaluation(); | ||||
| 
 | ||||
| 	protected final TaskProvider<UnpickJarTask> createUnpickJarTask(String name, File inputJar, File outputJar) { | ||||
| 		return project.getTasks().register(name, UnpickJarTask.class, unpickJarTask -> { | ||||
| 			unpickJarTask.getUnpickDefinitions().set(mappingsProvider.getUnpickDefinitionsFile()); | ||||
| 			unpickJarTask.getInputJar().set(inputJar); | ||||
| 			unpickJarTask.getOutputJar().set(outputJar); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  | @ -1,7 +1,7 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2021 FabricMC | ||||
|  * Copyright (c) 2022 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 | ||||
|  | @ -25,40 +25,33 @@ | |||
| package net.fabricmc.loom.configuration.decompile; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.nio.file.Path; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.gradle.api.Project; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; | ||||
| import net.fabricmc.loom.task.GenerateSourcesTask; | ||||
| import net.fabricmc.loom.task.UnpickJarTask; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| 
 | ||||
| public final class MergedDecompileConfiguration { | ||||
| 	private final Project project; | ||||
| 	private final MappedMinecraftProvider.Merged minecraftProvider; | ||||
| 	private final LoomGradleExtension extension; | ||||
| 	private final MappingsProviderImpl mappingsProvider; | ||||
| 
 | ||||
| 	public MergedDecompileConfiguration(Project project, MappedMinecraftProvider.Merged minecraftProvider) { | ||||
| 		this.project = project; | ||||
| 		this.minecraftProvider = minecraftProvider; | ||||
| 		this.extension = LoomGradleExtension.get(project); | ||||
| 		this.mappingsProvider = extension.getMappingsProvider(); | ||||
| public class SingleJarDecompileConfiguration extends DecompileConfiguration<MappedMinecraftProvider> { | ||||
| 	public SingleJarDecompileConfiguration(Project project, MappedMinecraftProvider minecraftProvider) { | ||||
| 		super(project, minecraftProvider); | ||||
| 	} | ||||
| 
 | ||||
| 	public void afterEvaluation() { | ||||
| 		File mappedJar = minecraftProvider.getMergedJar().toFile(); | ||||
| 	@Override | ||||
| 	public final void afterEvaluation() { | ||||
| 		List<Path> minecraftJars = minecraftProvider.getMinecraftJars(); | ||||
| 		assert minecraftJars.size() == 1; | ||||
| 
 | ||||
| 		final File namedJar = minecraftJars.get(0).toFile(); | ||||
| 
 | ||||
| 		File mappedJar = namedJar; | ||||
| 
 | ||||
| 		if (mappingsProvider.hasUnpickDefinitions()) { | ||||
| 			File outputJar = new File(extension.getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-unpicked.jar"); | ||||
| 
 | ||||
| 			project.getTasks().register("unpickJar", UnpickJarTask.class, unpickJarTask -> { | ||||
| 				unpickJarTask.getUnpickDefinitions().set(mappingsProvider.getUnpickDefinitionsFile()); | ||||
| 				unpickJarTask.getInputJar().set(minecraftProvider.getMergedJar().toFile()); | ||||
| 				unpickJarTask.getOutputJar().set(outputJar); | ||||
| 			}); | ||||
| 			createUnpickJarTask("unpickJar", namedJar, outputJar); | ||||
| 
 | ||||
| 			mappedJar = outputJar; | ||||
| 		} | ||||
|  | @ -71,7 +64,7 @@ public final class MergedDecompileConfiguration { | |||
| 			// Decompiler will be passed to the constructor of GenerateSourcesTask | ||||
| 			project.getTasks().register(taskName, GenerateSourcesTask.class, options).configure(task -> { | ||||
| 				task.getInputJar().set(inputJar); | ||||
| 				task.getRuntimeJar().set(minecraftProvider.getMergedJar().toFile()); | ||||
| 				task.getRuntimeJar().set(namedJar); | ||||
| 
 | ||||
| 				task.dependsOn(project.getTasks().named("validateAccessWidener")); | ||||
| 				task.setDescription("Decompile minecraft using %s.".formatted(decompilerName)); | ||||
|  | @ -31,26 +31,17 @@ import org.gradle.api.Project; | |||
| import org.gradle.api.Task; | ||||
| import org.gradle.api.tasks.TaskProvider; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; | ||||
| import net.fabricmc.loom.task.GenerateSourcesTask; | ||||
| import net.fabricmc.loom.task.UnpickJarTask; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| 
 | ||||
| public final class SplitDecompileConfiguration { | ||||
| 	private final Project project; | ||||
| 	private final MappedMinecraftProvider.Split minecraftProvider; | ||||
| 	private final LoomGradleExtension extension; | ||||
| 	private final MappingsProviderImpl mappingsProvider; | ||||
| 
 | ||||
| public final class SplitDecompileConfiguration extends DecompileConfiguration<MappedMinecraftProvider.Split> { | ||||
| 	public SplitDecompileConfiguration(Project project, MappedMinecraftProvider.Split minecraftProvider) { | ||||
| 		this.project = project; | ||||
| 		this.minecraftProvider = minecraftProvider; | ||||
| 		this.extension = LoomGradleExtension.get(project); | ||||
| 		this.mappingsProvider = extension.getMappingsProvider(); | ||||
| 		super(project, minecraftProvider); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void afterEvaluation() { | ||||
| 		File commonJarToDecompile = minecraftProvider.getCommonJar().toFile(); | ||||
| 		File clientOnlyJarToDecompile = minecraftProvider.getClientOnlyJar().toFile(); | ||||
|  | @ -62,8 +53,8 @@ public final class SplitDecompileConfiguration { | |||
| 			commonJarToDecompile = new File(extension.getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-common-unpicked.jar"); | ||||
| 			clientOnlyJarToDecompile = new File(extension.getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-clientonly-unpicked.jar"); | ||||
| 
 | ||||
| 			unpickCommonJar = createUnpickJarTask("Common", minecraftProvider.getCommonJar().toFile(), commonJarToDecompile); | ||||
| 			unpickClientOnlyJar = createUnpickJarTask("ClientOnly", minecraftProvider.getClientOnlyJar().toFile(), clientOnlyJarToDecompile); | ||||
| 			unpickCommonJar = createUnpickJarTask("unpickCommonJar", minecraftProvider.getCommonJar().toFile(), commonJarToDecompile); | ||||
| 			unpickClientOnlyJar = createUnpickJarTask("unpickClientOnlyJar", minecraftProvider.getClientOnlyJar().toFile(), clientOnlyJarToDecompile); | ||||
| 		} | ||||
| 
 | ||||
| 		// Need to re-declare them as final to access them from the lambada | ||||
|  | @ -102,18 +93,10 @@ public final class SplitDecompileConfiguration { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	private TaskProvider<UnpickJarTask> createUnpickJarTask(String name, File inputJar, File outputJar) { | ||||
| 		return project.getTasks().register("unpick%sJar".formatted(name), UnpickJarTask.class, unpickJarTask -> { | ||||
| 			unpickJarTask.getUnpickDefinitions().set(mappingsProvider.getUnpickDefinitionsFile()); | ||||
| 			unpickJarTask.getInputJar().set(inputJar); | ||||
| 			unpickJarTask.getOutputJar().set(outputJar); | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	private TaskProvider<Task> createDecompileTasks(String name, Action<GenerateSourcesTask> configureAction) { | ||||
| 		extension.getDecompilerOptions().forEach(options -> { | ||||
| 			final String decompilerName = options.getName().substring(0, 1).toUpperCase() + options.getName().substring(1); | ||||
| 			final String taskName = "gen%sSourcesWith%s".formatted(decompilerName, options.getName()); | ||||
| 			final String taskName = "gen%sSourcesWith%s".formatted(name, decompilerName); | ||||
| 
 | ||||
| 			project.getTasks().register(taskName, GenerateSourcesTask.class, options).configure(task -> { | ||||
| 				configureAction.execute(task); | ||||
|  |  | |||
|  | @ -30,10 +30,12 @@ import org.gradle.api.Project; | |||
| import org.gradle.api.tasks.TaskProvider; | ||||
| import org.gradle.execution.taskgraph.TaskExecutionGraphInternal; | ||||
| 
 | ||||
| import net.fabricmc.loom.task.LoomTasks; | ||||
| 
 | ||||
| public class IdeaConfiguration { | ||||
| 	public static void setup(Project project) { | ||||
| 		TaskProvider<IdeaSyncTask> ideaSyncTask = project.getTasks().register("ideaSyncTask", IdeaSyncTask.class, ideaSyncTask1 -> { | ||||
| 			ideaSyncTask1.dependsOn(project.getTasks().named("configureLaunch")); | ||||
| 		TaskProvider<IdeaSyncTask> ideaSyncTask = project.getTasks().register("ideaSyncTask", IdeaSyncTask.class, task -> { | ||||
| 			task.dependsOn(LoomTasks.getIDELaunchConfigureTaskName(project)); | ||||
| 		}); | ||||
| 
 | ||||
| 		if (!IdeaUtils.isIdeaSync()) { | ||||
|  |  | |||
|  | @ -298,7 +298,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { | |||
| 
 | ||||
| 	private void suggestFieldNames(MergedMinecraftProvider minecraftProvider, Path oldMappings, Path newMappings) { | ||||
| 		Command command = new CommandProposeFieldNames(); | ||||
| 		runCommand(command, minecraftProvider.getMergedJar().getAbsolutePath(), | ||||
| 		runCommand(command, minecraftProvider.getMergedJar().toFile().getAbsolutePath(), | ||||
| 						oldMappings.toAbsolutePath().toString(), | ||||
| 						newMappings.toAbsolutePath().toString()); | ||||
| 	} | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ package net.fabricmc.loom.configuration.providers.minecraft; | |||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
|  | @ -36,7 +37,7 @@ import net.fabricmc.loom.util.HashedDownloadUtil; | |||
| import net.fabricmc.stitch.merge.JarMerger; | ||||
| 
 | ||||
| public final class MergedMinecraftProvider extends MinecraftProvider { | ||||
| 	private File minecraftMergedJar; | ||||
| 	private Path minecraftMergedJar; | ||||
| 
 | ||||
| 	public MergedMinecraftProvider(Project project) { | ||||
| 		super(project); | ||||
|  | @ -45,25 +46,25 @@ public final class MergedMinecraftProvider extends MinecraftProvider { | |||
| 	@Override | ||||
| 	protected void initFiles() { | ||||
| 		super.initFiles(); | ||||
| 		minecraftMergedJar = file("minecraft-merged.jar"); | ||||
| 		minecraftMergedJar = path("minecraft-merged.jar"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public List<Path> getMinecraftJars() { | ||||
| 		return List.of(minecraftMergedJar.toPath()); | ||||
| 		return List.of(minecraftMergedJar); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void provide() throws Exception { | ||||
| 		super.provide(); | ||||
| 
 | ||||
| 		if (!minecraftMergedJar.exists() || isRefreshDeps()) { | ||||
| 		if (!Files.exists(minecraftMergedJar) || isRefreshDeps()) { | ||||
| 			try { | ||||
| 				mergeJars(); | ||||
| 			} catch (Throwable e) { | ||||
| 				HashedDownloadUtil.delete(getMinecraftClientJar()); | ||||
| 				HashedDownloadUtil.delete(getMinecraftServerJar()); | ||||
| 				minecraftMergedJar.delete(); | ||||
| 				Files.deleteIfExists(minecraftMergedJar); | ||||
| 
 | ||||
| 				getProject().getLogger().error("Could not merge JARs! Deleting source JARs - please re-run the command and move on.", e); | ||||
| 				throw e; | ||||
|  | @ -83,13 +84,13 @@ public final class MergedMinecraftProvider extends MinecraftProvider { | |||
| 
 | ||||
| 		Objects.requireNonNull(jarToMerge, "Cannot merge null input jar?"); | ||||
| 
 | ||||
| 		try (JarMerger jarMerger = new JarMerger(getMinecraftClientJar(), jarToMerge, minecraftMergedJar)) { | ||||
| 		try (JarMerger jarMerger = new JarMerger(getMinecraftClientJar(), jarToMerge, minecraftMergedJar.toFile())) { | ||||
| 			jarMerger.enableSyntheticParamsOffset(); | ||||
| 			jarMerger.merge(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public File getMergedJar() { | ||||
| 	public Path getMergedJar() { | ||||
| 		return minecraftMergedJar; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,115 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2022 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.providers.minecraft; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.function.BiFunction; | ||||
| import java.util.function.Function; | ||||
| 
 | ||||
| import org.gradle.api.Project; | ||||
| 
 | ||||
| import net.fabricmc.loom.configuration.decompile.DecompileConfiguration; | ||||
| import net.fabricmc.loom.configuration.decompile.SingleJarDecompileConfiguration; | ||||
| import net.fabricmc.loom.configuration.decompile.SplitDecompileConfiguration; | ||||
| import net.fabricmc.loom.configuration.processors.JarProcessorManager; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.mapped.ProcessedNamedMinecraftProvider; | ||||
| 
 | ||||
| public enum MinecraftJarConfiguration { | ||||
| 	MERGED( | ||||
| 		MergedMinecraftProvider::new, | ||||
| 		IntermediaryMinecraftProvider.MergedImpl::new, | ||||
| 		NamedMinecraftProvider.MergedImpl::new, | ||||
| 		ProcessedNamedMinecraftProvider.MergedImpl::new, | ||||
| 		SingleJarDecompileConfiguration::new, | ||||
| 		List.of("client", "server") | ||||
| 	), | ||||
| 	SERVER_ONLY( | ||||
| 		ServerOnlyMinecraftProvider::new, | ||||
| 		IntermediaryMinecraftProvider.ServerOnlyImpl::new, | ||||
| 		NamedMinecraftProvider.ServerOnlyImpl::new, | ||||
| 		ProcessedNamedMinecraftProvider.ServerOnlyImpl::new, | ||||
| 		SingleJarDecompileConfiguration::new, | ||||
| 		List.of("server") | ||||
| 	), | ||||
| 	SPLIT( | ||||
| 		SplitMinecraftProvider::new, | ||||
| 		IntermediaryMinecraftProvider.SplitImpl::new, | ||||
| 		NamedMinecraftProvider.SplitImpl::new, | ||||
| 		ProcessedNamedMinecraftProvider.SplitImpl::new, | ||||
| 		SplitDecompileConfiguration::new, | ||||
| 		List.of("client", "server") | ||||
| 	); | ||||
| 
 | ||||
| 	private final Function<Project, MinecraftProvider> minecraftProviderFunction; | ||||
| 	private final BiFunction<Project, MinecraftProvider, IntermediaryMinecraftProvider<?>> intermediaryMinecraftProviderBiFunction; | ||||
| 	private final BiFunction<Project, MinecraftProvider, NamedMinecraftProvider<?>> namedMinecraftProviderBiFunction; | ||||
| 	private final BiFunction<NamedMinecraftProvider<?>, JarProcessorManager, ProcessedNamedMinecraftProvider<?, ?>> processedNamedMinecraftProviderBiFunction; | ||||
| 	private final BiFunction<Project, MappedMinecraftProvider, DecompileConfiguration<?>> decompileConfigurationBiFunction; | ||||
| 	private final List<String> supportedEnvironments; | ||||
| 
 | ||||
| 	@SuppressWarnings("unchecked") // Just a bit of a generic mess :) | ||||
| 	<M extends MinecraftProvider, P extends NamedMinecraftProvider<M>, Q extends MappedMinecraftProvider> MinecraftJarConfiguration( | ||||
| 			Function<Project, M> minecraftProviderFunction, | ||||
| 			BiFunction<Project, M, IntermediaryMinecraftProvider<M>> intermediaryMinecraftProviderBiFunction, | ||||
| 			BiFunction<Project, M, P> namedMinecraftProviderBiFunction, | ||||
| 			BiFunction<P, JarProcessorManager, ProcessedNamedMinecraftProvider<M, P>> processedNamedMinecraftProviderBiFunction, | ||||
| 			BiFunction<Project, Q, DecompileConfiguration<?>> decompileConfigurationBiFunction, | ||||
| 			List<String> supportedEnvironments | ||||
| 	) { | ||||
| 		this.minecraftProviderFunction = (Function<Project, MinecraftProvider>) minecraftProviderFunction; | ||||
| 		this.intermediaryMinecraftProviderBiFunction = (BiFunction<Project, MinecraftProvider, IntermediaryMinecraftProvider<?>>) (Object) intermediaryMinecraftProviderBiFunction; | ||||
| 		this.namedMinecraftProviderBiFunction = (BiFunction<Project, MinecraftProvider, NamedMinecraftProvider<?>>) namedMinecraftProviderBiFunction; | ||||
| 		this.processedNamedMinecraftProviderBiFunction = (BiFunction<NamedMinecraftProvider<?>, JarProcessorManager, ProcessedNamedMinecraftProvider<?, ?>>) (Object) processedNamedMinecraftProviderBiFunction; | ||||
| 		this.decompileConfigurationBiFunction = (BiFunction<Project, MappedMinecraftProvider, DecompileConfiguration<?>>) decompileConfigurationBiFunction; | ||||
| 		this.supportedEnvironments = supportedEnvironments; | ||||
| 	} | ||||
| 
 | ||||
| 	public Function<Project, MinecraftProvider> getMinecraftProviderFunction() { | ||||
| 		return minecraftProviderFunction; | ||||
| 	} | ||||
| 
 | ||||
| 	public BiFunction<Project, MinecraftProvider, IntermediaryMinecraftProvider<?>> getIntermediaryMinecraftProviderBiFunction() { | ||||
| 		return intermediaryMinecraftProviderBiFunction; | ||||
| 	} | ||||
| 
 | ||||
| 	public BiFunction<Project, MinecraftProvider, NamedMinecraftProvider<?>> getNamedMinecraftProviderBiFunction() { | ||||
| 		return namedMinecraftProviderBiFunction; | ||||
| 	} | ||||
| 
 | ||||
| 	public BiFunction<NamedMinecraftProvider<?>, JarProcessorManager, ProcessedNamedMinecraftProvider<?, ?>> getProcessedNamedMinecraftProviderBiFunction() { | ||||
| 		return processedNamedMinecraftProviderBiFunction; | ||||
| 	} | ||||
| 
 | ||||
| 	public BiFunction<Project, MappedMinecraftProvider, DecompileConfiguration<?>> getDecompileConfigurationBiFunction() { | ||||
| 		return decompileConfigurationBiFunction; | ||||
| 	} | ||||
| 
 | ||||
| 	public List<String> getSupportedEnvironments() { | ||||
| 		return supportedEnvironments; | ||||
| 	} | ||||
| } | ||||
|  | @ -30,6 +30,7 @@ import java.util.regex.Pattern; | |||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.artifacts.ExternalModuleDependency; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.configuration.providers.BundleMetadata; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| 
 | ||||
|  | @ -37,8 +38,9 @@ public class MinecraftLibraryProvider { | |||
| 	private static final Pattern NATIVES_PATTERN = Pattern.compile("^(?<group>.*)/(.*?)/(?<version>.*)/((?<name>.*?)-([0-9].*?)-)(?<classifier>.*).jar$"); | ||||
| 
 | ||||
| 	public void provide(MinecraftProvider minecraftProvider, Project project) { | ||||
| 		MinecraftVersionMeta versionInfo = minecraftProvider.getVersionInfo(); | ||||
| 		BundleMetadata serverBundleMetadata = minecraftProvider.getServerBundleMetadata(); | ||||
| 		final MinecraftJarConfiguration jarConfiguration = LoomGradleExtension.get(project).getMinecraftJarConfiguration().get(); | ||||
| 		final MinecraftVersionMeta versionInfo = minecraftProvider.getVersionInfo(); | ||||
| 		final BundleMetadata serverBundleMetadata = minecraftProvider.getServerBundleMetadata(); | ||||
| 
 | ||||
| 		final boolean overrideLWJGL = LWJGLVersionOverride.overrideByDefault() || LWJGLVersionOverride.forceOverride(project) || Boolean.getBoolean("loom.test.lwjgloverride"); | ||||
| 
 | ||||
|  | @ -54,7 +56,7 @@ public class MinecraftLibraryProvider { | |||
| 			if (library.isValidForOS() && !library.hasNatives() && library.artifact() != null) { | ||||
| 				if (serverBundleMetadata != null && isLibraryInBundle(serverBundleMetadata, library)) { | ||||
| 					project.getDependencies().add(Constants.Configurations.MINECRAFT_SERVER_DEPENDENCIES, library.name()); | ||||
| 				} else { | ||||
| 				} else if (jarConfiguration.getSupportedEnvironments().contains("client")) { | ||||
| 					// Client only library, or legacy version | ||||
| 					project.getDependencies().add(Constants.Configurations.MINECRAFT_DEPENDENCIES, library.name()); | ||||
| 				} | ||||
|  |  | |||
|  | @ -264,6 +264,10 @@ public abstract class MinecraftProvider { | |||
| 		return new File(workingDir(), path); | ||||
| 	} | ||||
| 
 | ||||
| 	public Path path(String path) { | ||||
| 		return file(path).toPath(); | ||||
| 	} | ||||
| 
 | ||||
| 	public File getMinecraftClientJar() { | ||||
| 		return minecraftClientJar; | ||||
| 	} | ||||
|  | @ -275,7 +279,6 @@ public abstract class MinecraftProvider { | |||
| 	} | ||||
| 
 | ||||
| 	// This may be the server bundler jar on newer versions prob not what you want. | ||||
| 	@Deprecated | ||||
| 	public File getMinecraftServerJar() { | ||||
| 		return minecraftServerJar; | ||||
| 	} | ||||
|  |  | |||
|  | @ -0,0 +1,102 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2022 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.providers.minecraft; | ||||
| 
 | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.gradle.api.Project; | ||||
| 
 | ||||
| import net.fabricmc.loom.configuration.providers.BundleMetadata; | ||||
| import net.fabricmc.tinyremapper.NonClassCopyMode; | ||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; | ||||
| import net.fabricmc.tinyremapper.TinyRemapper; | ||||
| 
 | ||||
| public final class ServerOnlyMinecraftProvider extends MinecraftProvider { | ||||
| 	private Path minecraftServerOnlyJar; | ||||
| 
 | ||||
| 	public ServerOnlyMinecraftProvider(Project project) { | ||||
| 		super(project); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void initFiles() { | ||||
| 		super.initFiles(); | ||||
| 
 | ||||
| 		minecraftServerOnlyJar = path("minecraft-server-only.jar"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public List<Path> getMinecraftJars() { | ||||
| 		return List.of(minecraftServerOnlyJar); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void provide() throws Exception { | ||||
| 		super.provide(); | ||||
| 
 | ||||
| 		boolean requiresRefresh = isRefreshDeps() || Files.notExists(minecraftServerOnlyJar); | ||||
| 
 | ||||
| 		if (!requiresRefresh) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		BundleMetadata serverBundleMetadata = getServerBundleMetadata(); | ||||
| 
 | ||||
| 		if (serverBundleMetadata == null) { | ||||
| 			throw new UnsupportedOperationException("Only Minecraft versions using a bundled server jar support server only configuration, please use a merged jar setup for this version of minecraft"); | ||||
| 		} | ||||
| 
 | ||||
| 		extractBundledServerJar(); | ||||
| 		final Path serverJar = getMinecraftExtractedServerJar().toPath(); | ||||
| 
 | ||||
| 		TinyRemapper remapper = null; | ||||
| 
 | ||||
| 		try { | ||||
| 			remapper = TinyRemapper.newRemapper().build(); | ||||
| 
 | ||||
| 			Files.deleteIfExists(minecraftServerOnlyJar); | ||||
| 
 | ||||
| 			// Pass through tiny remapper to fix the meta-inf | ||||
| 			try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(minecraftServerOnlyJar).build()) { | ||||
| 				outputConsumer.addNonClassFiles(serverJar, NonClassCopyMode.FIX_META_INF, remapper); | ||||
| 				remapper.readInputs(serverJar); | ||||
| 				remapper.apply(outputConsumer); | ||||
| 			} | ||||
| 		} catch (Exception e) { | ||||
| 			Files.deleteIfExists(minecraftServerOnlyJar); | ||||
| 			throw new RuntimeException("Failed to process server only jar", e); | ||||
| 		} finally { | ||||
| 			if (remapper != null) { | ||||
| 				remapper.finish(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public Path getMinecraftServerOnlyJar() { | ||||
| 		return minecraftServerOnlyJar; | ||||
| 	} | ||||
| } | ||||
|  | @ -24,7 +24,6 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.configuration.providers.minecraft; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.List; | ||||
|  | @ -34,8 +33,8 @@ import org.gradle.api.Project; | |||
| import net.fabricmc.loom.configuration.providers.BundleMetadata; | ||||
| 
 | ||||
| public final class SplitMinecraftProvider extends MinecraftProvider { | ||||
| 	private File minecraftClientOnlyJar; | ||||
| 	private File minecraftCommonJar; | ||||
| 	private Path minecraftClientOnlyJar; | ||||
| 	private Path minecraftCommonJar; | ||||
| 
 | ||||
| 	public SplitMinecraftProvider(Project project) { | ||||
| 		super(project); | ||||
|  | @ -45,20 +44,20 @@ public final class SplitMinecraftProvider extends MinecraftProvider { | |||
| 	protected void initFiles() { | ||||
| 		super.initFiles(); | ||||
| 
 | ||||
| 		minecraftClientOnlyJar = file("minecraft-client-only.jar"); | ||||
| 		minecraftCommonJar = file("minecraft-common.jar"); | ||||
| 		minecraftClientOnlyJar = path("minecraft-client-only.jar"); | ||||
| 		minecraftCommonJar = path("minecraft-common.jar"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public List<Path> getMinecraftJars() { | ||||
| 		return List.of(minecraftClientOnlyJar.toPath(), minecraftCommonJar.toPath()); | ||||
| 		return List.of(minecraftClientOnlyJar, minecraftCommonJar); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void provide() throws Exception { | ||||
| 		super.provide(); | ||||
| 
 | ||||
| 		boolean requiresRefresh = isRefreshDeps() || !minecraftClientOnlyJar.exists() || !minecraftCommonJar.exists(); | ||||
| 		boolean requiresRefresh = isRefreshDeps() || Files.notExists(minecraftClientOnlyJar) || Files.notExists(minecraftCommonJar); | ||||
| 
 | ||||
| 		if (!requiresRefresh) { | ||||
| 			return; | ||||
|  | @ -80,20 +79,20 @@ public final class SplitMinecraftProvider extends MinecraftProvider { | |||
| 			jarSplitter.sharedEntry("version.json"); | ||||
| 			jarSplitter.forcedClientEntry("assets/.mcassetsroot"); | ||||
| 
 | ||||
| 			jarSplitter.split(minecraftClientOnlyJar.toPath(), minecraftCommonJar.toPath()); | ||||
| 			jarSplitter.split(minecraftClientOnlyJar, minecraftCommonJar); | ||||
| 		} catch (Exception e) { | ||||
| 			Files.deleteIfExists(minecraftClientOnlyJar.toPath()); | ||||
| 			Files.deleteIfExists(minecraftCommonJar.toPath()); | ||||
| 			Files.deleteIfExists(minecraftClientOnlyJar); | ||||
| 			Files.deleteIfExists(minecraftCommonJar); | ||||
| 
 | ||||
| 			throw new RuntimeException("Failed to split minecraft", e); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public File getMinecraftClientOnlyJar() { | ||||
| 	public Path getMinecraftClientOnlyJar() { | ||||
| 		return minecraftClientOnlyJar; | ||||
| 	} | ||||
| 
 | ||||
| 	public File getMinecraftCommonJar() { | ||||
| 	public Path getMinecraftCommonJar() { | ||||
| 		return minecraftCommonJar; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -32,11 +32,12 @@ import org.gradle.api.Project; | |||
| import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.ServerOnlyMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; | ||||
| import net.fabricmc.loom.util.SidedClassVisitor; | ||||
| import net.fabricmc.tinyremapper.TinyRemapper; | ||||
| 
 | ||||
| public abstract sealed class IntermediaryMinecraftProvider<M extends MinecraftProvider> extends AbstractMappedMinecraftProvider<M> permits IntermediaryMinecraftProvider.SplitImpl, IntermediaryMinecraftProvider.MergedImpl { | ||||
| public abstract sealed class IntermediaryMinecraftProvider<M extends MinecraftProvider> extends AbstractMappedMinecraftProvider<M> permits IntermediaryMinecraftProvider.MergedImpl, IntermediaryMinecraftProvider.ServerOnlyImpl, IntermediaryMinecraftProvider.SplitImpl { | ||||
| 	public IntermediaryMinecraftProvider(Project project, M minecraftProvider) { | ||||
| 		super(project, minecraftProvider); | ||||
| 	} | ||||
|  | @ -59,7 +60,7 @@ public abstract sealed class IntermediaryMinecraftProvider<M extends MinecraftPr | |||
| 		@Override | ||||
| 		public List<RemappedJars> getRemappedJars() { | ||||
| 			return List.of( | ||||
| 				new RemappedJars(minecraftProvider.getMergedJar().toPath(), getMergedJar(), MappingsNamespace.OFFICIAL) | ||||
| 				new RemappedJars(minecraftProvider.getMergedJar(), getMergedJar(), MappingsNamespace.OFFICIAL) | ||||
| 			); | ||||
| 		} | ||||
| 	} | ||||
|  | @ -72,8 +73,8 @@ public abstract sealed class IntermediaryMinecraftProvider<M extends MinecraftPr | |||
| 		@Override | ||||
| 		public List<RemappedJars> getRemappedJars() { | ||||
| 			return List.of( | ||||
| 				new RemappedJars(minecraftProvider.getMinecraftCommonJar().toPath(), getCommonJar(), MappingsNamespace.OFFICIAL), | ||||
| 				new RemappedJars(minecraftProvider.getMinecraftClientOnlyJar().toPath(), getClientOnlyJar(), MappingsNamespace.OFFICIAL, minecraftProvider.getMinecraftCommonJar().toPath()) | ||||
| 				new RemappedJars(minecraftProvider.getMinecraftCommonJar(), getCommonJar(), MappingsNamespace.OFFICIAL), | ||||
| 				new RemappedJars(minecraftProvider.getMinecraftClientOnlyJar(), getClientOnlyJar(), MappingsNamespace.OFFICIAL, minecraftProvider.getMinecraftCommonJar()) | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -84,4 +85,17 @@ public abstract sealed class IntermediaryMinecraftProvider<M extends MinecraftPr | |||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static final class ServerOnlyImpl extends IntermediaryMinecraftProvider<ServerOnlyMinecraftProvider> implements ServerOnly { | ||||
| 		public ServerOnlyImpl(Project project, ServerOnlyMinecraftProvider minecraftProvider) { | ||||
| 			super(project, minecraftProvider); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public List<RemappedJars> getRemappedJars() { | ||||
| 			return List.of( | ||||
| 				new RemappedJars(minecraftProvider.getMinecraftServerOnlyJar(), getServerOnlyJar(), MappingsNamespace.OFFICIAL) | ||||
| 			); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -64,4 +64,17 @@ public interface MappedMinecraftProvider { | |||
| 			return List.of(getCommonJar(), getClientOnlyJar()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	interface ServerOnly extends ProviderImpl { | ||||
| 		String SERVER_ONLY = "serverOnly"; | ||||
| 
 | ||||
| 		default Path getServerOnlyJar() { | ||||
| 			return getJar(SERVER_ONLY); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		default List<Path> getMinecraftJars() { | ||||
| 			return List.of(getServerOnlyJar()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -33,6 +33,7 @@ import org.gradle.api.Project; | |||
| import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.ServerOnlyMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| import net.fabricmc.loom.util.SidedClassVisitor; | ||||
|  | @ -61,7 +62,7 @@ public abstract class NamedMinecraftProvider<M extends MinecraftProvider> extend | |||
| 		@Override | ||||
| 		public List<RemappedJars> getRemappedJars() { | ||||
| 			return List.of( | ||||
| 					new RemappedJars(minecraftProvider.getMergedJar().toPath(), getMergedJar(), MappingsNamespace.OFFICIAL) | ||||
| 					new RemappedJars(minecraftProvider.getMergedJar(), getMergedJar(), MappingsNamespace.OFFICIAL) | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -79,8 +80,8 @@ public abstract class NamedMinecraftProvider<M extends MinecraftProvider> extend | |||
| 		@Override | ||||
| 		public List<RemappedJars> getRemappedJars() { | ||||
| 			return List.of( | ||||
| 					new RemappedJars(minecraftProvider.getMinecraftCommonJar().toPath(), getCommonJar(), MappingsNamespace.OFFICIAL), | ||||
| 					new RemappedJars(minecraftProvider.getMinecraftClientOnlyJar().toPath(), getClientOnlyJar(), MappingsNamespace.OFFICIAL, minecraftProvider.getMinecraftCommonJar().toPath()) | ||||
| 					new RemappedJars(minecraftProvider.getMinecraftCommonJar(), getCommonJar(), MappingsNamespace.OFFICIAL), | ||||
| 					new RemappedJars(minecraftProvider.getMinecraftClientOnlyJar(), getClientOnlyJar(), MappingsNamespace.OFFICIAL, minecraftProvider.getMinecraftCommonJar()) | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -97,4 +98,22 @@ public abstract class NamedMinecraftProvider<M extends MinecraftProvider> extend | |||
| 			consumer.accept(Constants.Configurations.MINECRAFT_NAMED, CLIENT_ONLY); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static final class ServerOnlyImpl extends NamedMinecraftProvider<ServerOnlyMinecraftProvider> implements ServerOnly { | ||||
| 		public ServerOnlyImpl(Project project, ServerOnlyMinecraftProvider minecraftProvider) { | ||||
| 			super(project, minecraftProvider); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public List<RemappedJars> getRemappedJars() { | ||||
| 			return List.of( | ||||
| 				new RemappedJars(minecraftProvider.getMinecraftServerOnlyJar(), getServerOnlyJar(), MappingsNamespace.OFFICIAL) | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		protected void applyDependencies(BiConsumer<String, String> consumer) { | ||||
| 			consumer.accept(Constants.Configurations.MINECRAFT_NAMED, SERVER_ONLY); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ import net.fabricmc.loom.LoomGradlePlugin; | |||
| import net.fabricmc.loom.configuration.processors.JarProcessorManager; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.ServerOnlyMinecraftProvider; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider; | ||||
| 
 | ||||
| public abstract class ProcessedNamedMinecraftProvider<M extends MinecraftProvider, P extends NamedMinecraftProvider<M>> extends NamedMinecraftProvider<M> { | ||||
|  | @ -154,4 +155,15 @@ public abstract class ProcessedNamedMinecraftProvider<M extends MinecraftProvide | |||
| 			return getProcessedPath(getParentMinecraftProvider().getClientOnlyJar()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static final class ServerOnlyImpl extends ProcessedNamedMinecraftProvider<ServerOnlyMinecraftProvider, NamedMinecraftProvider.ServerOnlyImpl> implements ServerOnly { | ||||
| 		public ServerOnlyImpl(NamedMinecraftProvider.ServerOnlyImpl parentMinecraftProvide, JarProcessorManager jarProcessorManager) { | ||||
| 			super(parentMinecraftProvide, jarProcessorManager); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public Path getServerOnlyJar() { | ||||
| 			return getProcessedPath(getParentMinecraftProvider().getServerOnlyJar()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext; | |||
| import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; | ||||
| import net.fabricmc.loom.util.DeprecationHelper; | ||||
| 
 | ||||
| /** | ||||
|  | @ -62,6 +63,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA | |||
| 	protected final Property<Boolean> transitiveAccessWideners; | ||||
| 	protected final Property<String> intermediary; | ||||
| 	protected final Property<Boolean> enableInterfaceInjection; | ||||
| 	private final Property<MinecraftJarConfiguration> minecraftJarConfiguration; | ||||
| 
 | ||||
| 	private final ModVersionParser versionParser; | ||||
| 
 | ||||
|  | @ -97,6 +99,9 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA | |||
| 				baseName -> new RunConfigSettings(project, baseName)); | ||||
| 		this.decompilers = project.getObjects().domainObjectContainer(DecompilerOptions.class); | ||||
| 
 | ||||
| 		this.minecraftJarConfiguration = project.getObjects().property(MinecraftJarConfiguration.class).convention(MinecraftJarConfiguration.MERGED); | ||||
| 		this.minecraftJarConfiguration.finalizeValueOnRead(); | ||||
| 
 | ||||
| 		this.accessWidener.finalizeValueOnRead(); | ||||
| 		this.getGameJarProcessors().finalizeValueOnRead(); | ||||
| 	} | ||||
|  | @ -203,6 +208,11 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA | |||
| 		net.fabricmc.loom.configuration.MavenPublication.excludePublication(publication); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public Property<MinecraftJarConfiguration> getMinecraftJarConfiguration() { | ||||
| 		return minecraftJarConfiguration; | ||||
| 	} | ||||
| 
 | ||||
| 	// This is here to ensure that LoomGradleExtensionApiImpl compiles without any unimplemented methods | ||||
| 	private final class EnsureCompile extends LoomGradleExtensionApiImpl { | ||||
| 		private EnsureCompile() { | ||||
|  |  | |||
|  | @ -26,11 +26,14 @@ package net.fabricmc.loom.task; | |||
| 
 | ||||
| import com.google.common.base.Preconditions; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.Task; | ||||
| import org.gradle.api.provider.Provider; | ||||
| import org.gradle.api.tasks.TaskContainer; | ||||
| import org.gradle.api.tasks.TaskProvider; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.configuration.ide.RunConfigSettings; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; | ||||
| import net.fabricmc.loom.task.launch.GenerateDLIConfigTask; | ||||
| import net.fabricmc.loom.task.launch.GenerateLog4jConfigTask; | ||||
| import net.fabricmc.loom.task.launch.GenerateRemapClasspathTask; | ||||
|  | @ -67,8 +70,6 @@ public final class LoomTasks { | |||
| 		}); | ||||
| 
 | ||||
| 		tasks.register("configureLaunch", task -> { | ||||
| 			task.dependsOn(tasks.named("extractNatives")); | ||||
| 			task.dependsOn(tasks.named("downloadAssets")); | ||||
| 			task.dependsOn(tasks.named("generateDLIConfig")); | ||||
| 			task.dependsOn(tasks.named("generateLog4jConfig")); | ||||
| 			task.dependsOn(tasks.named("generateRemapClasspath")); | ||||
|  | @ -77,6 +78,15 @@ public final class LoomTasks { | |||
| 			task.setGroup(Constants.TaskGroup.FABRIC); | ||||
| 		}); | ||||
| 
 | ||||
| 		tasks.register("configureClientLaunch", task -> { | ||||
| 			task.dependsOn(tasks.named("extractNatives")); | ||||
| 			task.dependsOn(tasks.named("downloadAssets")); | ||||
| 			task.dependsOn(tasks.named("configureLaunch")); | ||||
| 
 | ||||
| 			task.setDescription("Setup the required files to launch the Minecraft client"); | ||||
| 			task.setGroup(Constants.TaskGroup.FABRIC); | ||||
| 		}); | ||||
| 
 | ||||
| 		TaskProvider<ValidateAccessWidenerTask> validateAccessWidener = tasks.register("validateAccessWidener", ValidateAccessWidenerTask.class, t -> { | ||||
| 			t.setDescription("Validate all the rules in the access widener against the Minecraft jar"); | ||||
| 			t.setGroup("verification"); | ||||
|  | @ -91,13 +101,13 @@ public final class LoomTasks { | |||
| 	private static void registerIDETasks(TaskContainer tasks) { | ||||
| 		tasks.register("genIdeaWorkspace", GenIdeaProjectTask.class, t -> { | ||||
| 			t.setDescription("Generates an IntelliJ IDEA workspace from this project."); | ||||
| 			t.dependsOn("idea", "configureLaunch"); | ||||
| 			t.dependsOn("idea", getIDELaunchConfigureTaskName(t.getProject())); | ||||
| 			t.setGroup(Constants.TaskGroup.IDE); | ||||
| 		}); | ||||
| 
 | ||||
| 		tasks.register("genEclipseRuns", GenEclipseRunsTask.class, t -> { | ||||
| 			t.setDescription("Generates Eclipse run configurations for this project."); | ||||
| 			t.dependsOn("configureLaunch"); | ||||
| 			t.dependsOn(getIDELaunchConfigureTaskName(t.getProject())); | ||||
| 			t.setGroup(Constants.TaskGroup.IDE); | ||||
| 		}); | ||||
| 
 | ||||
|  | @ -108,7 +118,7 @@ public final class LoomTasks { | |||
| 
 | ||||
| 		tasks.register("vscode", GenVsCodeProjectTask.class, t -> { | ||||
| 			t.setDescription("Generates VSCode launch configurations."); | ||||
| 			t.dependsOn("configureLaunch"); | ||||
| 			t.dependsOn(getIDELaunchConfigureTaskName(t.getProject())); | ||||
| 			t.setGroup(Constants.TaskGroup.IDE); | ||||
| 		}); | ||||
| 	} | ||||
|  | @ -125,11 +135,25 @@ public final class LoomTasks { | |||
| 			tasks.register(taskName, RunGameTask.class, config).configure(t -> { | ||||
| 				t.setDescription("Starts the '" + config.getConfigName() + "' run configuration"); | ||||
| 
 | ||||
| 				t.dependsOn("configureLaunch"); | ||||
| 				t.dependsOn(config.getEnvironment().equals("client") ? "configureClientLaunch" : "configureLaunch"); | ||||
| 			}); | ||||
| 		}); | ||||
| 
 | ||||
| 		extension.getRunConfigs().create("client", RunConfigSettings::client); | ||||
| 		extension.getRunConfigs().create("server", RunConfigSettings::server); | ||||
| 
 | ||||
| 		// Remove the client run config when server only. Done by name to not remove any possible custom run configs | ||||
| 		project.afterEvaluate(p -> { | ||||
| 			if (extension.getMinecraftJarConfiguration().get() == MinecraftJarConfiguration.SERVER_ONLY) { | ||||
| 				extension.getRunConfigs().removeIf(settings -> settings.getName().equals("client")); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	public static Provider<Task> getIDELaunchConfigureTaskName(Project project) { | ||||
| 		return project.provider(() -> { | ||||
| 			final MinecraftJarConfiguration jarConfiguration = LoomGradleExtension.get(project).getMinecraftJarConfiguration().get(); | ||||
| 			final String name = jarConfiguration == MinecraftJarConfiguration.SERVER_ONLY ? "configureLaunch" : "configureClientLaunch"; | ||||
| 			return project.getTasks().getByName(name); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,88 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2021 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.test.integration | ||||
| 
 | ||||
| import net.fabricmc.loom.test.util.GradleProjectTestTrait | ||||
| import spock.lang.Specification | ||||
| import spock.lang.Unroll | ||||
| 
 | ||||
| import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS | ||||
| import static org.gradle.testkit.runner.TaskOutcome.SUCCESS | ||||
| 
 | ||||
| class MCJarConfigTest extends Specification implements GradleProjectTestTrait { | ||||
|     @Unroll | ||||
|     def "server only (gradle #version)"() { | ||||
|         setup: | ||||
|             def gradle = gradleProject(project: "minimalBase", version: version) | ||||
| 
 | ||||
|             gradle.buildGradle << ''' | ||||
|                 loom { | ||||
|                     serverOnlyMinecraftJar() | ||||
|                 } | ||||
| 
 | ||||
|                 dependencies { | ||||
|                     minecraft "com.mojang:minecraft:1.18.1" | ||||
|                     mappings "net.fabricmc:yarn:1.18.1+build.18:v2" | ||||
|                     modImplementation "net.fabricmc:fabric-loader:0.12.12" | ||||
|                 } | ||||
|             ''' | ||||
| 
 | ||||
|         when: | ||||
|             def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|             result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
|         where: | ||||
|             version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| 
 | ||||
|     @Unroll | ||||
|     def "split (gradle #version)"() { | ||||
|         setup: | ||||
|         def gradle = gradleProject(project: "minimalBase", version: version) | ||||
| 
 | ||||
|         gradle.buildGradle << ''' | ||||
|                 loom { | ||||
|                     splitMinecraftJar() | ||||
|                 } | ||||
| 
 | ||||
|                 dependencies { | ||||
|                     minecraft "com.mojang:minecraft:1.18.1" | ||||
|                     mappings "net.fabricmc:yarn:1.18.1+build.18:v2" | ||||
|                     modImplementation "net.fabricmc:fabric-loader:0.12.12" | ||||
|                 } | ||||
|             ''' | ||||
| 
 | ||||
|         when: | ||||
|         def result = gradle.run(task: "build") | ||||
| 
 | ||||
|         then: | ||||
|         result.task(":build").outcome == SUCCESS | ||||
| 
 | ||||
|         where: | ||||
|         version << STANDARD_TEST_VERSIONS | ||||
|     } | ||||
| } | ||||
|  | @ -199,6 +199,10 @@ trait GradleProjectTestTrait { | |||
|             return new File(getProjectDir(), "build.gradle") | ||||
|         } | ||||
| 
 | ||||
|         File getGradleProperties() { | ||||
|             return new File(getProjectDir(), "gradle.properties") | ||||
|         } | ||||
| 
 | ||||
|         String getOutputZipEntry(String filename, String entryName) { | ||||
|             def file = getOutputFile(filename) | ||||
|             def bytes = ZipUtils.unpackNullable(file.toPath(), entryName) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue