fusesource / jansi

Jansi is a small java library that allows you to use ANSI escape sequences to format your console output which works even on windows.
http://fusesource.github.io/jansi/
Apache License 2.0
1.11k stars 140 forks source link

Output from JANSI is distorted in new cygwin (3.1.0 or newer). #165

Closed tyan0 closed 3 years ago

tyan0 commented 4 years ago

Overview

In cygwin 3.1.0 or newer, output of jansi is distorted in Win10 1809 or later.

Description

Output of Maven, which uses jansi 1.17.1, is distorted in new cygwin (3.1.0 or newer). For example in mintty:

[INFO] Scanning for projects...
[INFO] -----------------------------------------------------------
-------------
[INFO] BUILD FAILURE
[INFO] -----------------------------------------------------------
-------------
[INFO] Total time:  0.094 s
[INFO] Finished at: 2020-02-12T21:40:27+09:00
[INFO] -----------------------------------------------------------
-------------
[ERROR] No goals have bee          n specified for this build. You must specify
a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugi
n-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle
phases are: validate, initialize, generate-sources, process-sources, generate-re
sources, process-resources, compile, process-classes, generate-test-sources, pro
cess-test-sources, generate-test-resources, process-test-resources, test-compile
, process-test-classes, test, prepare-package, package, pre-integration-test, in
tegration-test, post-integration-test, verify, install, deploy, pre-clean, clean
, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]

Lines with '-------' are wrapped before right edge of the screen and stray spaces are inserted in the word been.

Another example in console:

[INFO] Scanning for projects...
[INFO] -----------------------------------------------------------
-------------
[INFO] BUILD FAILURE
[INFO] -----------------------------------------------------------
-------------
[INFO] Total time:  0.094 s
[INFO] Finished at: 2020-02-12T21:46:42+09:00
[INFO] -----------------------------------------------------------
-------------
[ERROR] No goals have been specified for this build. You must specify
a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugi
n-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle
phases are: validate, initialize, generate-sources, process-sources, generate-re
sources, process-resources, compile, process-classes, generate-test-sources, pro
cess-test-sources, generate-test-resources, process-test-resources, test-compile
, process-test-classes, test, prepare-package, package, pre-integration-test, in
tegration-test, post-integration-test, verify, install, deploy, pre-clean, clean
, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]

In this case, the escape sequences are garbled. This causes in Win10 1703 or later.

The Cause

New cygwin adds pseudo console support to PTY. New PTY provides pure windows console for native (non-cygwin) apps. As a result, native apps can not use ANSI escape sequence in PTY even in mintty unless setting ENABLE_VIRTUAL_TERMINAL_PROCESSING. Furthermore, cygwin console (cygwin in command prompt) uses xterm compatible mode, which is enabled by ENABLE_VIRTUAL_TERMINAL_PROCESSING, and set TERM to xterm-256color rather than cygwin.

These changes cause incorrect judgement of terminal type in JANSI. Currently, JANSI works as expected in MSYS2, however, MSYS2 is based on cygwin, so probably the same problem will occur in near future.

Patch for this issue

diff --git a/jansi/src/main/java/org/fusesource/jansi/AnsiConsole.java b/jansi/src/main/java/org/fusesource/jansi/AnsiConsole.java
index 628cad3..670afb5 100644
--- a/jansi/src/main/java/org/fusesource/jansi/AnsiConsole.java
+++ b/jansi/src/main/java/org/fusesource/jansi/AnsiConsole.java
@@ -19,6 +19,10 @@ import static org.fusesource.jansi.internal.CLibrary.STDERR_FILENO;
 import static org.fusesource.jansi.internal.CLibrary.STDOUT_FILENO;
 import static org.fusesource.jansi.internal.CLibrary.isatty;

+import static org.fusesource.jansi.internal.Kernel32.GetConsoleMode;
+import static org.fusesource.jansi.internal.Kernel32.GetStdHandle;
+import static org.fusesource.jansi.internal.Kernel32.STD_OUTPUT_HANDLE;
+
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -54,15 +58,17 @@ public class AnsiConsole {
      */
     static final boolean IS_CON_EMU_ANSI = "ON".equals(System.getenv("ConEmuANSI"));

+    static private int[] mode = {0};
     static final boolean IS_CYGWIN = IS_WINDOWS
             && System.getenv("PWD") != null
             && System.getenv("PWD").startsWith("/")
-            && !"cygwin".equals(System.getenv("TERM"));
+            && GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode) == 0;

     static final boolean IS_MINGW_XTERM = IS_WINDOWS
             && System.getenv("MSYSTEM") != null
-            && System.getenv("MSYSTEM").startsWith("MINGW")
-            && "xterm".equals(System.getenv("TERM"));
+            && (System.getenv("MSYSTEM").startsWith("MINGW")
+                || System.getenv("MSYSTEM").startsWith("MSYS"))
+            && GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode) == 0;

     private static JansiOutputType jansiOutputType;
     static final JansiOutputType JANSI_STDOUT_TYPE;
UncleInf commented 4 years ago

Msys2 already migrated to cygwin 3.1.x. @tyan0 do you know any walk around to force apps that use jansi to solve color escapes? Because it might be some time until fix is merged, and picked by other apps/libs.

Edit, this might be gradle problem after all, because they have their own ansi utils which is based on old jansi code.

unb commented 4 years ago

In my environment, running cygwin 3.1.4, the TERM variable is set to xterm-256color. This breaks the output from maven 3.6.3. Setting TERM to cygwin resolves the problem e.g. > TERM=cygwin mvn

gnodet commented 3 years ago

Another more general workaround is to set the system property jansi.passthrough=true.

gnodet commented 3 years ago

I think this has been fixed in 2.x, please reopen if needed.

tyan0 commented 3 years ago

I have confirmed that Maven works as expected in cygwin 3.1.7 with/without pseudo console enabled if jansi is replaced with 2.0.2-SNAPSHOT.

Thanks!