Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ColorScheme not working #1186

Closed
sysmat opened this issue Sep 24, 2020 · 26 comments
Closed

ColorScheme not working #1186

sysmat opened this issue Sep 24, 2020 · 26 comments

Comments

@sysmat
Copy link

sysmat commented Sep 24, 2020

picocli: 4.5.1

When exception is in Callable then from cli I should expect massage to be color red, but is not(powershell, gitbash)

My code:

static IExecutionExceptionHandler errorHandler = (Exception ex, CommandLine cmdL, ParseResult pr) -> {
        cmdL.getErr().println(cmdL.getColorScheme().errorText(ex.getMessage())); 
        return cmdL.getCommandSpec().exitCodeOnExecutionException();
};

public static void main( String[] args ) {
       ColorScheme colorScheme = createColorScheme();
       CommandLine commands = new CommandLine(new TopLavelCommands()).setColorScheme(colorScheme).setExecutionExceptionHandler(errorHandler);
        System.exit(commands ).execute(args);
}

private static ColorScheme createColorScheme() {
        return new ColorScheme.Builder()
                .commands(CommandLine.Help.Ansi.Style.bold, CommandLine.Help.Ansi.Style.underline) // combine multiple styles
                .options(CommandLine.Help.Ansi.Style.fg_yellow) // yellow foreground color
                .parameters(CommandLine.Help.Ansi.Style.fg_yellow)
                .optionParams(CommandLine.Help.Ansi.Style.italic)
                .errors(CommandLine.Help.Ansi.Style.fg_red, CommandLine.Help.Ansi.Style.bold)
                .stackTraces(CommandLine.Help.Ansi.Style.italic)
                .build();
}
@remkop
Copy link
Owner

remkop commented Sep 24, 2020

@sysmat Are colors showing correctly when you execute <yourcmd> --help in those shells?

To help troubleshoot this issue, can you run again with system property -Dpicocli.trace=DEBUG on both shells, and copy-paste the output here?

The powershell problem may be related to this issue.
(I have not heard any reports of problems with ANSI colors in gitbash until now.)

@sysmat
Copy link
Author

sysmat commented Sep 24, 2020

