Search code examples
command-linecommand-line-interfacepicocli

Picocli: how to show header/banner at all times


Picocli offers the ability to add a nice header in the @Command annotation, for example:

@Command(name = "git-star", header = {
    "@|green       _ _      _             |@", 
    "@|green  __ _(_) |_ __| |_ __ _ _ _  |@",
    "@|green / _` | |  _(_-<  _/ _` | '_| |@",
    "@|green \\__, |_|\\__/__/\\__\\__,_|_|   |@",
    "@|green |___/                        |@"},
    description = "Shows GitHub stars for a project",
    mixinStandardHelpOptions = true, version = "git-star 0.1")

How do I always show that header/banner when the program is running, without duplicating this banner in two places?

(See also https://github.com/remkop/picocli/issues/517)


Solution

  • There are two aspects to this:

    • How to get the banner text from the application?
    • How to render the ANSI colors and styles?

    You can get the banner from the usage help message, either with new CommandLine(new App()).getCommandSpec().usageHelpMessage().header() or by injecting a @Spec annotated CommandSpec field in your application.

    To render the ANSI styles, use CommandLine.Help.Ansi.AUTO.string(line) for each banner line.

    Putting it all together:

    @Command(name = "git-star", header = {
            "@|green       _ _      _             |@", 
            "@|green  __ _(_) |_ __| |_ __ _ _ _  |@",
            "@|green / _` | |  _(_-<  _/ _` | '_| |@",
            "@|green \\__, |_|\\__/__/\\__\\__,_|_|   |@",
            "@|green |___/                        |@"},
            description = "Shows GitHub stars for a project",
            mixinStandardHelpOptions = true, version = "git-star 0.1")
    class GitStar implements Runnable {
    
      @Option(names = "-c")
      int count;
    
      @Spec CommandSpec spec;
    
      // prints banner every time the command is invoked
      public void run() {
    
        String[] banner = spec.usageHelpMessage().header();
    
        // or: String[] banner = new CommandLine(new GitStar())
        //        .getCommandSpec().usageHelpMessage().header();
    
        for (String line : banner) {
          System.out.println(CommandLine.Help.Ansi.AUTO.string(line));
        }
    
        // business logic here...
      }
    
      public static void main(String[] args) {
        CommandLine.run(new GitStar(), args);
      }
    }