From f4baaba715b1b546566bd5d8fa2f53767bdd2215 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Sun, 28 Apr 2024 11:20:07 +0200 Subject: [PATCH] Fix handling of multiple AccessTransformers in the same project (#155) --- .../runtime/tasks/AccessTransformer.java | 1 - .../common/util/CommonRuntimeTaskUtils.java | 47 +--- .../userdev/AccessTransformerTests.groovy | 222 ++++++++++++++++++ .../gradle/userdev/FunctionalTests.groovy | 4 +- 4 files changed, 233 insertions(+), 41 deletions(-) create mode 100644 userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/AccessTransformerTests.groovy diff --git a/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/AccessTransformer.java b/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/AccessTransformer.java index 38c5637f9..07642dc4b 100644 --- a/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/AccessTransformer.java +++ b/common/src/main/java/net/neoforged/gradle/common/runtime/tasks/AccessTransformer.java @@ -50,7 +50,6 @@ public AccessTransformer() { @PathSensitive(PathSensitivity.NONE) public abstract RegularFileProperty getInputFile(); - @InputFiles @PathSensitive(PathSensitivity.NONE) public abstract ConfigurableFileCollection getTransformers(); diff --git a/common/src/main/java/net/neoforged/gradle/common/util/CommonRuntimeTaskUtils.java b/common/src/main/java/net/neoforged/gradle/common/util/CommonRuntimeTaskUtils.java index bb803e871..42c765443 100644 --- a/common/src/main/java/net/neoforged/gradle/common/util/CommonRuntimeTaskUtils.java +++ b/common/src/main/java/net/neoforged/gradle/common/util/CommonRuntimeTaskUtils.java @@ -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; @@ -26,52 +27,22 @@ private CommonRuntimeTaskUtils() { } public static TaskProvider createAccessTransformer(Definition definition, String namePreFix, File workspaceDirectory, Consumer> dependentTaskConfigurationHandler, FileTree files, Collection data) { - final Collection> fileProducingTasks = new ArrayList<>(); - final Map 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 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 generator; if (!data.isEmpty()) { - final TaskProvider 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 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); } }); } diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/AccessTransformerTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/AccessTransformerTests.groovy new file mode 100644 index 000000000..8ba916fe6 --- /dev/null +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/AccessTransformerTests.groovy @@ -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 + } +} diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy index cfd6dcaac..928523e65 100644 --- a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy @@ -6,7 +6,6 @@ import org.gradle.testkit.runner.TaskOutcome class FunctionalTests extends BuilderBasedTestSpecification { - @Override protected void configurePluginUnderTest() { pluginUnderTest = "net.neoforged.gradle.userdev"; @@ -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 { @@ -165,4 +164,5 @@ class FunctionalTests extends BuilderBasedTestSpecification { secondRun.task(":neoFormRecompile").outcome == TaskOutcome.FROM_CACHE initialRun.task(":build").outcome == TaskOutcome.SUCCESS } + }