From 86d5cc18126faa081381cc8a3082090853456ed7 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Sun, 22 Sep 2024 10:39:42 +0200 Subject: [PATCH] Fix the LCP writer not properly de-duplicating dependencies because it was directly adding them to a CFC, instead of through a config. --- .../gradle/common/util/run/RunsUtil.java | 18 +++++++-------- .../definition/UserDevRuntimeDefinition.java | 23 ++++++++++++++----- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/net/neoforged/gradle/common/util/run/RunsUtil.java b/common/src/main/java/net/neoforged/gradle/common/util/run/RunsUtil.java index a6d75f6c6..142c7a376 100644 --- a/common/src/main/java/net/neoforged/gradle/common/util/run/RunsUtil.java +++ b/common/src/main/java/net/neoforged/gradle/common/util/run/RunsUtil.java @@ -50,9 +50,7 @@ import java.util.List; import java.util.Locale; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; -import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -63,8 +61,8 @@ private RunsUtil() { throw new IllegalStateException("Tried to create utility class!"); } - public static String createTaskName(final String prefix, final Run run) { - return createTaskName(prefix, run.getName()); + public static String createNameFor(final String prefix, final Run run) { + return createNameFor(prefix, run.getName()); } public static void configure(Project project, Run run, boolean isInternal) { @@ -91,7 +89,7 @@ public static void registerPostSyncTasks(Project project, Run run) { public static void createTasks(Project project, Run run) { if (!run.getIsJUnit().get()) { //Create run exec tasks for all non-unit test runs - project.getTasks().register(createTaskName(run.getName()), JavaExec.class, runExec -> { + project.getTasks().register(createNameFor(run.getName()), JavaExec.class, runExec -> { runExec.setDescription("Runs the " + run.getName() + " run."); runExec.setGroup("NeoGradle/Runs"); @@ -220,7 +218,7 @@ public static void setupRenderDocSupport(Project project, Run run) { throw new InvalidUserDataException("RenderDoc can only be enabled for client runs."); final RenderDocTools renderDocTools = project.getExtensions().getByType(Subsystems.class).getTools().getRenderDoc(); - final TaskProvider setupRenderDoc = project.getTasks().register(RunsUtil.createTaskName("setupRenderDoc", run), RenderDocDownloaderTask.class, renderDoc -> { + final TaskProvider setupRenderDoc = project.getTasks().register(RunsUtil.createNameFor("setupRenderDoc", run), RenderDocDownloaderTask.class, renderDoc -> { renderDoc.getRenderDocVersion().set(renderDocTools.getRenderDocVersion()); renderDoc.getRenderDocOutputDirectory().set(renderDocTools.getRenderDocPath().dir("download")); renderDoc.getRenderDocInstallationDirectory().set(renderDocTools.getRenderDocPath().dir("installation")); @@ -347,7 +345,7 @@ private static void createOrReuseTestTask(Project project, String name, Run run) private static void createNewTestTask(Project project, String name, Run run) { //Create a test task for unit tests - TaskProvider newTestTask = project.getTasks().register(createTaskName("test", name), Test.class); + TaskProvider newTestTask = project.getTasks().register(createNameFor("test", name), Test.class); configureTestTask(project, newTestTask, run); project.getTasks().named("check", check -> check.dependsOn(newTestTask)); } @@ -663,11 +661,11 @@ public static Provider buildModClasses(final Provider minecraftClasspathSerializer = getSpecification().getProject().getTasks().register( - RunsUtil.createTaskName("writeMinecraftClasspath", run), + RunsUtil.createNameFor("writeMinecraftClasspath", run), ClasspathSerializer.class, task -> { - this.additionalUserDevDependencies.getExtendsFrom().forEach(task.getInputFiles()::from); - task.getInputFiles().from(this.additionalUserDevDependencies); - task.getInputFiles().from(neoformRuntimeDefinition.getMinecraftDependenciesConfiguration()); + final Configuration lcpConfiguration = ConfigurationUtils.temporaryConfiguration(getSpecification().getProject(), + RunsUtil.createNameFor("lcp", run)); + + lcpConfiguration.extendsFrom(neoformRuntimeDefinition.getMinecraftDependenciesConfiguration()); + lcpConfiguration.extendsFrom(this.additionalUserDevDependencies); + lcpConfiguration.extendsFrom(run.getDependencies().getRuntimeConfiguration()); + + //We depend on the configuration, this ensures that if we have dependencies with different versions in the + //dependency tree they are resolved to one version and are not added with different versions to the ConfigurableFileCollection + //on the input files. + //Additionally, we need to directly depend on the output file of the userdevClasspathElementProducer, we can not convert + //this to a dependency because it would be a transform of a configurable file collection that holds the output of the task + //which requires running that task, which would be a cyclic dependency. + //This is a workaround to ensure that the path to the userdev classpath element is resolved correctly. + //And added to the LCP, as we are now not transforming the CFC created from the output (we are not even creating a CFC) + task.getInputFiles().from(lcpConfiguration); task.getInputFiles().from(this.userdevClasspathElementProducer.flatMap(WithOutput::getOutput)); - task.getInputFiles().from(run.getDependencies().getRuntimeConfiguration()); } ); configureAssociatedTask(minecraftClasspathSerializer);