Install jansi only when colors are enabled, add test

Also minor cleanup. Remove the comment about the issue jansi#35 because
although the issue is fixed, the behavior is correct right now: we
enable colors by default iff stderr is a TTY (and the platform is not
Windows), and to determine that we need to call `CLibrary.isatty`.

 #KT-55784
This commit is contained in:
Alexander Udalov
2023-01-16 15:44:21 +01:00
parent 34947c9d7a
commit 2a80e70860
3 changed files with 118 additions and 14 deletions
@@ -58,8 +58,8 @@ abstract class CLITool<A : CommonToolArguments> {
val collector = PrintingMessageCollector(errStream, messageRenderer, arguments.verbose)
try {
if (PlainTextMessageRenderer.COLOR_ENABLED) {
AnsiConsole.systemInstall()
if (messageRenderer is PlainTextMessageRenderer) {
messageRenderer.enableColorsIfNeeded()
}
errStream.print(messageRenderer.renderPreamble())
@@ -80,8 +80,8 @@ abstract class CLITool<A : CommonToolArguments> {
} finally {
errStream.print(messageRenderer.renderConclusion())
if (PlainTextMessageRenderer.COLOR_ENABLED) {
AnsiConsole.systemUninstall()
if (messageRenderer is PlainTextMessageRenderer) {
messageRenderer.disableColorsIfNeeded()
}
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.common.messages;
import kotlin.text.StringsKt;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.internal.CLibrary;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,21 +32,19 @@ import java.util.Set;
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*;
public abstract class PlainTextMessageRenderer implements MessageRenderer {
public static final boolean COLOR_ENABLED;
private static final boolean IS_STDERR_A_TTY;
static {
boolean colorEnabled = false;
boolean isStderrATty = false;
// TODO: investigate why ANSI escape codes on Windows only work in REPL for some reason
if (!PropertiesKt.isWindows() && "true".equals(CompilerSystemProperties.KOTLIN_COLORS_ENABLED_PROPERTY.getValue())) {
try {
// AnsiConsole doesn't check isatty() for stderr (see https://github.com/fusesource/jansi/pull/35).
colorEnabled = CLibrary.isatty(CLibrary.STDERR_FILENO) != 0;
isStderrATty = CLibrary.isatty(CLibrary.STDERR_FILENO) != 0;
}
catch (UnsatisfiedLinkError e) {
colorEnabled = false;
catch (UnsatisfiedLinkError ignored) {
}
}
COLOR_ENABLED = colorEnabled;
IS_STDERR_A_TTY = isStderrATty;
}
private static final String LINE_SEPARATOR = System.lineSeparator();
@@ -55,11 +54,10 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer {
private final boolean colorEnabled;
public PlainTextMessageRenderer() {
this(COLOR_ENABLED);
this(IS_STDERR_A_TTY);
}
// This constructor is not used in this project
// but it can be useful in a compilation server to still be able to generate colored output
// This constructor can be used in a compilation server to still be able to generate colored output, even if stderr is not a TTY.
@SuppressWarnings("WeakerAccess")
public PlainTextMessageRenderer(boolean colorEnabled) {
this.colorEnabled = colorEnabled;
@@ -180,4 +178,16 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer {
public String renderConclusion() {
return "";
}
public void enableColorsIfNeeded() {
if (colorEnabled) {
AnsiConsole.systemInstall();
}
}
public void disableColorsIfNeeded() {
if (colorEnabled) {
AnsiConsole.systemUninstall();
}
}
}