Applying the Gradle plugin causes the `run` task to be `UP-TO-DATE`
Describe the bug
Usually the run task as provided by Gradle's application plugin is never UP-TO-DATE by design as the task defines no outputs. However, applying the org.graalvm.buildtools.native in version 0.10.6 seems to add a JVM argument provider that defined an output directory, making the run task capable of being UP-TO-DATE, and subsequent run task executions do not actually run the application.
To Reproduce
- Checkout https://github.com/sschuberth/stan.
- Run
./gradlew :cli:run --args="--help". - Run
./gradlew :cli:run --args="--help"again.
Expected behavior
Help output should be shown in both steps 2. and 3., but it is only shown in step 2. as step 3. is UP-TO-DATE.
System Info (please complete the following information):
- OS: Linux
- GraalVM Version Oracle GraalVM 24+36.1
- Java Version 21
- Plugin version 0.10.6
Additional context
I'm not so sure whether this should be considered a bug.
A run task could well be up-to-date or even cacheable, for example if it processes some inputs to some outputs and rerunning would just produce the same result, it would be fully expected that the task is up-to-date and cacheable.
If then this plugin adds an output to the task, the task should be out-of-date if it changed or vanished and also cache that output alongside if the task is cacheable.
If it would not add the output to the task, that would actually be a bug and a more serious one.
And I don't think the plugin can determine reliably whether the task will be up-to-dateable / cacheable without adding that output and conditionally only add it then.
It can also be "fixed" consumer-side by either configuring the run task to not track state using
tasks.run.configure {
doNotTrackState("The task is not supposed to be UP-TO-DATE.")
}
or by excluding the task from instrumentation by this plugin if appropriate using
graalvmNative {
agent {
tasksToInstrumentPredicate = Predicate { name != "run" }
}
}
if it processes some inputs to some outputs and rerunning would just produce the same result, it would be fully expected that the task is up-to-date and cacheable.
True, but that's something only the application itself can say, not a generic plugin that can be applied to any application, which could be interactive and do different things on each run based on user input (or similar environment changes).
Exactly.
The plugin is only adding its output do the task which seems to be appropriate, otherwise up-to-date checks are wrong and the cache will be poisoned with wrong entries if the task is made up-to-dateable / cacheable by a consumer for this plugin.
You as the one controlling what the run task is doing needs to make sure the task is not up-to-dateable by declaring it doNotTrackState.
🤷♂️
I guess there is no perfect solution to this but declaring the output is the less harmful / dangerous way.
You as the one controlling what the
runtask is doing needs to make sure the task is not up-to-dateable by declaring itdoNotTrackState.
I believe it should rather the opposite, "opt-in"-like: This plugin should not change the default behavior of the run task WRT being up-to-dateable.
And actually, agent output should only be written to stan/cli/build/native/agent-output/run if the tracing agent is enabled. So if it's disabled, no task output should be declared.
I would have to check since I didn't look into this code for a while, but I think it adds an output so that the tasks which depend on the agent run are wired properly. Without this, the task will not be executed if a task which depends on it is requested.
For the record, this issue causes several side effects, e.g. this in IntelliJ IDEA.
Sounds like a regression, because I'm pretty sure we discussed this with the IDEA folks a few years back when I was working at Gradle, so that they inject a random seed.
Would be good if you could add that comment as well to the linked issue, @melix!