Gradle color output

17,695

Solution 1

Found the answer! According to this gradle forum post, there's no public interface for coloring the output of the logger. You are free to use the internal classes, but those may change in future versions. In the gradle script, put at the top:

Older Gradle:

import org.gradle.logging.StyledTextOutput;
import org.gradle.logging.StyledTextOutputFactory;
import static org.gradle.logging.StyledTextOutput.Style;

Gradle 3.3+:

import org.gradle.internal.logging.text.StyledTextOutput;
import org.gradle.internal.logging.text.StyledTextOutputFactory;
import static org.gradle.internal.logging.text.StyledTextOutput.Style;

(I still haven't figured out how to move this to the init.gradle file.) Then shortly after, define

def out = services.get(StyledTextOutputFactory).create("blah")

I'm still not sure what needs to be in the create method's string (it doesn't seem to affect anything yet). Then later in your task,

out.withStyle(Style.Info).println('colored text')

This should work with all the categories: normal, header, userinput, identifier, description, progressstatus, failure, info, and error. An additional step if you want to customize the color of each category, add the following to an init.gradle file in your ~/.gradle directory (or other options):

System.setProperty('org.gradle.color.error', 'RED')

and then replace the "error" category with any from the above list.

Solution 2

Just additional informations completing the accepted answer. Here is the default styles with gradle 4.10

StyledTextOutput.Style.values().each {
    out.style(it).println("This line has the style $it")
}

all styles

Moreoever, you can create multicolor line, like a StringBuilder

out.style(Style.ProgressStatus).text('This is ').style(Style.Failure).text('a multicolor ').style(Style.Identifier).println('line')

multicolor

edit : here is a working example :

import org.gradle.internal.logging.text.StyledTextOutput 
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.internal.logging.text.StyledTextOutput.Style

def out = services.get(StyledTextOutputFactory).create("an-ouput")

out.style(Style.ProgressStatus).text('This is ').style(Style.Failure).text('a multicolor ').style(Style.Identifier).println('line')

Solution 3

Is there a simple way to tap into the color printing powers of Gradle/Groovy without importing a lot of packages?

In the interest of exploring more options, without importing packages, you could just use straight ANSI escape codes (not a strictly Gradle/Groovy technology), to format your output. The following is a working example:

task myTask {
    def styler = 'black red green yellow blue magenta cyan white'
        .split().toList().withIndex(30)
        .collectEntries { key, val -> [(key) : { "\033[${val}m${it}\033[0m" }] }

    doLast {
        println "Message: ${styler['red']('Hello')} ${styler['blue']('World')}"
    }
}

Complete code on GitHub

Solution 4

Similar solution, suggested by ToYonos written on Kotlin DSL

val printStyles by tasks.registering {
    doLast {
       val out = project.serviceOf<org.gradle.internal.logging.text.StyledTextOutputFactory>().create("an-output")
        org.gradle.internal.logging.text.StyledTextOutput.Style.values().forEach {
            out.style(it).println("This line has the style $it")
        }
    }
}

Solution 5

Simple example using a custom task written in Kotlin:

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import javax.inject.Inject

abstract class ExampleTask @Inject constructor(outputFactory: StyledTextOutputFactory) :
    DefaultTask() {

    private val out = outputFactory.create("example-task")

    @TaskAction
    fun run() {
        out.style(StyledTextOutput.Style.Success)
            .text("Hello, ")
            .style(StyledTextOutput.Style.Failure)
            .println("World!")
    }
}
Share:
17,695
tralston
Author by

tralston

Updated on June 07, 2022

Comments

  • tralston
    tralston almost 2 years

    I've looked this up on Google, but there doesn't seem to be any documentation on the Gradle site, or even people discussing this in forums.

    I have Gradle installed on my Mac (10.8.2, ML) and am building a custom build.gradle script. When I call println(), I would like to make the output colored (like errors in red, info in green, etc). How do I do this in my gradle build script?

    Here's an example of code I have so far:

    def proc = "echo `DATE`".execute()
    proc.in.eachLine {line -> println line}
    proc.err.eachLine {line -> println 'ERROR: ' + line}
    

    On this gradle forum, they talk about various styles like normal, header, userinput, identifier, description, progressstatus, failure, info, and error, as part of the StyledTextOutput class. It looks like this is an internal class. Is there a simple way to tap into the color printing powers of Gradle/Groovy without importing a lot of packages?

  • Ian Robertson
    Ian Robertson over 10 years
    It appears that the argument to create is a category, similar to a log4j category. It could be, for example, the name of the class doing the logging. The category can be a String (as above) or a Class. Alternatively, one can supply an org.gradle.api.logging.LogLevel of DEGUG, INFO, WARN, ERROR, LIFECYCLE or QUIET. Finally, one can supply both a category (as a String or Class) and a LogLevel.
  • Sonny
    Sonny over 8 years
    I used the above, and set System.setProperty ('org.gradle.logging.StyledTextOutput.Style.Success', 'GREEN') and I used it as out.withStyle (Style.Success).println (configurations.runtime) but it does not come out GREEN (just default white, for my Ubuntu gnome-terminal). Any insights into this behavior?
  • Chriki
    Chriki about 7 years
    In case anyone else should wonder: services is a property of both GradleInternal and ProjectInternal. Since I wanted to use colored output from a Gradle plugin written in Java, I needed to cast a Gradle/Project instance to one of those internal interfaces to get hold of the services property.
  • hannes ach
    hannes ach over 5 years
    it does not work: I get > No signature of method: org.gradle.internal.io.LinePerThreadBufferingOutputStream.st‌​yle() is applicable for argument types: (org.gradle.internal.logging.text.StyledTextOutput$Style) values: [Success] Possible solutions: asType(java.lang.Class), close(), close(), close(), close(), any()
  • Dirk Hoffmann
    Dirk Hoffmann about 4 years
    does not seem to work anymore (gradle 6.2) as project API does not have a serviceOf method anymore ... any ideas?
  • Dirk Hoffmann
    Dirk Hoffmann about 4 years
    this doesn't seem to work with Gradle 6.x anymore ... any solutions you came up with?
  • Sean Barbeau
    Sean Barbeau about 4 years
    Even though the above works from command-line, IntelliJ 2019.3 give me a cannot resolve symbol for the import of StyledTextOutput.Style. However, if I remove the StyledTextOutput.Style import and just reference StyledTextOutput.Style.SuccessHeader in-line, then IntelliJ stops complaining.
  • Per Lundberg
    Per Lundberg over 3 years
    @DirkHoffmann Any more details about why this is broken in Gradle 6? I tried looking at their release notes but couldn't find anything obvious (docs.gradle.org/6.0/release-notes.html)
  • Dirk Hoffmann
    Dirk Hoffmann over 3 years
    @per-lundberg no did not hear of anything, but gave up searching for it so might be something slipped my attention
  • Thomas Keller
    Thomas Keller almost 3 years
    The API is still available. Make a custom task and inject the factory in it's constructor.
  • Reza
    Reza over 2 years
    line 2: use: command not found line 3: use: command not found line 4: use: command not found line 5: syntax error near unexpected token `(' line 5: ` use Term::ANSIColor qw(:constants);'
  • LanDenLabs
    LanDenLabs over 2 years
    To use Perl - you often need to install modules used by the script. In this case you probably need to install Term::ANSIColor. See this link for how to install modules. stackoverflow.com/questions/65865/…