diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java index 1564e8bbb..61a4d8443 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModConfigurationRemapper.java @@ -137,6 +137,7 @@ public static void supplyModConfigurations(Project project, SharedServiceManager // the installer data. The installer data has to be added before // any mods are remapped since remapping needs the dependencies provided by that data. final Map> dependenciesBySourceConfig = new HashMap<>(); + final Map metaCache = new HashMap<>(); configsToRemap.forEach((sourceConfig, remappedConfig) -> { /* sourceConfig - The source configuration where the intermediary named artifacts come from. i.e "modApi" @@ -148,11 +149,13 @@ public static void supplyModConfigurations(Project project, SharedServiceManager for (ArtifactRef artifact : resolveArtifacts(project, sourceConfig)) { final ArtifactMetadata artifactMetadata; - try { - artifactMetadata = ArtifactMetadata.create(artifact, LoomGradlePlugin.LOOM_VERSION); - } catch (IOException e) { - throw ExceptionUtil.createDescriptiveWrapper(UncheckedIOException::new, "Failed to read metadata from " + artifact.path(), e); - } + artifactMetadata = metaCache.computeIfAbsent(artifact, a -> { + try { + return ArtifactMetadata.create(a, LoomGradlePlugin.LOOM_VERSION); + } catch (IOException e) { + throw ExceptionUtil.createDescriptiveWrapper(UncheckedIOException::new, "Failed to read metadata from " + a.path(), e); + } + }); if (artifactMetadata.installerData() != null) { if (extension.getInstallerData() != null) { diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java index 622a0a1c6..97e96a47e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/SpecContextImpl.java @@ -29,8 +29,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; -import java.util.Optional; +import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Stream; @@ -57,11 +59,12 @@ */ public record SpecContextImpl(List modDependencies, List localMods, List compileRuntimeMods) implements SpecContext { public static SpecContextImpl create(Project project) { - return new SpecContextImpl(getDependentMods(project), FabricModJsonHelpers.getModsInProject(project), getCompileRuntimeMods(project)); + final Map> fmjCache = new HashMap<>(); + return new SpecContextImpl(getDependentMods(project, fmjCache), FabricModJsonHelpers.getModsInProject(project), getCompileRuntimeMods(project, fmjCache)); } // Reruns a list of mods found on both the compile and/or runtime classpaths - private static List getDependentMods(Project project) { + private static List getDependentMods(Project project, Map> fmjCache) { final LoomGradleExtension extension = LoomGradleExtension.get(project); var mods = new ArrayList(); @@ -69,10 +72,14 @@ private static List getDependentMods(Project project) { final Set artifacts = entry.getSourceConfiguration().get().resolve(); for (File artifact : artifacts) { - final FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(artifact.toPath()); - - if (fabricModJson != null) { - mods.add(fabricModJson); + final List fabricModJson = fmjCache.computeIfAbsent(artifact.toPath().toAbsolutePath().toString(), $ -> { + return FabricModJsonFactory.createFromZipOptional(artifact.toPath()) + .map(List::of) + .orElseGet(List::of); + }); + + if (!fabricModJson.isEmpty()) { + mods.add(fabricModJson.get(0)); } } } @@ -80,7 +87,9 @@ private static List getDependentMods(Project project) { if (!GradleUtils.getBooleanProperty(project, Constants.Properties.DISABLE_PROJECT_DEPENDENT_MODS)) { // Add all the dependent projects for (Project dependentProject : getDependentProjects(project).toList()) { - mods.addAll(FabricModJsonHelpers.getModsInProject(dependentProject)); + mods.addAll(fmjCache.computeIfAbsent(dependentProject.getPath(), $ -> { + return FabricModJsonHelpers.getModsInProject(dependentProject); + })); } } @@ -96,18 +105,20 @@ private static Stream getDependentProjects(Project project) { } // Returns a list of mods that are on both to compile and runtime classpath - private static List getCompileRuntimeMods(Project project) { - var mods = new ArrayList<>(getCompileRuntimeModsFromRemapConfigs(project).toList()); + private static List getCompileRuntimeMods(Project project, Map> fmjCache) { + var mods = new ArrayList<>(getCompileRuntimeModsFromRemapConfigs(project, fmjCache).toList()); for (Project dependentProject : getCompileRuntimeProjectDependencies(project).toList()) { - mods.addAll(FabricModJsonHelpers.getModsInProject(dependentProject)); + mods.addAll(fmjCache.computeIfAbsent(dependentProject.getPath(), $ -> { + return FabricModJsonHelpers.getModsInProject(dependentProject); + })); } return Collections.unmodifiableList(mods); } // Returns a list of jar mods that are found on the compile and runtime remapping configurations - private static Stream getCompileRuntimeModsFromRemapConfigs(Project project) { + private static Stream getCompileRuntimeModsFromRemapConfigs(Project project, Map> fmjCache) { final LoomGradleExtension extension = LoomGradleExtension.get(project); final List runtimeEntries = extension.getRuntimeRemapConfigurations().stream() .filter(settings -> settings.getApplyDependencyTransforms().get()) @@ -118,9 +129,15 @@ private static Stream getCompileRuntimeModsFromRemapConfigs(Proje .filter(settings -> settings.getApplyDependencyTransforms().get()) .flatMap(resolveArtifacts(project, false)) .filter(runtimeEntries::contains) // Use the intersection of the two configurations. - .map(FabricModJsonFactory::createFromZipOptional) - .filter(Optional::isPresent) - .map(Optional::get) + .map(zipPath -> { + final List list = fmjCache.computeIfAbsent(zipPath.toAbsolutePath().toString(), $ -> { + return FabricModJsonFactory.createFromZipOptional(zipPath) + .map(List::of) + .orElseGet(List::of); + }); + return list.isEmpty() ? null : list.get(0); + }) + .filter(Objects::nonNull) .sorted(Comparator.comparing(FabricModJson::getId)); }