Skip to content

Commit

Permalink
Add Fabric-Loom-Mixin-Remap-Type manifest entry
Browse files Browse the repository at this point in the history
  • Loading branch information
modmuss50 committed Nov 8, 2023
1 parent 83ab524 commit 7dcec87
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 222 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import java.util.function.Predicate;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
Expand All @@ -41,15 +42,17 @@
import net.fabricmc.loom.util.FileSystemUtil;
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;

public record ArtifactMetadata(boolean isFabricMod, RemapRequirements remapRequirements, @Nullable InstallerData installerData) {
public record ArtifactMetadata(boolean isFabricMod, RemapRequirements remapRequirements, @Nullable InstallerData installerData, RefmapRemapType refmapRemapType) {
private static final String INSTALLER_PATH = "fabric-installer.json";
private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF";
private static final String MANIFEST_REMAP_KEY = "Fabric-Loom-Remap";
public static final String MANIFEST_MIXIN_REMAP_TYPE = "Fabric-Loom-Mixin-Remap-Type";

public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
boolean isFabricMod;
RemapRequirements remapRequirements = RemapRequirements.DEFAULT;
InstallerData installerData = null;
RefmapRemapType refmapRemapType = RefmapRemapType.MIXIN;

try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(artifact.path())) {
isFabricMod = FabricModJsonFactory.containsMod(fs);
Expand All @@ -58,11 +61,20 @@ public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
if (Files.exists(manifestPath)) {
final var manifest = new Manifest(new ByteArrayInputStream(Files.readAllBytes(manifestPath)));
final Attributes mainAttributes = manifest.getMainAttributes();
final String value = mainAttributes.getValue(MANIFEST_REMAP_KEY);
final String remapKey = mainAttributes.getValue(MANIFEST_REMAP_KEY);
final String mixinRemapType = mainAttributes.getValue(MANIFEST_MIXIN_REMAP_TYPE);

if (value != null) {
if (remapKey != null) {
// Support opting into and out of remapping with "Fabric-Loom-Remap" manifest entry
remapRequirements = Boolean.parseBoolean(value) ? RemapRequirements.OPT_IN : RemapRequirements.OPT_OUT;
remapRequirements = Boolean.parseBoolean(remapKey) ? RemapRequirements.OPT_IN : RemapRequirements.OPT_OUT;
}

if (mixinRemapType != null) {
try {
refmapRemapType = RefmapRemapType.valueOf(mixinRemapType.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Unknown mixin remap type: " + mixinRemapType);
}
}
}

Expand All @@ -74,7 +86,7 @@ public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
}
}

return new ArtifactMetadata(isFabricMod, remapRequirements, installerData);
return new ArtifactMetadata(isFabricMod, remapRequirements, installerData, refmapRemapType);
}

public boolean shouldRemap() {
Expand All @@ -100,4 +112,15 @@ private Predicate<ArtifactMetadata> getShouldRemap() {
return shouldRemap;
}
}

public enum RefmapRemapType {
// Jar uses refmaps, so will be remapped by mixin
MIXIN,
// Jar does not use refmaps, so will be remapped by tiny-remapper
STATIC;

public String manifestValue() {
return name().toLowerCase(Locale.ROOT);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public static void supplyModConfigurations(Project project, SharedServiceManager
continue;
}

final ModDependency modDependency = ModDependencyFactory.create(artifact, remappedConfig, clientRemappedConfig, mappingsSuffix, project);
final ModDependency modDependency = ModDependencyFactory.create(artifact, artifactMetadata, remappedConfig, clientRemappedConfig, mappingsSuffix, project);
scheduleSourcesRemapping(project, sourceRemapper, modDependency);
modDependencies.add(modDependency);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,14 @@ private void remapJars(List<ModDependency> remapList) throws IOException {
builder.extension(kotlinRemapperClassloader.getTinyRemapperExtension());
}

final Set<InputTag> hasMixinsWithoutRefmaps = new HashSet<>();
// Configure the mixin extension to remap mixins from mod jars detected not to contain refmaps.
builder.extension(new MixinExtension(hasMixinsWithoutRefmaps::contains));
final Set<InputTag> remapMixins = new HashSet<>();
final boolean requiresStaticMixinRemap = remapList.stream()
.anyMatch(modDependency -> modDependency.getMetadata().refmapRemapType() == ArtifactMetadata.RefmapRemapType.STATIC);

if (requiresStaticMixinRemap) {
// Configure the mixin extension to remap mixins from mod jars that were remapped with the mixin extension.
builder.extension(new MixinExtension(remapMixins::contains));
}

final TinyRemapper remapper = builder.build();

Expand Down Expand Up @@ -182,8 +187,14 @@ private void remapJars(List<ModDependency> remapList) throws IOException {

// Note: this is done at a jar level, not at the level of an individual mixin config.
// If a mod has multiple mixin configs, it's assumed that either all or none of them have refmaps.
if (MixinDetector.hasMixinsWithoutRefmap(info.getInputFile())) {
hasMixinsWithoutRefmaps.add(tag);
if (info.getMetadata().refmapRemapType() == ArtifactMetadata.RefmapRemapType.STATIC) {
if (!requiresStaticMixinRemap) {
// Should be impossible but stranger things have happened.
throw new IllegalStateException("Was not configured for static remap, but a mod required it?!");
}

project.getLogger().info("Remapping mixins in {} statically", info.getInputFile());
remapMixins.add(tag);
}

remapper.readInputsAsync(tag, info.getInputFile());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
import org.jetbrains.annotations.Nullable;

import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.configuration.mods.ArtifactMetadata;
import net.fabricmc.loom.configuration.mods.ArtifactRef;

public abstract sealed class ModDependency permits SplitModDependency, SimpleModDependency {
private final ArtifactRef artifact;
private final ArtifactMetadata metadata;
protected final String group;
protected final String name;
protected final String version;
Expand All @@ -43,8 +45,9 @@ public abstract sealed class ModDependency permits SplitModDependency, SimpleMod
protected final String mappingsSuffix;
protected final Project project;

public ModDependency(ArtifactRef artifact, String mappingsSuffix, Project project) {
public ModDependency(ArtifactRef artifact, ArtifactMetadata metadata, String mappingsSuffix, Project project) {
this.artifact = artifact;
this.metadata = metadata;
this.group = artifact.group();
this.name = artifact.name();
this.version = artifact.version();
Expand Down Expand Up @@ -78,6 +81,10 @@ public ArtifactRef getInputArtifact() {
return artifact;
}

public ArtifactMetadata getMetadata() {
return metadata;
}

protected String getRemappedGroup() {
return getMappingsPrefix() + "." + group;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@
import org.jetbrains.annotations.Nullable;

import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.configuration.mods.ArtifactMetadata;
import net.fabricmc.loom.configuration.mods.ArtifactRef;
import net.fabricmc.loom.configuration.mods.JarSplitter;
import net.fabricmc.loom.util.AttributeHelper;

public class ModDependencyFactory {
private static final String TARGET_ATTRIBUTE_KEY = "loom-target";

public static ModDependency create(ArtifactRef artifact, Configuration targetConfig, @Nullable Configuration targetClientConfig, String mappingsSuffix, Project project) {
public static ModDependency create(ArtifactRef artifact, ArtifactMetadata metadata, Configuration targetConfig, @Nullable Configuration targetClientConfig, String mappingsSuffix, Project project) {
if (targetClientConfig != null && LoomGradleExtension.get(project).getSplitModDependencies().get()) {
final Optional<JarSplitter.Target> cachedTarget = readTarget(artifact);
JarSplitter.Target target;
Expand All @@ -53,11 +54,11 @@ public static ModDependency create(ArtifactRef artifact, Configuration targetCon
}

if (target != null) {
return new SplitModDependency(artifact, mappingsSuffix, targetConfig, targetClientConfig, target, project);
return new SplitModDependency(artifact, metadata, mappingsSuffix, targetConfig, targetClientConfig, target, project);
}
}

return new SimpleModDependency(artifact, mappingsSuffix, targetConfig, project);
return new SimpleModDependency(artifact, metadata, mappingsSuffix, targetConfig, project);
}

private static Optional<JarSplitter.Target> readTarget(ArtifactRef artifact) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@
import org.gradle.api.artifacts.Configuration;
import org.jetbrains.annotations.Nullable;

import net.fabricmc.loom.configuration.mods.ArtifactMetadata;
import net.fabricmc.loom.configuration.mods.ArtifactRef;

// Single jar in and out
public final class SimpleModDependency extends ModDependency {
private final Configuration targetConfig;
private final LocalMavenHelper maven;

public SimpleModDependency(ArtifactRef artifact, String mappingsSuffix, Configuration targetConfig, Project project) {
super(artifact, mappingsSuffix, project);
public SimpleModDependency(ArtifactRef artifact, ArtifactMetadata metadata, String mappingsSuffix, Configuration targetConfig, Project project) {
super(artifact, metadata, mappingsSuffix, project);
this.targetConfig = Objects.requireNonNull(targetConfig);
this.maven = createMaven(name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.ModSettings;
import net.fabricmc.loom.configuration.mods.ArtifactMetadata;
import net.fabricmc.loom.configuration.mods.ArtifactRef;
import net.fabricmc.loom.configuration.mods.JarSplitter;

Expand All @@ -47,8 +48,8 @@ public final class SplitModDependency extends ModDependency {
@Nullable
private final LocalMavenHelper clientMaven;

public SplitModDependency(ArtifactRef artifact, String mappingsSuffix, Configuration targetCommonConfig, Configuration targetClientConfig, JarSplitter.Target target, Project project) {
super(artifact, mappingsSuffix, project);
public SplitModDependency(ArtifactRef artifact, ArtifactMetadata metadata, String mappingsSuffix, Configuration targetCommonConfig, Configuration targetClientConfig, JarSplitter.Target target, Project project) {
super(artifact, metadata, mappingsSuffix, project);
this.targetCommonConfig = Objects.requireNonNull(targetCommonConfig);
this.targetClientConfig = Objects.requireNonNull(targetClientConfig);
this.target = Objects.requireNonNull(target);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/net/fabricmc/loom/task/RemapJarTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import net.fabricmc.loom.build.nesting.IncludedJarFactory;
import net.fabricmc.loom.build.nesting.JarNester;
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
import net.fabricmc.loom.configuration.mods.ArtifactMetadata;
import net.fabricmc.loom.extension.MixinExtension;
import net.fabricmc.loom.task.service.TinyRemapperService;
import net.fabricmc.loom.util.Constants;
Expand Down Expand Up @@ -146,6 +147,12 @@ public void run() {
if (mixinAp) {
setupLegacyMixinRefmapRemapping(params);
}

// Add the mixin refmap remap type to the manifest
// This is used by the mod dependency remapper to determine if it should remap the refmap
// or if the refmap should be remapped by mixin at runtime.
final var refmapRemapType = mixinAp ? ArtifactMetadata.RefmapRemapType.MIXIN : ArtifactMetadata.RefmapRemapType.STATIC;
params.getManifestAttributes().put(ArtifactMetadata.MANIFEST_MIXIN_REMAP_TYPE, refmapRemapType.manifestValue());
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import spock.lang.Specification
import net.fabricmc.loom.configuration.mods.ArtifactMetadata
import net.fabricmc.loom.configuration.mods.ArtifactRef

import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.RefmapRemapType.MIXIN
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.RefmapRemapType.STATIC
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.RemapRequirements.*
import static net.fabricmc.loom.test.util.ZipTestUtils.*

Expand Down Expand Up @@ -101,6 +103,22 @@ class ArtifactMetadataTest extends Specification {
false | ["fabric.mod.json": "{}"] // Fabric mod, no installer data
}

def "Refmap remap type" () {
given:
def zip = createZip(entries)
when:
def metadata = createMetadata(zip)
def result = metadata.refmapRemapType()
then:
result == type
where:
type | entries
MIXIN | ["hello.json": "{}"] // None Mod jar
MIXIN | ["fabric.mod.json": "{}"] // Fabric mod without manfiest file
MIXIN | ["fabric.mod.json": "{}", "META-INF/MANIFEST.MF": manifest("Fabric-Loom-Mixin-Remap-Type", "mixin")] // Fabric mod without remap type entry
STATIC | ["fabric.mod.json": "{}", "META-INF/MANIFEST.MF": manifest("Fabric-Loom-Mixin-Remap-Type", "static")] // Fabric mod opt-in
}

private static ArtifactMetadata createMetadata(Path zip) {
return ArtifactMetadata.create(createArtifact(zip))
}
Expand Down
Loading

0 comments on commit 7dcec87

Please sign in to comment.