From 3f27a847006738bce1d4337079bbe472d015264d Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:07:24 +0300 Subject: [PATCH] Fix configuration cache test --- .../loom/util/ForgeLoggerConfig.java | 46 ++++--- .../fabricmc/loom/api/ForgeExtensionAPI.java | 5 +- .../loom/build/IntermediaryNamespaces.java | 13 +- .../providers/forge/ForgeRunTemplate.java | 31 +++++ .../task/launch/GenerateDLIConfigTask.java | 118 ++++++++++++++---- .../task/launch/GenerateLog4jConfigTask.java | 31 ++++- 6 files changed, 189 insertions(+), 55 deletions(-) diff --git a/src/main/java/dev/architectury/loom/util/ForgeLoggerConfig.java b/src/main/java/dev/architectury/loom/util/ForgeLoggerConfig.java index f3667cce3..ff4cbb1d1 100644 --- a/src/main/java/dev/architectury/loom/util/ForgeLoggerConfig.java +++ b/src/main/java/dev/architectury/loom/util/ForgeLoggerConfig.java @@ -5,10 +5,12 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.List; import java.util.StringJoiner; import org.gradle.api.Project; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.LoomGradleExtension; @@ -22,46 +24,42 @@ public final class ForgeLoggerConfig { new ArtifactCoordinates("net.minecraftforge", "forge", "launcher") ); - public static void copyToPath(Project project, Path outputFile) { - try { - Files.deleteIfExists(outputFile); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - + public static @Nullable File getForgeLoggerConfigSource(Project project) { final List libraries = LoomGradleExtension.get(project) .getForgeUserdevProvider() .getConfig() .libraries(); - boolean found = false; for (String library : libraries) { if (LOGGER_CONFIG_ARTIFACTS.stream().anyMatch(artifact -> artifact.matches(library))) { - final File libraryFile = project.getConfigurations() + return project.getConfigurations() .detachedConfiguration(project.getDependencies().create(library)) .setTransitive(false) .getSingleFile(); - - try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(libraryFile, false)) { - final Path configPath = fs.getPath("log4j2.xml"); - Files.copy(configPath, outputFile); - found = true; - break; - } catch (IOException e) { - throw new UncheckedIOException(e); - } } } - if (!found) { - StringBuilder sb = new StringBuilder("Could not find Forge dependency with logger config. Tried to find:"); + return null; + } - for (ArtifactCoordinates artifact : LOGGER_CONFIG_ARTIFACTS) { - sb.append('\n').append(" - ").append(artifact); - } + public static void copyToPath(Path libraryFile, Path outputFile) { + try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(libraryFile, false)) { + final Path configPath = fs.getPath("log4j2.xml"); + Files.copy(configPath, outputFile, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Contract("-> fail") + public static void throwNotFound() { + StringBuilder sb = new StringBuilder("Could not find Forge dependency with logger config. Tried to find:"); - throw new RuntimeException(sb.toString()); + for (ArtifactCoordinates artifact : LOGGER_CONFIG_ARTIFACTS) { + sb.append('\n').append(" - ").append(artifact); } + + throw new RuntimeException(sb.toString()); } private record ArtifactCoordinates(String group, String name, @Nullable String classifier) { diff --git a/src/main/java/net/fabricmc/loom/api/ForgeExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/ForgeExtensionAPI.java index 17f5b3a54..0b8f94c0e 100644 --- a/src/main/java/net/fabricmc/loom/api/ForgeExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/ForgeExtensionAPI.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2021-2023 FabricMC + * Copyright (c) 2021-2024 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 @@ -109,7 +109,10 @@ default void mixinConfig(String... mixinConfigs) { * This is disabled by default. * * @return the property + * @deprecated This API is not needed on newer Minecraft versions where Forge forces its own logger config. */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.0") + @Deprecated(forRemoval = true) Property getUseForgeLoggerConfig(); /** diff --git a/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java b/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java index 13f255df5..f3a93922e 100644 --- a/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java +++ b/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2022-2023 FabricMC + * Copyright (c) 2022-2024 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 @@ -28,6 +28,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.util.ModPlatform; public final class IntermediaryNamespaces { /** @@ -49,8 +50,14 @@ public static String runtimeIntermediary(Project project) { * Returns the intermediary namespace of the project. */ public static MappingsNamespace intermediaryNamespace(Project project) { - LoomGradleExtension extension = LoomGradleExtension.get(project); - return switch (extension.getPlatform().get()) { + return intermediaryNamespace(LoomGradleExtension.get(project).getPlatform().get()); + } + + /** + * Returns the intermediary namespace of the platform. + */ + public static MappingsNamespace intermediaryNamespace(ModPlatform platform) { + return switch (platform) { case FABRIC, QUILT -> MappingsNamespace.INTERMEDIARY; case FORGE -> MappingsNamespace.SRG; case NEOFORGE -> MappingsNamespace.MOJANG; diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeRunTemplate.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeRunTemplate.java index 210d33ee9..c94e951e2 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeRunTemplate.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeRunTemplate.java @@ -28,6 +28,8 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import java.util.stream.Collector; +import java.util.stream.Collectors; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -117,4 +119,33 @@ public void applyTo(RunConfigSettings settings, ConfigValue.Resolver configValue settings.property(Constants.Forge.UNION_RELAUNCHER_MAIN_CLASS_PROPERTY, main); } } + + public Resolved resolve(ConfigValue.Resolver configValueResolver) { + final Function resolve = value -> value.resolve(configValueResolver); + final Collector, ?, Map> resolveMap = + Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().resolve(configValueResolver)); + + final List args = this.args.stream().map(resolve).toList(); + final List jvmArgs = this.jvmArgs.stream().map(resolve).toList(); + final Map env = this.env.entrySet().stream().collect(resolveMap); + final Map props = this.props.entrySet().stream().collect(resolveMap); + + return new Resolved( + name, + main, + args, + jvmArgs, + env, + props + ); + } + + public record Resolved( + String name, + String main, + List args, + List jvmArgs, + Map env, + Map props + ) { } } diff --git a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java index 46e5482e5..cd5a90fee 100644 --- a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java +++ b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java @@ -26,26 +26,32 @@ import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.StringJoiner; import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; import org.gradle.api.Project; +import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.logging.configuration.ConsoleOutput; import org.gradle.api.provider.Property; +import org.gradle.api.provider.SetProperty; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; +import org.jetbrains.annotations.ApiStatus; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; @@ -57,7 +63,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.task.AbstractLoomTask; import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.PropertyUtil; +import net.fabricmc.loom.util.ModPlatform; import net.fabricmc.loom.util.gradle.SourceSetHelper; public abstract class GenerateDLIConfigTask extends AbstractLoomTask { @@ -103,6 +109,27 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask { @OutputFile protected abstract RegularFileProperty getDevLauncherConfig(); + @ApiStatus.Internal + @Input + protected abstract Property getPlatform(); + + @ApiStatus.Internal + @Input + @Optional + protected abstract Property getForgeInputs(); + + @ApiStatus.Internal + @InputFile + protected abstract RegularFileProperty getPlatformMappingFile(); + + @ApiStatus.Internal + @InputFiles + protected abstract ConfigurableFileCollection getMappingJars(); + + @ApiStatus.Internal + @Input + protected abstract SetProperty getRunTemplates(); + public GenerateDLIConfigTask() { getVersionInfoJson().set(LoomGradlePlugin.GSON.toJson(getExtension().getMinecraftProvider().getVersionInfo())); getMinecraftVersion().set(getExtension().getMinecraftProvider().minecraftVersion()); @@ -124,6 +151,30 @@ public GenerateDLIConfigTask() { getAssetsDirectoryPath().set(new File(getExtension().getFiles().getUserCache(), "assets").getAbsolutePath()); getNativesDirectoryPath().set(getExtension().getFiles().getNativesDirectory(getProject()).getAbsolutePath()); getDevLauncherConfig().set(getExtension().getFiles().getDevLauncherConfig()); + + getPlatform().set(getExtension().getPlatform()); + getPlatform().finalizeValue(); + + getPlatformMappingFile().set(getProject().getLayout().file(getProject().provider(() -> getExtension().getPlatformMappingFile().toFile()))); + getPlatformMappingFile().finalizeValue(); + getMappingJars().from(getProject().getConfigurations().getByName(Constants.Configurations.MAPPINGS_FINAL)); + + if (getExtension().isForgeLike()) { + getRunTemplates().addAll(getProject().provider(() -> { + final ForgeRunsProvider forgeRunsProvider = getExtension().getForgeRunsProvider(); + final ConfigValue.Resolver configResolver = forgeRunsProvider.getResolver(null); + return forgeRunsProvider.getTemplates() + .stream() + .map(template -> template.resolve(configResolver)) + .toList(); + })); + + if (getExtension().isForge()) { + getForgeInputs().set(getProject().provider(() -> new ForgeInputs(getProject(), getExtension()))); + } + } else { + getRunTemplates().empty(); + } } @TaskAction @@ -135,7 +186,8 @@ public void run() throws IOException { assetsDirectory = new File(assetsDirectory, "/legacy/" + versionInfo.id()); } - boolean quilt = getExtension().isQuilt(); + final ModPlatform platform = getPlatform().get(); + boolean quilt = platform == ModPlatform.QUILT; final LaunchConfig launchConfig = new LaunchConfig() .property(!quilt ? "fabric.development" : "loader.development", "true") .property(!quilt ? "fabric.remapClasspathFile" : "loader.remapClasspathFile", getRemapClasspathFile().get().getAsFile().getAbsolutePath()) @@ -150,7 +202,7 @@ public void run() throws IOException { .property("client", "org.lwjgl.librarypath", nativesPath); } - if (!getExtension().isForgeLike()) { + if (!platform.isForgeLike()) { launchConfig .argument("client", "--assetIndex") .argument("client", versionInfo.assetIndex().fabricId(getMinecraftVersion().get())) @@ -167,24 +219,23 @@ public void run() throws IOException { } } - if (getExtension().isQuilt()) { + if (quilt) { launchConfig .argument("client", "--version") .argument("client", "Architectury Loom"); } - if (getExtension().isForgeLike()) { + if (platform.isForgeLike()) { // Find the mapping files for Unprotect to use for figuring out // which classes are from Minecraft. - String unprotectMappings = getProject().getConfigurations() - .getByName(Constants.Configurations.MAPPINGS_FINAL) - .resolve() + String unprotectMappings = getMappingJars() + .getFiles() .stream() .map(File::getAbsolutePath) .collect(Collectors.joining(File.pathSeparator)); - final String intermediateNs = IntermediaryNamespaces.intermediary(getProject()); - final String mappingsPath = getExtension().getPlatformMappingFile().toAbsolutePath().toString(); + final String intermediateNs = IntermediaryNamespaces.intermediaryNamespace(platform).toString(); + final String mappingsPath = getPlatformMappingFile().get().getAsFile().getAbsolutePath(); launchConfig .property("unprotect.mappings", unprotectMappings) @@ -192,31 +243,32 @@ public void run() throws IOException { .property("architectury.naming.sourceNamespace", intermediateNs) .property("architectury.naming.mappingsPath", mappingsPath); - if (getExtension().isForge()) { - final List dataGenMods = getExtension().getForge().getDataGenMods(); + if (platform == ModPlatform.FORGE) { + final ForgeInputs forgeInputs = Objects.requireNonNull(getForgeInputs().getOrNull()); + final List dataGenMods = forgeInputs.dataGenMods(); // Only apply the hardcoded data arguments if the deprecated data generator API is being used. if (!dataGenMods.isEmpty()) { launchConfig .argument("data", "--all") .argument("data", "--mod") - .argument("data", String.join(",", getExtension().getForge().getDataGenMods())) + .argument("data", String.join(",", dataGenMods)) .argument("data", "--output") - .argument("data", getProject().file("src/generated/resources").getAbsolutePath()); + .argument("data", forgeInputs.legacyDataGenDir()); } launchConfig.property("mixin.env.remapRefMap", "true"); - if (PropertyUtil.getAndFinalize(getExtension().getForge().getUseCustomMixin())) { + if (forgeInputs.useCustomMixin()) { // See mixin remapper service in forge-runtime launchConfig .property("architectury.mixinRemapper.sourceNamespace", intermediateNs) .property("architectury.mixinRemapper.mappingsPath", mappingsPath); } else { - launchConfig.property("net.minecraftforge.gradle.GradleStart.srg.srg-mcp", getExtension().getMappingConfiguration().srgToNamedSrg.toAbsolutePath().toString()); + launchConfig.property("net.minecraftforge.gradle.GradleStart.srg.srg-mcp", forgeInputs.srgToNamedSrg()); } - Set mixinConfigs = PropertyUtil.getAndFinalize(getExtension().getForge().getMixinConfigs()); + Set mixinConfigs = forgeInputs.mixinConfigs(); if (!mixinConfigs.isEmpty()) { for (String config : mixinConfigs) { @@ -226,16 +278,13 @@ public void run() throws IOException { } } - ForgeRunsProvider forgeRunsProvider = getExtension().getForgeRunsProvider(); - ConfigValue.Resolver configResolver = forgeRunsProvider.getResolver(null); - - for (ForgeRunTemplate template : forgeRunsProvider.getTemplates()) { - for (ConfigValue argument : template.args()) { - launchConfig.argument(template.name(), argument.resolve(configResolver)); + for (ForgeRunTemplate.Resolved template : getRunTemplates().get()) { + for (String argument : template.args()) { + launchConfig.argument(template.name(), argument); } - for (Map.Entry property : template.props().entrySet()) { - launchConfig.property(template.name(), property.getKey(), property.getValue().resolve(configResolver)); + for (Map.Entry property : template.props().entrySet()) { + launchConfig.property(template.name(), property.getKey(), property.getValue()); } } } @@ -322,4 +371,23 @@ public String asString() { return stringJoiner.toString(); } } + + @ApiStatus.Internal + public record ForgeInputs( + List dataGenMods, + String legacyDataGenDir, + Set mixinConfigs, + boolean useCustomMixin, + String srgToNamedSrg + ) implements Serializable { + public ForgeInputs(Project project, LoomGradleExtension extension) { + this( + extension.getForge().getDataGenMods(), + project.file("src/generated/resources").getAbsolutePath(), + extension.getForge().getMixinConfigs().get(), + extension.getForge().getUseCustomMixin().get(), + extension.getMappingConfiguration().srgToNamedSrg.toAbsolutePath().toString() + ); + } + } } diff --git a/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java b/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java index 55974a62e..dad61e2d1 100644 --- a/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java +++ b/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java @@ -32,9 +32,16 @@ import javax.inject.Inject; import dev.architectury.loom.util.ForgeLoggerConfig; +import org.gradle.api.file.RegularFile; import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.task.AbstractLoomTask; @@ -42,17 +49,37 @@ public abstract class GenerateLog4jConfigTask extends AbstractLoomTask { @OutputFile public abstract RegularFileProperty getOutputFile(); + @ApiStatus.Internal + @Input + protected abstract Property getUseForgeLoggerConfig(); + + @ApiStatus.Internal + @InputFile + @Optional + protected abstract RegularFileProperty getForgeLoggerConfigSource(); + @Inject public GenerateLog4jConfigTask() { getOutputFile().set(getExtension().getFiles().getDefaultLog4jConfigFile()); + + if (getExtension().isForge()) { + getUseForgeLoggerConfig().set(getProject().provider(() -> getExtension().getForge().getUseForgeLoggerConfig().get())); + getForgeLoggerConfigSource().set(getProject().getLayout().file( + getProject().provider(() -> ForgeLoggerConfig.getForgeLoggerConfigSource(getProject())) + )); + } else { + getUseForgeLoggerConfig().set(false); + } } @TaskAction public void run() { Path outputFile = getOutputFile().get().getAsFile().toPath(); - if (getExtension().isForge() && getExtension().getForge().getUseForgeLoggerConfig().get()) { - ForgeLoggerConfig.copyToPath(getProject(), outputFile); + if (getUseForgeLoggerConfig().get()) { + final @Nullable RegularFile source = getForgeLoggerConfigSource().getOrNull(); + if (source == null) ForgeLoggerConfig.throwNotFound(); + ForgeLoggerConfig.copyToPath(source.getAsFile().toPath(), outputFile); return; }