Consoles Java interativos com JLine e ConsoleUI

blog

LarLar / blog / Consoles Java interativos com JLine e ConsoleUI

May 01, 2024

Consoles Java interativos com JLine e ConsoleUI

Por Matthew Tyson Arquiteto de Software, InfoWorld | A interface de linha de comando (CLI) é o mundo interno do desenvolvimento de software. Do shell, temos acesso direto a todos os recursos do sistema operacional

Por Matthew Tyson

Arquiteto de Software, InfoWorld |

A interface de linha de comando (CLI) é o mundo interno do desenvolvimento de software. A partir do shell, temos acesso direto a todos os recursos do sistema operacional e com isso vem o poder de compor e orquestrar todos os aspectos do software. Muitas ferramentas e estruturas incorporam linhas de comando. Não apenas isso, mas o prompt de comando é a raiz mágica do trabalho com sistemas de software; é o lar de possibilidades quase ilimitadas.

Neste artigo, faremos um tour pela construção de aplicativos sofisticados de interface de linha de comando interativa (CLI) e REPLs (loops de leitura-eval-impressão ou shells interativos) em Java. Configuraremos um aplicativo de demonstração básico em Java e usaremos as bibliotecas JLine e ConsoleUI para adicionar os recursos necessários.

Nossa demonstração é baseada em uma aplicação teórica que examina o diretório de trabalho de um projeto de software e reúne informações sobre os projetos ali existentes. A aplicação também é capaz de criar novos projetos no diretório. O aplicativo de exemplo iniciará um REPL que aceita dois comandos, descrever e criar, que podem ser preenchidos com guias. O comando descrever listará a hierarquia de pastas do diretório de trabalho com codificação de cores (usando paginação, se necessário), enquanto criar inicia um menu interativo que permite ao usuário escolher que tipo de projeto criar – Java, JavaScript ou Python. Se for um aplicativo Java, permitiremos uma seleção múltipla de recursos adicionais que o usuário pode adicionar (banco de dados ou API REST) ​​que nos permitirá ver um menu aninhado.

Usaremos esses recursos apenas para explorar os recursos do JLine, em vez de realmente implementá-los.

Para este tour, você precisará de um Java JDK e Maven instalados. Começaremos criando um novo aplicativo com um arquétipo Maven, como mostrado na Listagem 1.

Maven usará esses comandos para apresentar um novo projeto para nós. Antes de prosseguirmos, vamos também adicionar todas as dependências que precisaremos e também definir a versão do Java como 11 (qualquer versão do Java 8 em diante deve funcionar), como fiz na Listagem 2. Isso se aplica ao pom .xml na raiz do projeto (deixe o restante do pom.xml como está).

A seguir, vamos modificar a classe principal em src/main/java/com/infoworld/App.java para iniciar um loop REPL. Modifique App.java usando o código da Listagem 3.

A Listagem 3 cria um programa muito simples que observa as linhas de entrada do usuário e as repete. A isso, adicionei um “completo”, que contém os dois comandos que apoiamos, descrevemos e criamos. Isso significa que quando o usuário está digitando no prompt, ele pode tabular para concluir esses comandos. Tabular duas vezes oferecerá um menu com os comandos disponíveis. JLine tornou isso muito fácil com a chamada do método .completer(new StringsCompleter("describe", "create")) de estilo fluente. JLine possui vários completadores integrados, além de Strings, e você também pode construir o seu próprio.

No fundo, o REPL é um loop while infinito, que é interrompido quando o usuário entra em exit.

Você pode testá-lo executando o comando Maven exec:java mostrado na Listagem 4.

Você receberá o prompt cenoura, a resposta de eco e os comandos de preenchimento de tabulação.

Agora que temos o echo REPL funcionando com preenchimento automático, vamos realmente lidar com os comandos. Faremos isso com Java típico, comparando a string inserida com os comandos e chamando métodos para cada um. Por enquanto, create não fará nada, mas implementaremos a lógica para gerar a hierarquia de diretórios, conforme mostrado na Listagem 5.

Agora, ao executar o aplicativo, se você inserir o comando de descrição, verá uma lista formatada por recuo do diretório de trabalho. O trabalho de construção dessa string acontece em getDirectoryHierarchy(). Esse método usa Java normal do pacote java.nio.file para percorrer o diretório e gerar cada arquivo e diretório, recuando um espaço para cada nível de diretório que descemos. Este trabalho é feito principalmente com path.relativize(p).getNameCount(), que diz: do meu caminho atual (.) forneça-me o caminho relativo ao atual (por exemplo, ./src/main/java). O getNameCount() apenas conta o número de nomes nesse caminho – três, neste caso. Para cada nome, adicionamos um espaço.