Skip to content

Commit

Permalink
Fix handling of multiple AccessTransformers in the same project (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
marchermans authored Apr 28, 2024
1 parent 08369c9 commit f4baaba
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public AccessTransformer() {
@PathSensitive(PathSensitivity.NONE)
public abstract RegularFileProperty getInputFile();


@InputFiles
@PathSensitive(PathSensitivity.NONE)
public abstract ConfigurableFileCollection getTransformers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils;
import net.neoforged.gradle.dsl.common.util.GameArtifact;
import net.neoforged.gradle.util.StringCapitalizationUtils;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.EmptyFileVisitor;
import org.gradle.api.file.FileTree;
import org.gradle.api.file.FileVisitDetails;
Expand All @@ -26,52 +27,22 @@ private CommonRuntimeTaskUtils() {
}

public static TaskProvider<? extends AccessTransformer> createAccessTransformer(Definition<?> definition, String namePreFix, File workspaceDirectory, Consumer<TaskProvider<? extends Runtime>> dependentTaskConfigurationHandler, FileTree files, Collection<String> data) {
final Collection<TaskProvider<? extends WithOutput>> fileProducingTasks = new ArrayList<>();
final Map<String, Integer> indexes = new HashMap<>();

files.visit(new EmptyFileVisitor() {
@Override
public void visitFile(@NotNull FileVisitDetails fileDetails) {
indexes.compute(fileDetails.getName(), (s, index) -> index == null ? 0 : index + 1);
final int index = indexes.get(fileDetails.getName());

final String name = CommonRuntimeUtils.buildTaskName(definition.getSpecification(), namePreFix + "AccessTransformerProvider" + fileDetails.getName() + (index == 0 ? "" : "_" + index));

final TaskProvider<? extends WithOutput> provider = definition.getSpecification().getProject().getTasks().register(name, ArtifactProvider.class, task -> {
task.getInputFiles().from(
files.matching(f -> f.include(fileDetails.getPath()))
);
String outputFileName = fileDetails.getName();
if (index > 0) {
int extensionDot = outputFileName.lastIndexOf('.');
if (extensionDot == -1) {
outputFileName += "_" + index;
} else {
outputFileName = outputFileName.substring(0, extensionDot) + "_" + index + outputFileName.substring(extensionDot);
}
}
task.getOutputFileName().set(outputFileName);
task.getOutput().set(new File(workspaceDirectory, "accesstransformers/" + namePreFix + "/" + outputFileName));
});

fileProducingTasks.add(provider);
}
});

final TaskProvider<AccessTransformerFileGenerator> generator;
if (!data.isEmpty()) {
final TaskProvider<AccessTransformerFileGenerator> generator = definition.getSpecification().getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(definition.getSpecification(), namePreFix + "AccessTransformerGenerator"), AccessTransformerFileGenerator.class, task -> {
generator = definition.getSpecification().getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(definition.getSpecification(), namePreFix + "AccessTransformerGenerator"), AccessTransformerFileGenerator.class, task -> {
task.getOutput().set(new File(workspaceDirectory, "accesstransformers/" + namePreFix + "/_script-access-transformer.cfg"));
task.getAdditionalTransformers().set(data);
});
dependentTaskConfigurationHandler.accept(generator);
fileProducingTasks.add(generator);
} else {
generator = null;
}

return definition.getSpecification().getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(definition.getSpecification(), String.format("apply%sAccessTransformer", StringCapitalizationUtils.capitalize(namePreFix))), AccessTransformer.class, task -> {
for (TaskProvider<? extends WithOutput> fileRemapTask : fileProducingTasks) {
task.getTransformers().from(fileRemapTask.flatMap(WithOutput::getOutput));
task.dependsOn(fileRemapTask);
task.getTransformers().from(files);
if (generator != null) {
task.getTransformers().from(generator.flatMap(WithOutput::getOutput));
task.dependsOn(generator);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
package net.neoforged.gradle.userdev

import net.neoforged.trainingwheels.gradle.functional.BuilderBasedTestSpecification
import org.gradle.testkit.runner.TaskOutcome

class AccessTransformerTests extends BuilderBasedTestSpecification {

@Override
protected void configurePluginUnderTest() {
pluginUnderTest = "net.neoforged.gradle.userdev";
injectIntoAllProject = true;
}

def "the userdev runtime supports loading ats from a file"() {
given:
def project = create("userdev_supports_ats_from_file", {
it.build("""
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
dependencies {
implementation 'net.neoforged:neoforge:+'
}
""")
it.file("src/main/resources/META-INF/accesstransformer.cfg", """public-f net.minecraft.client.Minecraft fixerUpper # fixerUpper""")
it.file("src/main/java/net/neoforged/gradle/userdev/FunctionalTests.java", """
package net.neoforged.gradle.userdev;
import net.minecraft.client.Minecraft;
public class FunctionalTests {
public static void main(String[] args) {
System.out.println(Minecraft.getInstance().fixerUpper.getClass().toString());
}
}
""")
it.withToolchains()
})

when:
def initialRun = project.run {
it.tasks('build')
}

then:
initialRun.task(":neoFormRecompile").outcome == TaskOutcome.SUCCESS
initialRun.task(":build").outcome == TaskOutcome.SUCCESS
}

def "the userdev runtime supports loading ats from the script"() {
given:
def project = create("userdev_supports_ats_in_scripts", {
it.build("""
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
minecraft.accessTransformers.entry 'public-f net.minecraft.client.Minecraft fixerUpper # fixerUpper'
dependencies {
implementation 'net.neoforged:neoforge:+'
}
""")
it.file("src/main/java/net/neoforged/gradle/userdev/FunctionalTests.java", """
package net.neoforged.gradle.userdev;
import net.minecraft.client.Minecraft;
public class FunctionalTests {
public static void main(String[] args) {
System.out.println(Minecraft.getInstance().fixerUpper.getClass().toString());
}
}
""")
it.withToolchains()
})

when:
def initialRun = project.run {
it.tasks('build')
}

then:
initialRun.task(":neoFormRecompile").outcome == TaskOutcome.SUCCESS
initialRun.task(":build").outcome == TaskOutcome.SUCCESS
}

def "the userdev runtime supports loading ats from the script and the file"() {
given:
def project = create("userdev_supports_ats_in_script_and_file", {
it.build("""
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
minecraft.accessTransformers.entry 'public-f net.minecraft.client.Minecraft LOGGER # LOGGER'
dependencies {
implementation 'net.neoforged:neoforge:+'
}
""")
it.file("src/main/resources/META-INF/accesstransformer.cfg", """public-f net.minecraft.client.Minecraft fixerUpper # fixerUpper""")
it.file("src/main/java/net/neoforged/gradle/userdev/FunctionalTests.java", """
package net.neoforged.gradle.userdev;
import net.minecraft.client.Minecraft;
public class FunctionalTests {
public static void main(String[] args) {
System.out.println(Minecraft.getInstance().fixerUpper.getClass().toString());
System.out.println(Minecraft.LOGGER.getClass().toString());
}
}
""")
it.withToolchains()
})

when:
def initialRun = project.run {
it.tasks('build')
}

then:
initialRun.task(":neoFormRecompile").outcome == TaskOutcome.SUCCESS
initialRun.task(":build").outcome == TaskOutcome.SUCCESS
}

def "the userdev runtime supports loading ats from multiple files"() {
given:
def project = create("userdev_supports_ats_in_multiple_distinctly_named_files", {
it.build("""
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer2.cfg')
dependencies {
implementation 'net.neoforged:neoforge:+'
}
""")
it.file("src/main/resources/META-INF/accesstransformer.cfg", """public-f net.minecraft.client.Minecraft fixerUpper # fixerUpper""")
it.file("src/main/resources/META-INF/accesstransformer2.cfg", """public-f net.minecraft.client.Minecraft LOGGER # LOGGER""")
it.file("src/main/java/net/neoforged/gradle/userdev/FunctionalTests.java", """
package net.neoforged.gradle.userdev;
import net.minecraft.client.Minecraft;
public class FunctionalTests {
public static void main(String[] args) {
System.out.println(Minecraft.getInstance().fixerUpper.getClass().toString());
System.out.println(Minecraft.LOGGER.getClass().toString());
}
}
""")
it.withToolchains()
})

when:
def initialRun = project.run {
it.tasks('build')
}

then:
initialRun.task(":neoFormRecompile").outcome == TaskOutcome.SUCCESS
initialRun.task(":build").outcome == TaskOutcome.SUCCESS
}

def "the userdev runtime supports loading ats from multiple files named the same in different directories"() {
given:
def project = create("userdev_supports_ats_in_files_named_the_same", {
it.build("""
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
minecraft.accessTransformers.file rootProject.file('src/main/resources/accesstransformer.cfg')
dependencies {
implementation 'net.neoforged:neoforge:+'
}
""")
it.file("src/main/resources/META-INF/accesstransformer.cfg", """public-f net.minecraft.client.Minecraft fixerUpper # fixerUpper""")
it.file("src/main/resources/accesstransformer.cfg", """public-f net.minecraft.client.Minecraft LOGGER # LOGGER""")
it.file("src/main/java/net/neoforged/gradle/userdev/FunctionalTests.java", """
package net.neoforged.gradle.userdev;
import net.minecraft.client.Minecraft;
public class FunctionalTests {
public static void main(String[] args) {
System.out.println(Minecraft.getInstance().fixerUpper.getClass().toString());
System.out.println(Minecraft.LOGGER.getClass().toString());
}
}
""")
it.withToolchains()
})

when:
def initialRun = project.run {
it.tasks('build')
}

then:
initialRun.task(":neoFormRecompile").outcome == TaskOutcome.SUCCESS
initialRun.task(":build").outcome == TaskOutcome.SUCCESS
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.gradle.testkit.runner.TaskOutcome

class FunctionalTests extends BuilderBasedTestSpecification {


@Override
protected void configurePluginUnderTest() {
pluginUnderTest = "net.neoforged.gradle.userdev";
Expand Down Expand Up @@ -117,7 +116,7 @@ class FunctionalTests extends BuilderBasedTestSpecification {

def "the userdev runtime by default supports the build cache"() {
given:
def project = create("compile_with_gradle_and_official_mappings", {
def project = create("userdev_supports_loading_from_buildcache", {
it.build("""
java {
toolchain {
Expand Down Expand Up @@ -165,4 +164,5 @@ class FunctionalTests extends BuilderBasedTestSpecification {
secondRun.task(":neoFormRecompile").outcome == TaskOutcome.FROM_CACHE
initialRun.task(":build").outcome == TaskOutcome.SUCCESS
}

}

0 comments on commit f4baaba

Please sign in to comment.