diff --git a/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java b/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java index 9bb9912d..2ec61a28 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java @@ -28,7 +28,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Collection; -import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -37,17 +36,17 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import org.gradle.api.UncheckedIOException; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import net.fabricmc.loom.LoomGradlePlugin; -import net.fabricmc.loom.build.nesting.IncludedJarFactory.NestedFile; import net.fabricmc.loom.util.ModPlatform; import net.fabricmc.loom.util.Pair; import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.fmj.FabricModJsonFactory; public class JarNester { - public static void nestJars(Collection jars, List forgeJars, File modJar, ModPlatform platform, Logger logger) { + public static void nestJars(Collection jars, File modJar, ModPlatform platform, Logger logger) { if (jars.isEmpty()) { logger.debug("Nothing to nest into " + modJar.getName()); return; @@ -65,7 +64,7 @@ public class JarNester { }).collect(Collectors.toList())); if (platform.isForgeLike()) { - handleForgeJarJar(forgeJars, modJar, logger); + handleForgeJarJar(jars, modJar, logger); return; } @@ -141,13 +140,27 @@ public class JarNester { } } - private static void handleForgeJarJar(List forgeJars, File modJar, Logger logger) throws IOException { + private static @Nullable NestableJarGenerationTask.Metadata readNestedFile(File file, Logger logger) { + try { + return ZipUtils.unpackGsonNullable(file.toPath(), NestableJarGenerationTask.NESTING_METADATA_PATH, NestableJarGenerationTask.Metadata.class); + } catch (IOException e) { + logger.error("Could not read {}", file.getAbsolutePath(), e); + return null; + } + } + + private static void handleForgeJarJar(Collection jars, File modJar, Logger logger) throws IOException { JsonObject json = new JsonObject(); JsonArray nestedJars = new JsonArray(); - for (NestedFile nestedFile : forgeJars) { - IncludedJarFactory.Metadata metadata = nestedFile.metadata(); - File file = nestedFile.file(); + for (File file : jars) { + NestableJarGenerationTask.Metadata metadata = readNestedFile(file, logger); + + if (metadata == null) { + logger.error("Jar {} does not contain Loom nesting metadata", file.getAbsolutePath()); + continue; + } + String nestedJarPath = "META-INF/jars/" + file.getName(); for (JsonElement nestedJar : nestedJars) { diff --git a/src/main/java/net/fabricmc/loom/build/nesting/NestableJarGenerationTask.java b/src/main/java/net/fabricmc/loom/build/nesting/NestableJarGenerationTask.java index 365a630f..f0e61463 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/NestableJarGenerationTask.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/NestableJarGenerationTask.java @@ -40,7 +40,6 @@ import java.util.regex.Pattern; import com.google.common.hash.Hashing; import com.google.gson.JsonObject; import org.apache.commons.io.FileUtils; -import org.gradle.api.DefaultTask; import org.gradle.api.artifacts.ArtifactView; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.component.ComponentIdentifier; @@ -61,13 +60,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.task.AbstractLoomTask; import net.fabricmc.loom.util.ZipReprocessorUtil; +import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.fmj.FabricModJsonFactory; -public abstract class NestableJarGenerationTask extends DefaultTask { +public abstract class NestableJarGenerationTask extends AbstractLoomTask { private static final Logger LOGGER = LoggerFactory.getLogger(NestableJarGenerationTask.class); private static final String SEMVER_REGEX = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"; private static final Pattern SEMVER_PATTERN = Pattern.compile(SEMVER_REGEX); + public static final String NESTING_METADATA_PATH = "META-INF/architectury-loom-nesting-metadata.json"; @InputFiles @PathSensitive(PathSensitivity.NAME_ONLY) @@ -82,7 +84,13 @@ public abstract class NestableJarGenerationTask extends DefaultTask { @TaskAction void makeNestableJars() { Map fabricModJsons = new HashMap<>(); + Map metadataFiles = new HashMap<>(); getJarIds().get().forEach((fileName, metadata) -> { + if (getExtension().isForgeLike()) { + metadataFiles.put(fileName, LoomGradlePlugin.GSON.toJson(metadata)); + return; + } + fabricModJsons.put(fileName, generateModForDependency(metadata)); }); @@ -97,8 +105,14 @@ public abstract class NestableJarGenerationTask extends DefaultTask { getJars().forEach(file -> { File targetFile = getOutputDirectory().file(file.getName()).get().getAsFile(); targetFile.delete(); - String fabricModJson = Objects.requireNonNull(fabricModJsons.get(file.getName()), "Could not generate fabric.mod.json for included dependency "+file.getName()); - makeNestableJar(file, targetFile, fabricModJson); + String fabricModJson = fabricModJsons.get(file.getName()); + String nestingMetadata = metadataFiles.get(file.getName()); + + if (!getExtension().isForgeLike()) { + Objects.requireNonNull(fabricModJson, "Could not generate fabric.mod.json for included dependency "+file.getName()); + } + + makeNestableJar(file, targetFile, fabricModJson, nestingMetadata); }); } @@ -215,14 +229,22 @@ public abstract class NestableJarGenerationTask extends DefaultTask { return matcher.find(); } - private void makeNestableJar(final File input, final File output, final String modJsonFile) { + private void makeNestableJar(final File input, final File output, final @Nullable String modJsonFile, final @Nullable String nestingMetadata) { try { FileUtils.copyFile(input, output); } catch (IOException e) { throw new UncheckedIOException("Failed to copy mod file %s".formatted(input), e); } - if (FabricModJsonFactory.isModJar(input)) { + if (nestingMetadata != null) { + try { + ZipUtils.add(input.toPath(), NESTING_METADATA_PATH, nestingMetadata); + } catch (IOException e) { + throw new UncheckedIOException("Failed to add nesting metadata to " + input, e); + } + } + + if (modJsonFile == null || FabricModJsonFactory.isModJar(input, getExtension().getPlatform().get())) { // Input is a mod, nothing needs to be done. return; } @@ -234,7 +256,7 @@ public abstract class NestableJarGenerationTask extends DefaultTask { } } - protected record Metadata(String group, String name, String version, @Nullable String classifier) implements Serializable { + public record Metadata(String group, String name, String version, @Nullable String classifier) implements Serializable { @Override public String classifier() { if (classifier == null) { diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index a34b2b86..946c01ec 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -24,7 +24,6 @@ package net.fabricmc.loom.task; -import java.io.File; import java.io.IOException; import java.io.Serializable; import java.nio.file.Files; @@ -44,7 +43,6 @@ import javax.inject.Inject; import com.google.gson.JsonObject; import dev.architectury.loom.extensions.ModBuildExtensions; -import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; @@ -59,7 +57,6 @@ import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskAction; -import org.gradle.api.tasks.TaskDependency; import org.gradle.api.tasks.TaskProvider; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -95,9 +92,6 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { @InputFiles public abstract ConfigurableFileCollection getNestedJars(); - @Input - public abstract ListProperty getForgeNestedJars(); - @Input public abstract Property getAddNestedDependencies(); @@ -194,10 +188,6 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { submitWork(RemapAction.class, params -> { if (getAddNestedDependencies().get()) { params.getNestedJars().from(getNestedJars()); - - if (extension.isForgeLike()) { - params.getForgeNestedJars().set(getForgeNestedJars()); - } } if (!params.namespacesMatch()) { @@ -281,8 +271,6 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { public interface RemapParams extends AbstractRemapParams { ConfigurableFileCollection getNestedJars(); - ListProperty getForgeNestedJars(); - ConfigurableFileCollection getRemapClasspath(); Property getPlatform(); @@ -458,16 +446,13 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { private void addNestedJars() { FileCollection nestedJars = getParameters().getNestedJars(); - ListProperty forgeNestedJars = getParameters().getForgeNestedJars(); - if (nestedJars.isEmpty() && (!forgeNestedJars.isPresent() || forgeNestedJars.get().isEmpty())) { + if (nestedJars.isEmpty()) { LOGGER.info("No jars to nest"); return; } - Set jars = new LinkedHashSet<>(nestedJars.getFiles()); - jars.addAll(forgeNestedJars.get().stream().map(NestedFile::file).toList()); - JarNester.nestJars(jars, forgeNestedJars.getOrElse(List.of()), outputFile.toFile(), getParameters().getPlatform().get(), LOGGER); + JarNester.nestJars(nestedJars.getFiles(), outputFile.toFile(), getParameters().getPlatform().get(), LOGGER); } private void addRefmaps() throws IOException {