How to determine which configurations will be resolved when the task runs?

I would like to find all SNAPSHOT dependencies resolved for all configurations.
I created a Gradle plugin for this purpose that iterates over all resolvable project.configurations and passes to configuration.incoming.afterResolve method a logic for finding SNAPSHOTS. But the problem is that I can’t determine when the last configuration.incoming.afterResolve method will be invoked. Collection project.configurations.filter { canBeResolved(it)} has more elements than configurations will be resolved.
Is there a way to determine which configurations will be resolved when a task runs?
The idea is to get all tasks from dependency graph with project.gradle.taskGraph.allTasks then find all configurations for tasks containing *compile* in name and then for such configurations invoke configuration.incoming.afterResolve

Is there a way to determine which configurations will be resolved when a task runs?

Not really, or at least not that I’m aware of.
Why do you want that?
What is the problem with adding the afterResolve action to all resolvable configuration (or even to all configurations)?

I added an action to all resolvable configuration and collected all SNAPSHOT’s, but I need a condition that signals that there won’t be more afterResolve invocations in order to throw exception with an information about all SNAPSHOT’s. Currently, I add an action to the last task, but is there a guarantee that this task will be executed?

project.gradle.taskGraph.whenReady {           
    project.gradle.taskGraph.allTasks[project.gradle.taskGraph.allTasks.size - 1].doLast { ... }
}

I found one more strange behavior: not all tasks will be executed from project.gradle.taskGraph.allTasks. Why does this happen? Which task will be executed last?

You never know.
And you shouldn’t try something like that.
Especially if you ever want to be compatible with configuration cache.
I think that you would do is either:

  • create a shared build service
  • collect the information in that build service
  • make the service implement AutoCloseable and do the reporting in the close method
  • make the service implement OperationCompletionListener
  • register the service as OperationCompletionListener, that makes sure it gets closed between the last task being executed and the end of the build

Alternatively you could probably use the new flow scope API to do something at the end of the build.