Open Hubry opened 2 years ago
This seems to be caused by our registration of the run configuration-related tasks[^runtasks] during a Gradle#projectsEvaluated
listener, which causes Gradle to not find the task when trying to execute.
Take the following example:
tasks.create("task1") { group 'boop' }
afterEvaluate {
tasks.create("task2") { group 'boop' }
gradle.projectsEvaluated {
tasks.create("task3") { group 'boop' }
}
}
When running tasks
to list out all tasks, all three tasks appear as expected. Yet running the last task, task3
, while configuration on demand is enabled causes a build failure as Gradle cannot find the task, even though the first two tasks run successfully.
According to @OrionDevelopment[^orion], this is because the "task tree evaluation happens in practice immediately after project evaluation, but before the afterEvaluate
blocks run."
In ForgeGradle, we register our run config-related tasks in both userdev and patcherdev plugins by calling the Utils#createRunConfigTasks
method from within a Project#afterEvaluate
block (the area for task2
's registration above), which itself calls RunConfigGenerator#createIDEGenRunsTasks
from withn a Gradle#projectsEvaluated
block (the area for task3
's registration above) as well as registering the tasks for each RunConfig
through successive calls to RunConfigGenerator#createRunTask
.
This means that when configuration on demand is enabled, as seen in the example above, the run config-related tasks will fail to run due to them seemingly being nonexistent to Gradle.
Fixing this seems to be non-trivial -- the 'ideal' solution would be to modify RunConfig
to be lazy and use Property
s, so they can be plugged into tasks lazily, but that involves understanding and replicating in some fashion the confusing mess that is RunConfig
's merging system (which I have yet to figure out).
@OrionDevelopment's suggestion to fixing it would be to register the tasks as early as possible -- when the run configs are registered to their containers -- then using 'configuration tasks' which run before each run config task and configure them according to the RunConfig
's information. That seems more plausible[^plausible], though someone will need to try implement that suggestion to see any possibly shortcomings or limitations.
This issue seems related to https://github.com/gradle/gradle/issues/9489, which also relates to task execution troubles with configuration on demand and Gradle#projectsEvaluated
.
[^runtasks]: The prepare*
and run*
tasks for each RunConfig
, as well as the IDE run generation tasks -- genEclipseRuns
, genIntellijRuns
, and genVSCodeRuns
.
[^orion]: Taken from a discussion in Forgecord's #gradle
channel.
[^plausible]: Insofar that it requires less refactoring and breaking changes than refactoring the whole RunConfig
system.
If
org.gradle.configureondemand=true
is present ingradle.properties
, or if running the task with--configure-on-demand
, running theprepareRunClient
or any similar task in a multiproject setup will fail, saying that the task was not found in the project. This blocks running the game through Gradle, as the run tasks require these tasks.Tested with FG 5.1.+ and Gradle 7.3.3.
Reporting at Sci's request on discord.