Gradle color output
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")
}
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')
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')}"
}
}
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!")
}
}
tralston
Updated on June 07, 2022Comments
-
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 over 10 yearsIt 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
ofDEGUG
,INFO
,WARN
,ERROR
,LIFECYCLE
orQUIET
. Finally, one can supply both a category (as aString
orClass
) and aLogLevel
. -
Sonny over 8 yearsI used the above, and set
System.setProperty ('org.gradle.logging.StyledTextOutput.Style.Success', 'GREEN')
and I used it asout.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 about 7 yearsIn case anyone else should wonder:
services
is a property of bothGradleInternal
andProjectInternal
. Since I wanted to use colored output from a Gradle plugin written in Java, I needed to cast aGradle
/Project
instance to one of those internal interfaces to get hold of the services property. -
hannes ach over 5 yearsit does not work: I get > No signature of method: org.gradle.internal.io.LinePerThreadBufferingOutputStream.style() 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 about 4 yearsdoes not seem to work anymore (gradle 6.2) as project API does not have a
serviceOf
method anymore ... any ideas? -
Dirk Hoffmann about 4 yearsthis doesn't seem to work with Gradle 6.x anymore ... any solutions you came up with?
-
Sean Barbeau about 4 yearsEven though the above works from command-line, IntelliJ 2019.3 give me a
cannot resolve symbol
for the import ofStyledTextOutput.Style
. However, if I remove theStyledTextOutput.Style
import and just referenceStyledTextOutput.Style.SuccessHeader
in-line, then IntelliJ stops complaining. -
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 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 almost 3 yearsThe API is still available. Make a custom task and inject the factory in it's constructor.
-
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 over 2 yearsTo 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/…