[picocli DEBUG] Creating CommandSpec for si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6 with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Creating CommandSpec for class picocli.CommandLine$HelpCommand with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Adding subcommand 'help' to '<main class>'
[picocli DEBUG] Creating CommandSpec for class si.arnes.kdo.cli.SearchCmd with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Adding subcommand 'search' to '<main class>'
[picocli INFO] Picocli version: 4.5.1, JVM: 1.8.0_201 (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09), OS: Windows 10 10.0 amd64
[picocli INFO] Parsing 1 command line args [help]
[picocli DEBUG] Parser configuration: optionsCaseInsensitive=false, subcommandsCaseInsensitive=false, abbreviatedOptionsAllowed=false, abbreviatedSubcommandsAllowed=false, aritySatisfiedByAttachedOptionParam=false, atFileCommentChar=#, caseInsensitiveEnumValuesAllowed=false, collectErrors=false, endOfOptionsDelimiter=--, expandAtFiles=true, limitSplit=false, overwrittenOptionsAllowed=false, posixClusteredShortOptionsAllowed=true, separator=null, splitQuotedStrings=false, stopAtPositional=false, stopAtUnmatched=false, toggleBooleanFlags=false, trimQuotes=false, unmatchedArgumentsAllowed=false, unmatchedOptionsAllowedAsOptionParameters=true, unmatchedOptionsArePositionalParams=false, useSimplifiedAtFiles=false
[picocli DEBUG] (ANSI is disabled by default: systemproperty[picocli.ansi]=null, isatty=true, TERM=cygwin, OSTYPE=null, isWindows=true, JansiConsoleInstalled=false, ANSICON=null, ConEmuANSI=null, NO_COLOR=null, CLICOLOR=null, CLICOLOR_FORCE=null)
[picocli DEBUG] Initializing command 'null' (user object: si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6): 0 options, 0 positional parameters, 0 required, 0 groups, 2 subcommands.
[picocli DEBUG] [0] Processing argument 'help'. Remainder=[]
[picocli DEBUG] Found subcommand 'help' (command 'help' (user object: class picocli.CommandLine$HelpCommand))
[picocli DEBUG] Checking required args for parent command 'null' (user object: si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6)...
[picocli DEBUG] Initializing command 'help' (user object: class picocli.CommandLine$HelpCommand): 1 options, 1 positional parameters, 0 required, 0 groups, 0 subcommands.
[picocli DEBUG] Getting a picocli.CommandLine$HelpCommand instance from factory picocli.CommandLine$DefaultFactory@33e5ccce
[picocli DEBUG] Factory returned a picocli.CommandLine$HelpCommand instance (5a42bbf4)
[picocli DEBUG] Set initial value for field boolean picocli.CommandLine$HelpCommand.helpRequested of type boolean to false.
[picocli DEBUG] Set initial value for field String[] picocli.CommandLine$HelpCommand.commands of type class [Ljava.lang.String; to [Ljava.lang.String;@270421f5.

[picocli DEBUG] Applying default values for command '<main class> help'
[picocli DEBUG] defaultValue not defined for field boolean picocli.CommandLine$HelpCommand.helpRequested
[picocli DEBUG] defaultValue not defined for field String[] picocli.CommandLine$HelpCommand.commands
[picocli DEBUG] Applying default values for command '<main class>'
commands for kdo cli
Usage>> command switches
help>> help
help for search command>> help search
Commands:
  help    Displays help information about the specified command
  search  search users by username or mail and retrive users data

@remkop
Copy link
Owner

remkop commented Sep 24, 2020

Thank you!

I see what the cause is: the TERM environment variable has value Cygwin and this is not recognized by picocli.
I will fix this soon.

Can you provide details on the terminal software name and version?

@sysmat
Copy link
Author

sysmat commented Sep 24, 2020

I'm using Windows Terminal Version: 1.3.2651.0 with the different host terminal

  • Powershell
Name             : ConsoleHost
Version          : 5.1.19041.1
InstanceId       : 77c51b75-1189-4579-b72d-8499cbaa160a
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : sl-SI
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace
  • gitbash
cygwin
cygcheck (msys) 2.6.0
System Checker for Msys

@remkop
Copy link
Owner

remkop commented Sep 24, 2020

By the way, can you also provide -Dpicocli.trace=DEBUG output for PowerShell? The cause may be different.

@sysmat
Copy link
Author

sysmat commented Sep 25, 2020

  • powershell:

❯ java '-Dpicocli.trace=DEBUG' -jar kdo.jar
[picocli DEBUG] Creating CommandSpec for si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6 with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Creating CommandSpec for class picocli.CommandLine$HelpCommand with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Adding subcommand 'help' to '<main class>'
[picocli DEBUG] Creating CommandSpec for class si.arnes.kdo.cli.SearchCmd with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Adding subcommand 'search' to '<main class>'
[picocli INFO] Picocli version: 4.5.1, JVM: 1.8.0_201 (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09), OS: Windows 10 10.0 amd64
[picocli INFO] Parsing 0 command line args []
[picocli DEBUG] Parser configuration: optionsCaseInsensitive=false, subcommandsCaseInsensitive=false, abbreviatedOptionsAllowed=false, abbreviatedSubcommandsAllowed=false, aritySatisfiedByAttachedOptionParam=false, atFileCommentChar=#, caseInsensitiveEnumValuesAllowed=false, collectErrors=false, endOfOptionsDelimiter=--, expandAtFiles=true, limitSplit=false, overwrittenOptionsAllowed=false, posixClusteredShortOptionsAllowed=true, separator=null, splitQuotedStrings=false, stopAtPositional=false, stopAtUnmatched=false, toggleBooleanFlags=false, trimQuotes=false, unmatchedArgumentsAllowed=false, unmatchedOptionsAllowedAsOptionParameters=true, unmatchedOptionsArePositionalParams=false, useSimplifiedAtFiles=false
[picocli DEBUG] (ANSI is disabled by default: systemproperty[picocli.ansi]=null, isatty=true, TERM=null, OSTYPE=null, isWindows=true, JansiConsoleInstalled=false, ANSICON=null, ConEmuANSI=null, NO_COLOR=null, CLICOLOR=null, CLICOLOR_FORCE=null)
[picocli DEBUG] Initializing command 'null' (user object: si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6): 0 options, 0 positional parameters, 0 required, 0 groups, 2 subcommands.
[picocli DEBUG] Applying default values for command '<main class>'
Missing required subcommand
commands for kdo cli

@remkop
Copy link
Owner

remkop commented Sep 25, 2020

Thank you!

Looks like on PowerShell, picocli cannot detect that ANSI escape codes are supported.
So you would need to either use Jansi:

import org.fusesource.jansi.AnsiConsole;
...
public static void main(String[] args) {
    AnsiConsole.systemInstall(); // enable colors on Windows
    new CommandLine(new TopLavelCommands()).execute(args);
    AnsiConsole.systemUninstall(); // cleanup when done
}

...or ask your users to set one of the environment variables that picocli uses to determine if ANSI escape codes are supported.

I recommend Jansi, or picocli-jansi-graalvm.
picocli-jansi-graalvm allows you to only use Jansi on Windows-only, and fixes some Jansi bugs for GraalVM native images.

It is used like this:

import picocli.jansi.graalvm.AnsiConsole; // not org.fusesource.jansi.AnsiConsole
...
try (AnsiConsole ansi = AnsiConsole.windowsInstall()) { // enable colors on Windows
    new CommandLine(new MyApp()).execute(args);
}                                                       // Closeable does cleanup when done

@remkop remkop added this to the 4.6 milestone Sep 30, 2020
remkop added a commit that referenced this issue Sep 30, 2020
(Git for Windows, MSYS2-based Windows Terminal shells, etc.)
@remkop
Copy link
Owner

remkop commented Sep 30, 2020

@sysmat I finally got around to putting in a fix for MSYS2 (auto-enable ANSI when env var TERM contains cygwin).

Can you confirm that this solves the issue in the MSYS2-based Windows Terminal shell?

To verify, check out picocli master locally, and build it with publishToMavenLocal. That should publish picocli-4.5.2-SNAPSHOT to your local .m2 Maven cache.

git clone https://github.com/remkop/picocli.git
cd picocli
gradlew publishToMavenLocal

You can then try this in a project that uses the info.picocli:picocli:4.5.2-SNAPSHOT dependency. Feedback very welcome!

@remkop
Copy link
Owner

remkop commented Oct 5, 2020

@sysmat Can you think of a way to detect from the Java process whether it was launched from PowerShell or from some other shell like CMD? That would help further improve picocli's ANSI heuristics.

If we cannot improve the heuristics, then the best thing that picocli-based applications can do is to always use Jansi (at least when running on Windows).

Thoughts?

@remkop remkop modified the milestones: 4.5.2, 4.6 Oct 14, 2020
@remkop
Copy link
Owner

remkop commented Oct 14, 2020

I have started the release for picocli 4.5.2, which contains the fix for MSYS2.
So, from 4.5.2, gitbash should automatically show colors.

I don't have a solution for Powershell... This may be a Powershell issue (looking at #849).

@remkop
Copy link
Owner

remkop commented Oct 14, 2020

@sysmat Can you confirm that colors work correclty in MSYS2 (gitbash) with picocli 4.5.2?

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

  • even strange in gitbash:
←[31m←[1mUnknown options: '-u', 'gcime'←[21m←[39m←[0m

Usage:

←[1m←[4m<main class> search←[24m←[21m←[0m [←[33m-ah←[39m←[0m] [←[33m-s←[39m←[0m=←[3m<search>←[23m←[0m]

Description:

search users by username or mail and retrive users data

Options:

  ←[33m-a←[39m←[0m, ←[33m--all←[39m←[0m               Specify to show all users if more then limit of 20
                            users in search result
                          For example, `-a`
  ←[33m-h←[39m←[0m, ←[33m--history←[39m←[0m           Specify to show user dossier
                          For example, `-h`
  ←[33m-s←[39m←[0m, ←[33m--search←[39m←[0m=←[3m<search>←[23m←[0m   Specify search by username or email
                          For example, `-s test@arnes.si`
  • in PS
Missing required subcommand
commands for kdo cli
Usage>> command switches
help>> help
help for search command>> help search
Commands:
  help    Displays help information about the specified command
  search  search users by username or mail and retrive users data

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

Oh no, that gitbash output looks bad...
Is the PS output what you expected?

Also, can you print the output of gitbash when you run with -Dpicocli.trace=DEBUG?

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

I cannot reproduce this. How do I set up a MSYS2-based Windows Terminal shell?

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

  • When some exception happens I expect red color(not working in PS and gitbash - MINGW64)
  • DEBUG
[picocli DEBUG] Creating CommandSpec for si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6 with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Creating CommandSpec for class picocli.CommandLine$HelpCommand with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Adding subcommand 'help' to '<main class>'
[picocli DEBUG] Creating CommandSpec for class si.arnes.kdo.cli.SearchCmd with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Getting a si.arnes.kdo.cli.SearchCmd instance from factory picocli.CommandLine$DefaultFactory@51016012
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[picocli DEBUG] Factory returned a si.arnes.kdo.cli.SearchCmd instance (5d3411d)
[picocli DEBUG] Creating CommandSpec for si.arnes.kdo.cli.option.KdoOptions@2471cca7 with factory picocli.CommandLine$DefaultFactory
[picocli DEBUG] Adding subcommand 'search' to '<main class>'
[picocli INFO] Picocli version: 4.5.2, JVM: 1.8.0_201 (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09), OS: Windows 10 10.0 amd64
[picocli INFO] Parsing 3 command line args [search, -s, gcime]
[picocli DEBUG] Parser configuration: optionsCaseInsensitive=false, subcommandsCaseInsensitive=false, abbreviatedOptionsAllowed=false, abbreviatedSubcommandsAllowed=false, aritySatisfiedByAttachedOptionParam=false, atFileCommentChar=#, caseInsensitiveEnumValuesAllowed=false, collectErrors=false, endOfOptionsDelimiter=--, expandAtFiles=true, limitSplit=false, overwrittenOptionsAllowed=false, posixClusteredShortOptionsAllowed=true, separator=null, splitQuotedStrings=false, stopAtPositional=false, stopAtUnmatched=false, toggleBooleanFlags=false, trimQuotes=false, unmatchedArgumentsAllowed=false, unmatchedOptionsAllowedAsOptionParameters=true, unmatchedOptionsArePositionalParams=false, useSimplifiedAtFiles=false
[picocli DEBUG] (ANSI is enabled by default: systemproperty[picocli.ansi]=null, isatty=true, TERM=cygwin, OSTYPE=null, isWindows=true, JansiConsoleInstalled=false, ANSICON=null, ConEmuANSI=null, NO_COLOR=null, CLICOLOR=null, CLICOLOR_FORCE=null)
[picocli DEBUG] Initializing command 'null' (user object: si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6): 0 options, 0 positional parameters, 0 required, 0 groups, 2 subcommands.
[picocli DEBUG] [0] Processing argument 'search'. Remainder=[-s, gcime]
[picocli DEBUG] Found subcommand 'search' (command 'search' (user object: si.arnes.kdo.cli.SearchCmd@5d3411d))
[picocli DEBUG] Checking required args for parent command 'null' (user object: si.arnes.kdo.cli.TopLavelCommands@3f8f9dd6)...
[picocli DEBUG] Initializing command 'search' (user object: si.arnes.kdo.cli.SearchCmd@5d3411d): 3 options, 0 positional parameters, 0 required, 0 groups, 0 subcommands.
[picocli DEBUG] Set initial value for field String si.arnes.kdo.cli.option.KdoOptions.search of type class java.lang.String to null.
[picocli DEBUG] Set initial value for field boolean si.arnes.kdo.cli.option.KdoOptions.history of type boolean to false.
[picocli DEBUG] Set initial value for field boolean si.arnes.kdo.cli.option.KdoOptions.all of type boolean to false.
[picocli DEBUG] [1] Processing argument '-s'. Remainder=[gcime]
[picocli DEBUG] '-s' cannot be separated into <option>=<option-parameter>
[picocli DEBUG] Found option named '-s': field String si.arnes.kdo.cli.option.KdoOptions.search, arity=1
[picocli DEBUG] 'gcime' doesn't resemble an option: 0 matching prefix chars out of 6 option names
[picocli INFO] Setting field String si.arnes.kdo.cli.option.KdoOptions.search to 'gcime' (was 'null') for option -s on KdoOptions@2471cca7
[picocli DEBUG] Applying default values for command '<main class> search'
[picocli DEBUG] defaultValue not defined for field boolean si.arnes.kdo.cli.option.KdoOptions.history
[picocli DEBUG] defaultValue not defined for field boolean si.arnes.kdo.cli.option.KdoOptions.all
[picocli DEBUG] Applying default values for command '<main class>'
←[31m←[1mjava.net.ConnectException: Connection refused: connect←[21m←[39m←[0m
  • Windows Terminal/ Settings in json file profiles.list add:
{
                "guid": "{07b52e3e-de2c-5db4-bd2d-ba144ed6c200}",
                "hidden": false,
                "name": "GitBash",
                "commandline": "\"%PROGRAMFILES%\\git\\bin\\bash.exe\" --login -i -l",
                "icon": "%PROGRAMFILES%\\git\\mingw64\\share\\git\\git-for-windows.ico"
            }

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

Gitbash in Terminal

I was able to reproduce some strangeness when running picocli.AutoComplete or picocli.Demo in gitbash in Terminal. Not exactly the behaviour you are seeing, ANSI colors are partially working for me, but with some strange layout artifacts.

By the way, the value of the TERM environment variable in my gitbash in Terminal is not cygwin, but xterm-256color. This is not the default when I run gitbash: in plain gitbash, echo $TERM prints xterm. Not sure who is setting this value...

Powershell

About Powershell: is your application using Jansi? Using Jansi is the most reliable way to get colors in Powershell. I gave more details in an earlier comment.

Without that, you can try setting one of the environment variables that picocli checks:

# set environment variable
$Env:CLICOLOR=1

# now run a command that shows colored output
java -cp "picocli-4.5.2.jar;picocli-4.5.2-tests.jar" picocli.Demo

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

  • in PS with $Env:CLICOLOR=1 is working, error -> color red
  • no I'm not using Jansi

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

ok, I propose we put Powershell aside. I believe this (PS) is working as expected.

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

  • using jansi work in cygwin, powershell
AnsiConsole.systemInstall();
CommandLine commands = new CommandLine(new TopLavelCommands()).setExecutionExceptionHandler(errorHandler);
System.exit(commands.execute(args));
 AnsiConsole.systemUninstall(); // cleanup when done

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

Do you mean that with Jansi, you also see correct output in gitbash in Windows Terminal?

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

Yes, it solved the problem and also no strange output like ←[31m←[1m,

  • info.picocli:picocli:4.5.2
  • org.fusesource.jansi:jansi:1.18

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

That is good. Still weird that plain gitbash works fine for me but gitbash in Terminal gives strange layout problems.

Does plain gitbash (without Terminal) work correctly for you without Jansi? (Trying to isolate whether the problem is with Terminal...)

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

not using jansi

  • pure gitbash(cygwin) -> colors and layout working OK
  • pure powershell -> colors NOT OK, layout OK
  • Windows terminal + powershell -> colors NOT OK, layout OK
  • Windows terminal + gitbash -> colors NOT OK, layout NOT OK

@remkop
Copy link
Owner

remkop commented Oct 15, 2020

Looks to be a Terminal issue...
And you have a solution: use Jansi. So I think we are ok... no?

@sysmat
Copy link
Author

sysmat commented Oct 15, 2020

Yes, I think so, thx again :)

@sysmat sysmat closed this as completed Oct 15, 2020
@remkop
Copy link
Owner

remkop commented Oct 15, 2020

Great!
Please star ⭐ picocli on GitHub if you like the project! 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants