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:
modmuss50 2022-01-17 22:11:08 +00:00 committed by GitHub
parent d71af0cfd7
commit e9d1f005d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 551 additions and 117 deletions

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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);
});
}
}

View file

@ -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));

View file

@ -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);

View file

@ -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()) {

View file

@ -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());
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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());
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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)
);
}
}
}

View file

@ -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());
}
}
}

View file

@ -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);
}
}
}

View file

@ -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());
}
}
}

View file

@ -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() {

View file

@ -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);
});
}
}

View file

@ -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
}
}

View file

@ -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)