Skip to content

Commit cb2ea7e

Browse files
authored
Fix Mixin Remapping for reobf tasks added by users (#197)
1 parent b4e5b7c commit cb2ea7e

File tree

5 files changed

+74
-17
lines changed

5 files changed

+74
-17
lines changed

LEGACY.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,22 @@ neoForge {
4444
## Reobfuscating artifacts
4545
Forge used SRG mappings as intermediary mappings in 1.20.1 and below. While your mod is developed against the mappings provided
4646
by Mojang (known as official mappings), you need to reobfuscate it to SRG mappings for it to work in production.
47-
Reobfuscation will automatically be configured for the `jar` task; the non-obfuscated jar will have a `-dev` classifier
47+
Reobfuscation will automatically be configured for the `jar` task; the non-obfuscated jar will be moved to `build/devlibs`
4848
and will not be published in favour of the reobfuscated variant. You should upload the `reobfJar` task's output when using a
49-
task to upload to a mod hosting platform, or otherwise the jar without a `-dev` classifier if you're uploading it manually.
49+
task to upload to a mod hosting platform.
50+
51+
You may reobfuscate other jar tasks using `obfuscation.reobfuscate(TaskProvider<AbstractArchiveTask>, SourceSet, Action<RemapJarTask>)`.
5052

51-
You may reobfuscate other jar tasks using `obfuscation.reobfuscate(TaskProvider<AbstractArchiveTask>, SourceSet, Action<RemapJarTask>)`.
5253
For instance, if you want to reobfuscate a `shadowJar` task:
5354
```groovy
5455
shadowJar {
55-
// Change the classifier of the shadow jar to be -dev-all as it's not mapped in intermediary and not usable for production
56-
archiveClassifier = 'dev-all'
56+
archiveClassifier = 'all'
5757
}
5858
5959
obfuscation {
6060
// Reobfuscate the shadowJar task, using the classpath of the main sourceset for properly remapping inherited members
61-
reobfuscate(tasks.named('shadowJar'), sourceSets.main) {
62-
// Make the reobfuscated shadowJar have the all classifier
63-
// You could also change it to an empty string if you want it to not have a classifier (in that case, you will also need to change the classifier of the slim `reobfJar` task
64-
archiveClassifier = 'all'
65-
}
61+
// This will place the original shadow jar in build/devlibs while putting this reobfuscated version in build/libs
62+
reobfuscate(tasks.named('shadowJar'), sourceSets.main)
6663
}
6764
```
6865

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ sourceSets {
7171
runtimeClasspath += java8.output
7272
}
7373
legacy
74+
test {
75+
compileClasspath += legacy.output
76+
runtimeClasspath += legacy.output
77+
}
7478
}
7579

7680
configurations {

src/legacy/java/net/neoforged/moddevgradle/legacyforge/dsl/Obfuscation.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.gradle.api.artifacts.FileCollectionDependency;
1212
import org.gradle.api.artifacts.ProjectDependency;
1313
import org.gradle.api.component.AdhocComponentWithVariants;
14+
import org.gradle.api.file.FileCollection;
1415
import org.gradle.api.file.RegularFile;
1516
import org.gradle.api.plugins.JavaPlugin;
1617
import org.gradle.api.provider.Provider;
@@ -28,18 +29,21 @@ public abstract class Obfuscation {
2829
private final Provider<RegularFile> mappingsCsv;
2930
private final Configuration autoRenamingToolRuntime;
3031
private final Configuration installerToolsRuntime;
32+
private final FileCollection extraMixinMappings;
3133

3234
@Inject
3335
public Obfuscation(Project project,
3436
Provider<RegularFile> officialToSrg,
3537
Provider<RegularFile> mappingsCsv,
3638
Configuration autoRenamingToolRuntime,
37-
Configuration installerToolsRuntime) {
39+
Configuration installerToolsRuntime,
40+
FileCollection extraMixinMappings) {
3841
this.project = project;
3942
this.officialToSrg = officialToSrg;
4043
this.mappingsCsv = mappingsCsv;
4144
this.autoRenamingToolRuntime = autoRenamingToolRuntime;
4245
this.installerToolsRuntime = installerToolsRuntime;
46+
this.extraMixinMappings = extraMixinMappings;
4347
}
4448

4549
@ApiStatus.Internal
@@ -56,6 +60,17 @@ public void configureSrgToNamedOperation(RemapOperation operation) {
5660
operation.getMappings().from(mappingsCsv);
5761
}
5862

63+
/**
64+
* Create a reobfuscation task.
65+
*
66+
* @param jar the jar task to reobfuscate
67+
* @param sourceSet the source set whose classpath to use when remapping inherited methods
68+
* @return a provider of the created task
69+
*/
70+
public TaskProvider<RemapJar> reobfuscate(TaskProvider<? extends AbstractArchiveTask> jar, SourceSet sourceSet) {
71+
return reobfuscate(jar, sourceSet, ignored -> {});
72+
}
73+
5974
/**
6075
* Create and configure a reobfuscation task.
6176
*
@@ -77,6 +92,7 @@ public TaskProvider<RemapJar> reobfuscate(TaskProvider<? extends AbstractArchive
7792
task.getArchiveAppendix().convention(jar.flatMap(AbstractArchiveTask::getArchiveAppendix));
7893
task.getLibraries().from(sourceSet.getCompileClasspath());
7994
configureNamedToSrgOperation(task.getRemapOperation());
95+
task.getRemapOperation().getMappings().from(extraMixinMappings);
8096
configuration.execute(task);
8197
});
8298

src/legacy/java/net/neoforged/moddevgradle/legacyforge/internal/LegacyForgeModDevPlugin.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,10 @@ public void apply(Project project) {
6666
var intermediateToNamed = modDevBuildDir.map(d -> d.file("intermediateToNamed.srg"));
6767
var mappingsCsv = modDevBuildDir.map(d -> d.file("intermediateToNamed.zip"));
6868

69-
var obf = project.getExtensions().create("obfuscation", Obfuscation.class, project, namedToIntermediate, mappingsCsv, autoRenamingToolRuntime, installerToolsRuntime);
70-
69+
// This collection is used to share the files added by mixin with the obfuscation extension
7170
var extraMixinMappings = project.files();
71+
72+
var obf = project.getExtensions().create("obfuscation", Obfuscation.class, project, namedToIntermediate, mappingsCsv, autoRenamingToolRuntime, installerToolsRuntime, extraMixinMappings);
7273
var mixin = project.getExtensions().create("mixin", MixinExtension.class, project, namedToIntermediate, extraMixinMappings);
7374

7475
project.getExtensions().configure(NeoForgeExtension.class, extension -> {
@@ -92,10 +93,7 @@ public void apply(Project project) {
9293

9394
var reobfJar = obf.reobfuscate(
9495
project.getTasks().named(JavaPlugin.JAR_TASK_NAME, Jar.class),
95-
project.getExtensions().getByType(SourceSetContainer.class).getByName(SourceSet.MAIN_SOURCE_SET_NAME),
96-
task -> {
97-
task.getRemapOperation().getMappings().from(extraMixinMappings);
98-
}
96+
project.getExtensions().getByType(SourceSetContainer.class).getByName(SourceSet.MAIN_SOURCE_SET_NAME)
9997
);
10098

10199
project.getTasks().named("assemble", assemble -> assemble.dependsOn(reobfJar));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package net.neoforged.moddevgradle.legacyforge.dsl;
2+
3+
import net.neoforged.moddevgradle.internal.utils.ExtensionUtils;
4+
import net.neoforged.moddevgradle.legacyforge.internal.LegacyForgeModDevPlugin;
5+
import net.neoforged.moddevgradle.legacyforge.tasks.RemapJar;
6+
import org.gradle.jvm.tasks.Jar;
7+
import org.gradle.testfixtures.ProjectBuilder;
8+
import org.junit.jupiter.api.Test;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
class MixinMappingTest {
13+
/**
14+
* Tests that we expect the Mixin AP to create for each refmap is added to the reobfuscation tasks
15+
* (both the default reobfJar and custom ones).
16+
*/
17+
@Test
18+
public void testMixinMappingsArePropagatedToObfuscationTasks() {
19+
var project = ProjectBuilder.builder().build();
20+
project.getPlugins().apply(LegacyForgeModDevPlugin.class);
21+
22+
var obfuscation = ExtensionUtils.getExtension(project, "obfuscation", Obfuscation.class);
23+
var sourceSets = ExtensionUtils.getSourceSets(project);
24+
var mixinExtension = ExtensionUtils.getExtension(project, "mixin", MixinExtension.class);
25+
var mainSourceSet = sourceSets.getByName("main");
26+
mixinExtension.add(mainSourceSet, "testmod.refmap.json");
27+
28+
var someJarTask = project.getTasks().register("someJar", Jar.class);
29+
var customRemapJarTask = obfuscation.reobfuscate(someJarTask, mainSourceSet).get();
30+
var remapJarTask = (RemapJar) project.getTasks().getByName("reobfJar");
31+
32+
// The main named->intermediary mappings for the game
33+
var namedToIntermediary = project.getLayout().getBuildDirectory().file("moddev/namedToIntermediate.tsrg").get().getAsFile();
34+
var mixinApMappings = project.getLayout().getBuildDirectory().file("mixin/testmod.refmap.json.mappings.tsrg").get().getAsFile();
35+
36+
// The mapping file produced by the Mixin AP should be added as an input to both Jar tasks.
37+
var otherMappings = customRemapJarTask.getRemapOperation().getMappings().getFiles();
38+
assertThat(otherMappings).containsOnly(namedToIntermediary, mixinApMappings);
39+
var mappings = remapJarTask.getRemapOperation().getMappings().getFiles();
40+
assertThat(mappings).containsOnly(namedToIntermediary, mixinApMappings);
41+
}
42+
}

0 commit comments

Comments
 (0)