Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle - Capturing output written to out / err on a per task basis

Tags:

gradle

I'm trying to capture output written from each task as it is executed. The code below works as expected when running Gradle with --max-workers 1, but when multiple tasks are running in parallel this code below picks up output written from other tasks running simultaneously.

The API documentation states the following about the "getLogging" method on Task. From what it says I judge that it should support capturing output from single tasks regardless of any other tasks running at the same time.

getLogging() Returns the LoggingManager which can be used to control the logging level and standard output/error capture for this task. https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html

graph.allTasks.forEach { Task task ->
    task.ext.capturedOutput = [ ]

    def listener = { task.capturedOutput << it } as StandardOutputListener

    task.logging.addStandardErrorListener(listener)
    task.logging.addStandardOutputListener(listener)

    task.doLast {
        task.logging.removeStandardOutputListener(listener)
        task.logging.removeStandardErrorListener(listener)
    }
}

Have I messed up something in the code above or should I report this as a bug?

like image 891
Kimble Avatar asked Jul 20 '15 17:07

Kimble


People also ask

Why is Gradle task skipped?

If the task must be skipped, the result of the closure must be false , otherwise the task is executed. The task object is passed as a parameter to the closure. Gradle evaluates the closure just before the task is executed.

How do I disable task in Gradle?

You can disable the long-lived Gradle daemon via the --no-daemon command-line option, or by adding org. gradle. daemon=false to your gradle. properties file.


1 Answers

It looks like every LoggingManager instance shares an OutputLevelRenderer, which is what your listeners eventually get added to. This did make me wonder why you weren't getting duplicate messages because you're attaching the same listeners to the same renderer over and over again. But it seems the magic is in BroadcastDispatch, which keeps the listeners in a map, keyed by the listener object itself. So you can't have duplicate listeners.

Mind you, for that to hold, the hash code of each listener must be the same, which seems surprising. Anyway, perhaps this is working as intended, perhaps it isn't. It's certainly worth an issue to get some clarity on whether Gradle should support listeners per task. Alternatively raise it on the dev mailing list.

like image 73
Peter Ledbrook Avatar answered Nov 09 '22 05:11

Peter Ledbrook