diff --git a/.github/gradle/gradle.gradle b/.github/gradle/gradle.gradle index 9e584e7cd..a29946b3b 100644 --- a/.github/gradle/gradle.gradle +++ b/.github/gradle/gradle.gradle @@ -91,7 +91,7 @@ subprojects.forEach { Project subProject -> it.group = 'infrastructure' it.doLast { - subProject.tasks.withType(Test).forEach { Task test -> + subProject.tasks.withType(Test).forEach { Test test -> def testSourceSetCandidate = test.extensions.findByName('test-source-set') if (testSourceSetCandidate != null) { SourceSet testSourceSet = testSourceSetCandidate as SourceSet @@ -128,7 +128,10 @@ subprojects.forEach { Project subProject -> tests.addAll(createTestRuns(test, testClasses)) } else { - tests.addAll(createTestRuns(test, new ArrayList())) + //This test task is not marked as a filterable test task by our central build.gradle file. + //Check if it has source, if so run it, else skip it. No need to setup gradle to run nothing: + if (!test.getCandidateClassFiles().isEmpty()) + tests.addAll(createTestRuns(test, new ArrayList())) } } diff --git a/common/src/main/java/net/neoforged/gradle/common/runs/ide/IdeRunIntegrationManager.java b/common/src/main/java/net/neoforged/gradle/common/runs/ide/IdeRunIntegrationManager.java index e8e0da639..71b4b29e7 100644 --- a/common/src/main/java/net/neoforged/gradle/common/runs/ide/IdeRunIntegrationManager.java +++ b/common/src/main/java/net/neoforged/gradle/common/runs/ide/IdeRunIntegrationManager.java @@ -382,22 +382,24 @@ private TaskProvider getOrCreateIdeBeforeRunTask(Project project, RunImpl run private List> createIntelliJCopyResourcesTasks(Run run) { final List> copyProcessResources = new ArrayList<>(); for (SourceSet sourceSet : run.getModSources().all().get().values()) { - copyProcessResources.add(setupCopyResourcesForIdea(sourceSet)); + copyProcessResources.add(setupCopyResourcesForIdea(sourceSet, RunsUtil.IdeaCompileType.Production)); } if (run.getIsJUnit().get()) { for (SourceSet sourceSet : run.getUnitTestSources().all().get().values()) { - copyProcessResources.add(setupCopyResourcesForIdea(sourceSet)); + copyProcessResources.add(setupCopyResourcesForIdea(sourceSet, RunsUtil.IdeaCompileType.Test)); } } return copyProcessResources; } - private static @NotNull TaskProvider setupCopyResourcesForIdea(SourceSet sourceSet) { + private static @NotNull TaskProvider setupCopyResourcesForIdea(SourceSet sourceSet, RunsUtil.IdeaCompileType compileType) { final Project sourceSetProject = SourceSetUtils.getProject(sourceSet); - final String taskName = CommonRuntimeUtils.buildTaskName("intelliJCopy", sourceSet.getProcessResourcesTaskName()); + //We need a task per compile type, incase the modder configures the task in one run as a mod source and in the other as a unit test source. + final String taskPrefix = CommonRuntimeUtils.buildTaskName("intelliJCopy", compileType.name()); + final String taskName = CommonRuntimeUtils.buildTaskName(taskPrefix, sourceSet.getProcessResourcesTaskName()); final TaskProvider intelliJResourcesTask; if (sourceSetProject.getTasks().findByName(taskName) != null) { @@ -407,7 +409,7 @@ private List> createIntelliJCopyResourcesTasks(Run run) { intelliJResourcesTask = sourceSetProject.getTasks().register(taskName, Copy.class, task -> { final TaskProvider defaultProcessResources = sourceSetProject.getTasks().named(sourceSet.getProcessResourcesTaskName(), ProcessResources.class); task.from(defaultProcessResources.map(ProcessResources::getDestinationDir)); - task.into(RunsUtil.getRunWithIdeaResourcesDirectory(sourceSet)); + task.into(RunsUtil.getRunWithIdeaResourcesDirectory(sourceSet, compileType)); task.dependsOn(defaultProcessResources); }); 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 9dc28d152..348f5d1ee 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 @@ -607,12 +607,13 @@ public static Provider getRunWithIdeaDirectory(fin return getIdeaModuleOutDirectory(sourceSet, compileType).map(dir -> dir.dir(name)); } - public static Provider getRunWithIdeaResourcesDirectory(final SourceSet sourceSet) { - //When running with idea we forcefully redirect all sourcesets to a directory in build, to prevent issues - //with unit tests started from the gutter -> We can only have a single task, that should run always, regardless of run or sourceset: - final Project project = SourceSetUtils.getProject(sourceSet); - final ProjectLayout buildLayout = project.getLayout(); - return buildLayout.getBuildDirectory().map(dir -> dir.dir("idea").dir("resources").dir(sourceSet.getName())); + public static Provider getRunWithIdeaResourcesDirectory(final SourceSet sourceSet, final IdeaCompileType compileType) { + //We previously used this: + //buildLayout.getBuildDirectory().map(dir -> dir.dir("idea").dir("resources").dir(sourceSet.getName())); + //However this has issues at runtime with FML trying to load the old not interpolated mods.toml etc. + //It works smoothly if a user has an excluded templates directory configured for his templates in process resources however. + //To make it work transparently we switched back to this interpolation mechanic where we write into IDEAs output directory. + return getRunWithIdeaDirectory(sourceSet, compileType, "resources"); } public static Provider getRunWithIdeaClassesDirectory(final SourceSet sourceSet, final IdeaCompileType compileType) { @@ -625,7 +626,7 @@ public static Provider buildRunWithIdeaModClasses( return buildModClasses(compileSourceSets, sourceSet -> { if (isRunWithIdea(sourceSet)) { - final File resourcesDir = getRunWithIdeaResourcesDirectory(sourceSet).get().getAsFile(); + final File resourcesDir = getRunWithIdeaResourcesDirectory(sourceSet, compileType).get().getAsFile(); final File classesDir = getRunWithIdeaClassesDirectory(sourceSet, compileType).get().getAsFile(); return Stream.of(resourcesDir, classesDir); } diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/ConfigurationCacheTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/ConfigurationCacheTests.groovy index 6b5bceb61..bdeb08c33 100644 --- a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/ConfigurationCacheTests.groovy +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/ConfigurationCacheTests.groovy @@ -116,12 +116,12 @@ class ConfigurationCacheTests extends BuilderBasedTestSpecification { } runs { - data { } + clientData { } } afterEvaluate { //We don't care for the error here, we just want to run the task so that the config cache is created - tasks.withType(JavaExec).named('runData') { + tasks.withType(JavaExec).named('runClientData') { ignoreExitValue = true group = 'run' } @@ -145,11 +145,11 @@ class ConfigurationCacheTests extends BuilderBasedTestSpecification { when: def run = project.run { - it.tasks('runData') + it.tasks('runClientData') } then: - run.task(':runData').outcome == TaskOutcome.SUCCESS + run.task(':runClientData').outcome == TaskOutcome.SUCCESS } } diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/MultiProjectTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/MultiProjectTests.groovy index 9f42ddb41..ff8e8d050 100644 --- a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/MultiProjectTests.groovy +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/MultiProjectTests.groovy @@ -93,13 +93,13 @@ class MultiProjectTests extends BuilderBasedTestSpecification { when: def run = rootProject.run { - it.tasks(':main:runData') + it.tasks(':main:runClientData') //We are expecting this test to fail, since there is a mod without any files included so it is fine. it.shouldFail() } then: - run.task(':main:writeMinecraftClasspathData').outcome == TaskOutcome.SUCCESS + run.task(':main:writeMinecraftClasspathClientData').outcome == TaskOutcome.SUCCESS run.output.contains("Error during pre-loading phase: ERROR: File null is not a valid mod file") || run.output.contains("Caused by: net.neoforged.fml.ModLoadingException: Loading errors encountered:") @@ -286,13 +286,13 @@ class MultiProjectTests extends BuilderBasedTestSpecification { when: def run = rootProject.run { - it.tasks(':main:runData') + it.tasks(':main:runClientData') //We are expecting this test to fail, since there is a mod without any files included so it is fine. it.shouldFail() } then: - run.task(':main:writeMinecraftClasspathData').outcome == TaskOutcome.SUCCESS + run.task(':main:writeMinecraftClasspathClientData').outcome == TaskOutcome.SUCCESS run.output.contains("Error during pre-loading phase: ERROR: File null is not a valid mod file") || run.output.contains("Caused by: net.neoforged.fml.ModLoadingException: Loading errors encountered:") diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy index ab8c0709d..d54abf2f4 100644 --- a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy @@ -46,7 +46,7 @@ class RunTests extends BuilderBasedTestSpecification { when: def run = project.run { - it.tasks(':runData') + it.tasks(':runClientData') //We are expecting this test to fail, since there is a mod without any files included so it is fine. it.shouldFail() it.stacktrace() @@ -54,9 +54,8 @@ class RunTests extends BuilderBasedTestSpecification { then: true - run.task(':writeMinecraftClasspathData').outcome == TaskOutcome.SUCCESS - run.output.contains("Error during pre-loading phase: ERROR: File null is not a valid mod file") || - run.output.contains("Caused by: java.io.IOException: Invalid paths argument, contained no existing paths") + run.task(':writeMinecraftClasspathClientData').outcome == TaskOutcome.SUCCESS + run.output.contains("is not a valid mod file") } def "configuring of the configurations after the dependencies block should work"() { @@ -85,7 +84,7 @@ class RunTests extends BuilderBasedTestSpecification { } runs { - data { + clientData { modSource project.sourceSets.main } } @@ -100,15 +99,14 @@ class RunTests extends BuilderBasedTestSpecification { when: def run = project.run { - it.tasks(':runData') + it.tasks(':runClientData') //We are expecting this test to fail, since there is a mod without any files included so it is fine. it.shouldFail() } then: - run.task(':writeMinecraftClasspathData').outcome == TaskOutcome.SUCCESS - run.output.contains("Error during pre-loading phase: ERROR: File null is not a valid mod file") || - run.output.contains("Caused by: java.io.IOException: Invalid paths argument, contained no existing paths") + run.task(':writeMinecraftClasspathClientData').outcome == TaskOutcome.SUCCESS + run.output.contains("is not a valid mod file") } def "runs can be declared before the dependencies block"() {