From df8404cda2a2947a50bd1c98e0e50482626d82b1 Mon Sep 17 00:00:00 2001 From: Paint_Ninja Date: Tue, 18 Aug 2026 13:40:24 +0100 Subject: [PATCH] Hand SlimeLauncher the extracted metadata zip, cache extraction - Avoids needing to re-extract it every launch from SlimeLauncher's end - Zip extraction is now cached by Gradle's build cache feature across builds with the same metadata zip --- .../SlimeLauncherEclipseConfiguration.java | 2 +- .../gradle/internal/SlimeLauncherExec.java | 2 +- .../internal/SlimeLauncherMetadata.java | 56 +++++++++++-------- .../minecraftforge/gradle/internal/Tools.java | 2 +- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherEclipseConfiguration.java b/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherEclipseConfiguration.java index bbcdf259b..678703310 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherEclipseConfiguration.java +++ b/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherEclipseConfiguration.java @@ -137,7 +137,7 @@ static TaskProvider register(Project project, task.getCacheDir().set(task.getObjects().directoryProperty().value(task.globalCaches().dir("slime-launcher/cache/%s".formatted(mcdep.getPath())).map(task.problems.ensureFileLocation()))); task.getLocalCacheDir().set(task.getObjects().directoryProperty().value(task.localCaches().dir("slime-launcher/cache/%s".formatted(task.getName())).map(task.problems.ensureFileLocation()))); - task.getMetadata().setFrom(metadata.map(SlimeLauncherMetadata::getMetadata)); + task.getMetadata().setFrom(metadata.map(SlimeLauncherMetadata::getOutputDirectory)); task.getRunsJson().set(metadata.flatMap(SlimeLauncherMetadata::getRunsJson)); task.getOptions().set(options); diff --git a/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherExec.java b/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherExec.java index e5b329ba9..be2a937f0 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherExec.java +++ b/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherExec.java @@ -61,7 +61,7 @@ static TaskProvider register(Project project, SourceSet sourc task.getCacheDir().set(task.getObjectFactory().directoryProperty().value(task.globalCaches().dir("slime-launcher/cache/%s".formatted(mcdep.getPath())).map(task.problems.ensureFileLocation()))); task.getLocalCacheDir().set(task.getObjectFactory().directoryProperty().value(task.localCaches().dir("slime-launcher/cache/%s".formatted(task.getName())).map(task.problems.ensureFileLocation()))); - task.getMetadata().setFrom(metadata.map(SlimeLauncherMetadata::getMetadata)); + task.getMetadata().setFrom(metadata.map(SlimeLauncherMetadata::getOutputDirectory)); task.getRunsJson().set(metadata.flatMap(SlimeLauncherMetadata::getRunsJson)); task.getOptions().set(options); diff --git a/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherMetadata.java b/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherMetadata.java index 828c44fe1..f23c62bd8 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherMetadata.java +++ b/src/main/java/net/minecraftforge/gradle/internal/SlimeLauncherMetadata.java @@ -6,60 +6,70 @@ import org.gradle.api.DefaultTask; import org.gradle.api.Project; +import org.gradle.api.file.ArchiveOperations; import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.FileSystemOperations; import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.TaskProvider; import javax.inject.Inject; -import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +@CacheableTask abstract class SlimeLauncherMetadata extends DefaultTask implements ForgeGradleTask { static TaskProvider register(Project project, MinecraftDependencyInternal mcdep) { var taskName = "slimeLauncherMetadataFor" + Util.dependencyToCamelCase(mcdep.getModule()); return project.getTasks().register(taskName, SlimeLauncherMetadata.class, task -> { task.setDescription("Extracts the Slime Launcher metadata for '%s'.".formatted(mcdep.toString())); - task.getMetadata().setFrom(mcdep.getMetadataDependency()); + task.getMetadataZip().setFrom(mcdep.getMetadataDependency()); }); } - protected abstract @InputFiles ConfigurableFileCollection getMetadata(); + @PathSensitive(PathSensitivity.NONE) + protected abstract @InputFiles ConfigurableFileCollection getMetadataZip(); + + protected abstract @OutputDirectory DirectoryProperty getOutputDirectory(); protected abstract @OutputFile RegularFileProperty getRunsJson(); + protected abstract @Inject ArchiveOperations getArchiveOperations(); + + protected abstract @Inject FileSystemOperations getFileSystemOperations(); + @Inject public SlimeLauncherMetadata() { - this.getRunsJson().convention(this.getDefaultOutputDirectory().map(d -> d.file("runs.json"))); + this.getOutputDirectory().convention(this.getDefaultOutputDirectory()); + this.getRunsJson().convention( + this.getOutputDirectory().map(d -> d.dir("launcher").file("runs.json")) + ); } @TaskAction protected void exec() throws IOException { - var archive = this.getMetadata().getSingleFile(); - var json = this.getRunsJson().getAsFile().get().toPath(); + var archive = this.getMetadataZip().getSingleFile(); + var outputDir = this.getOutputDirectory().get(); - boolean foundRuns = false; - try (var zin = new ZipInputStream(new FileInputStream(archive))) { - for (ZipEntry entry; ((entry = zin.getNextEntry()) != null); ) { - if (!entry.getName().startsWith("launcher/")) - continue; - if (entry.getName().equals("launcher/runs.json")) { - Files.copy(zin, json, StandardCopyOption.REPLACE_EXISTING); - foundRuns = true; - } - } - } + this.getFileSystemOperations().sync(spec -> { + spec.from(this.getArchiveOperations().zipTree(archive)); + spec.into(outputDir); + }); - // If we don't find a metadata file, write an empty runs - // This happens when using a 'vanilla' minecraft dependency - if (!foundRuns) + // Write an empty runs.json if it doesn't exist + // This happens when using a 'vanilla' Minecraft dependency + var json = this.getRunsJson().getAsFile().get().toPath(); + if (!Files.exists(json)) { + Files.createDirectories(json.getParent()); Files.writeString(json, "{}", StandardCharsets.UTF_8); + } } } diff --git a/src/main/java/net/minecraftforge/gradle/internal/Tools.java b/src/main/java/net/minecraftforge/gradle/internal/Tools.java index ec15fcd84..3154a6623 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/Tools.java +++ b/src/main/java/net/minecraftforge/gradle/internal/Tools.java @@ -9,7 +9,7 @@ final class Tools { private Tools() { } - static final Tool SLIMELAUNCHER = Tool.ofForge("slimelauncher", "net.minecraftforge:slime-launcher:0.2.2", 8, "net.minecraftforge.launcher.Main"); + static final Tool SLIMELAUNCHER = Tool.ofForge("slimelauncher", "net.minecraftforge:slime-launcher:0.2.3", 8, "net.minecraftforge.launcher.Main"); static final Tool MAVENIZER = Tool.ofForge("mavenizer", "net.minecraftforge:minecraft-mavenizer:0.5.19", 25, "net.minecraftforge.mcmaven.cli.Main"); }