The correct way for a custom plugin to output colored/styled text to the gradle logging system?


(Matias Bjarland) #1

I would like to do some progress reporting from my custom plugin. To make things readable I would like to use the existing gradle console colorization facilities. I would like to also make use of the gradle-built-in functionality of detecting that the calling terminal/process/daemon actually supports this colored output and just output non-colored text if not (assuming I have read the source correctly and this is indeed what gradle is doing : )

I have the following test snippet in my custom task:

private void thisIsATest() {
    if (!System.env['USECOLOR']) {
      return
    }
    StyledTextOutput o = services.get(StyledTextOutputFactory).create(MyTask)
      o.withStyle(Style.Error).println("Hello World")
    o.withStyle(Style.Description).println("Hello World")
    o.withStyle(Style.UserInput).println("Hello World")
  }
    @TaskAction
  def someMethod() {
    thisIsATest()
    }

this works if called from an actual build where I set the system variable to force the method to run, but blocks indefinitely when called from a spock/junit test. If I don’t set the system variable the unit test completes fine (I stuck the system variable there just so I would be able to hack my way to testing an actual build).

So my question is: is this the correct way to output styled text from a custom plugin? If so, would you have any pointers on how to deal with the blocking unit test situation?

Any help much appreciated!


(Adam Murdoch) #2

There’s no public interface for doing this yet. It would be a good thing for us to support at some point, though.

If you’re happy to use internal interfaces that may change at any time, then you have 2 options: * Use ‘ProgressLoggerFactory’ to create a ‘ProgressLogger’. * Use ‘StyledTextFactory’ as above.

‘ProgressLogger’ has the advantage of being higher-level. For example, progress events travel out through the tooling API to be shown in the IDE, in addition to being shown in the status bar at the bottom. The implementation also takes care of logging different stuff when the dynamic console is not available. We’re also thinking of adding some support to the profile report for events tracked through the ‘ProgressLogger’.

As far as the stuck test goes, can you run ‘jstack’ on the stuck test process, so we can see where it’s stuck?


(Matias Bjarland) #3

Thank you for a fast and precise answer.

I tracked down my stuck test and it seems to have been unrelated to the styled output.

I have a follow up question. Part of the job of the custom task in question is to output data from a log file as it becomes available (basically equivalent to “tail -f”) onto the gradle build log.

As far as I understand, the ProgressLogger contract is to keep updating the same line the way gradle does for the “> Loading”, “> Building” etc atsks. I would like to control the output in some detail. For example I would print out:

<in green>some text 1</in green><in red>some other text 1</in red>
<in green>some text 2</in green><in red>some other text 2</in red>

I take it this would not be possible using a ProgressLogger? If so, is there a way to combine the higher level logic of detecting when it is possible to output things from the ProgressLogger with the line-level control of StyledTextFactory?