Skip to content

Commit

Permalink
Fix getCompileRuntimeModsFromRemapConfigs not returning mods that hav…
Browse files Browse the repository at this point in the history
…e different versions on the compile/runtime classpath. (#1246)
  • Loading branch information
modmuss50 authored Jan 8, 2025
1 parent e1cc6f0 commit 3ee1372
Showing 1 changed file with 24 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.attributes.Usage;
import org.gradle.api.plugins.JavaPlugin;
import org.jetbrains.annotations.Nullable;

import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.RemapConfigurationSettings;
Expand Down Expand Up @@ -121,27 +123,37 @@ private static List<FabricModJson> getCompileRuntimeMods(Project project, Map<St
// Returns a list of jar mods that are found on the compile and runtime remapping configurations
private static Stream<FabricModJson> getCompileRuntimeModsFromRemapConfigs(Project project, Map<String, List<FabricModJson>> fmjCache) {
final LoomGradleExtension extension = LoomGradleExtension.get(project);
final List<Path> runtimeEntries = extension.getRuntimeRemapConfigurations().stream()
final Set<String> runtimeModIds = extension.getRuntimeRemapConfigurations().stream()
.filter(settings -> settings.getApplyDependencyTransforms().get())
.flatMap(resolveArtifacts(project, true))
.toList();
.map(modFromZip(fmjCache))
.filter(Objects::nonNull)
.map(FabricModJson::getId)
.collect(Collectors.toSet());

return extension.getCompileRemapConfigurations().stream()
.filter(settings -> settings.getApplyDependencyTransforms().get())
.flatMap(resolveArtifacts(project, false))
.filter(runtimeEntries::contains) // Use the intersection of the two configurations.
.map(zipPath -> {
final List<FabricModJson> list = fmjCache.computeIfAbsent(zipPath.toAbsolutePath().toString(), $ -> {
return FabricModJsonFactory.createFromZipOptional(zipPath)
.map(List::of)
.orElseGet(List::of);
});
return list.isEmpty() ? null : list.get(0);
})
.flatMap(resolveArtifacts(project, false))// Use the intersection of the two configurations.
.map(modFromZip(fmjCache))
.filter(Objects::nonNull)
// Only check based on the modid, as there may be differing versions used between the compile and runtime classpath.
// We assume that the version used at runtime will be binary compatible with the version used to compile against.
// It's not perfect but better than silently not supplying the mod, and this could happen with regular API that you compile against anyway.
.filter(fabricModJson -> runtimeModIds.contains(fabricModJson.getId()))
.sorted(Comparator.comparing(FabricModJson::getId));
}

private static Function<Path, @Nullable FabricModJson> modFromZip(Map<String, List<FabricModJson>> fmjCache) {
return zipPath -> {
final List<FabricModJson> list = fmjCache.computeIfAbsent(zipPath.toAbsolutePath().toString(), $ -> {
return FabricModJsonFactory.createFromZipOptional(zipPath)
.map(List::of)
.orElseGet(List::of);
});
return list.isEmpty() ? null : list.get(0);
};
}

private static Function<RemapConfigurationSettings, Stream<Path>> resolveArtifacts(Project project, boolean runtime) {
final Usage usage = project.getObjects().named(Usage.class, runtime ? Usage.JAVA_RUNTIME : Usage.JAVA_API);

Expand Down

0 comments on commit 3ee1372

Please sign in to comment.