31

我在谷歌上查过这个,但 Gradle 网站上似乎没有任何文档,甚至没有人在论坛上讨论这个问题。

我在我的 Mac(10.8.2,ML)上安装了 Gradle,并且正在构建一个自定义 build.gradle 脚本。当我调用 println() 时,我想让输出着色(如红色错误、绿色信息等)。如何在我的 gradle 构建脚本中执行此操作?

这是我到目前为止的代码示例:

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

这个 gradle 论坛上,他们讨论了作为 StyledTextOutput 类的一部分的各种样式,例如 normal、header、userinput、identifier、description、progressstatus、failure、info 和 error。看起来这是一个内部类。有没有一种简单的方法可以在不导入大量包的情况下利用 Gradle/Groovy 的彩色打印功能?

4

6 回答 6

30

找到了答案!根据这个 gradle forum post,没有用于为记录器的输出着色的公共界面。您可以自由使用内部类,但在未来的版本中可能会发生变化。在 gradle 脚本中,放在顶部:

较旧的 Gradle

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

摇篮 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;

(我还没有弄清楚如何将它移动到 init.gradle 文件中。)然后不久之后,定义

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

我仍然不确定 create 方法的字符串中需要包含什么(它似乎还没有影响任何东西)。然后在你的任务中,

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

这应该适用于所有类别:正常、标题、用户输入、标识符、描述、进度状态、失败、信息和错误。如果要自定义每个类别的颜色,则需要额外的步骤,将以下内容添加到 ~/.gradle 目录(或其他选项)中的 init.gradle 文件中:

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

然后将“错误”类别替换为上述列表中的任何类别。

于 2013-01-25T09:03:05.527 回答
18

只是完成接受答案的附加信息。这是默认样式gradle 4.10

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

所有风格

此外,您可以创建多色线,如StringBuilder

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

多色的

编辑:这是一个工作示例:

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')
于 2018-09-25T08:02:31.423 回答
3

有没有一种简单的方法可以在不导入大量包的情况下利用 Gradle/Groovy 的彩色打印功能?

为了探索更多选项,无需导入包,您可以直接使用ANSI 转义码(不是严格的 Gradle/Groovy 技术)来格式化输出。以下是一个工作示例:

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')}"
    }
}

GitHub上的完整代码

于 2019-05-14T23:22:02.877 回答
1

ToYonos 在 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")
        }
    }
}
于 2019-12-24T10:36:03.987 回答
1

使用 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!")
    }
}
于 2021-05-27T07:38:52.157 回答
0

我通过创建外部着色器并使用 shell 别名制作宏以始终使用着色器来为 gradle 添加颜色。此解决方案将轻松扩展以使其他命令着色。

在 Mac 上使用 tcsh

alias gr ./gradlew !* |& ~/scripts/colorize.pl

或手动运行

./gradlew assembleDebug | & ~/scripts/colorize.pl

着色器只是一个具有两个特殊功能的 perl 脚本:

  1. 无缓冲读取标准输入
  2. 使用 color perl 模块来选择性地着色输出

-- 着色.pl --

   #!/usr/bin/perl
    use warnings;
    use strict;
    use Term::ANSIColor;
    use Term::ANSIColor qw(:constants);
    use IO::Select;
    
    sub colorize($);
    
    # unbuffered output
    $| = 1;
    
    # unbuffered input
    my $inStream = IO::Select->new(\*STDIN);
    my $line;
    while () {
        if ($inStream->can_read(2)) {
            last unless defined($line = get_unbuf_line());
            colorize($line)
        }
    }
    
    sub colorize($) {
        my $line = shift;
        # Example line to colorize
        #    NetInfo.java:142: warning: [unchecked]
        chomp( $line );
        if ($line =~ /([^:]+):([0-9]+): ([a-z]+): ([^ ]+)(.*)/) {
            my $head = $1;
            my $lineNo = $2;
            my $state = $3;
            my $code = $4;
            my $tail = $5;
    
            my $stateColor = WHITE;
            if ("$state" eq "warning") { $stateColor = MAGENTA; }
            if ("$state" eq "error") { $stateColor = RED; }
            print "$head" . YELLOW . ":$lineNo :" . $stateColor . " $state " . YELLOW . $code . RESET . $tail . "\n";
        } elsif ($line =~ /^(BUILD) ([A-Z]+)(.*)/) {
            my $head = $1;
            my $state = $2;
            my $tail = $3;
            my $stateColor = RED;
            if ("$state" eq "SUCCESSFUL") { $stateColor = GREEN; }
            print BOLD . $stateColor . "$line" . RESET  . "\n";
        } elsif ($line =~ /^(> Task) ([^ ]+)(.*)/) {
            print CYAN . $1 . WHITE . " $2" . YELLOW . " $3" . RESET  . "\n";
        } elsif ($line =~ /(.*)(warnings*)(.*)/i) {
            print   $1 . MAGENTA . "$2" . RESET . "$3" . "\n";
        } elsif ($line =~ /(.*)(errors*|unresolved|^e[:] .*)(.*)/i) {
            print   $1 . RED . "$2" . RESET . "$3" . "\n";
        } elsif ($line =~ /(.*)(-----.*|=====.*)/) {
            print   $1 . GREEN . "$2" . RESET . "\n";
        } else {
            print "$line\n";
        }
    }
    
    sub get_unbuf_line {
        my $line="";
        while (sysread(STDIN, my $nextbyte, 1)) {
                return $line if $nextbyte eq "\n";
                $line .= $nextbyte;
        }
        return(undef);
    }
于 2021-09-27T15:27:54.610 回答