Guia Completo de Construção de CLI
Neste artigo, vou abordar um guia completo de como construir uma CLI (Command Line Interface) profissional, que seja fácil de usar e, principalmente, fácil de ser integrada por outras aplicações. Se você nunca construiu uma CLI antes, não se preocupe — vamos começar do zero.
O que é uma CLI?
CLI significa Command Line Interface (Interface de
Linha de Comando). É aquele programa que você usa digitando comandos no
terminal, como git, npm, docker,
pip, entre outros. Diferente de programas com interface
gráfica (GUI), CLIs são controladas por texto, o que as torna
extremamente poderosas, automatizáveis e fáceis de integrar com outros
sistemas.
Entendendo o ARGV
Antes de mais nada, você precisa entender o que é o
argv. A resposta é simples: argv é um array de
strings que contém os argumentos passados para o programa. Tudo
que foi digitado no terminal é separado por espaços e transformado nesse
array.
argv[0]→ nome do programa (ou do runtime + script)argv[1]→ primeiro argumentoargv[2]→ segundo argumento- E assim por diante…
Como o argv funciona em diferentes linguagens
Em linguagens interpretadas (como Python), o
argv[0] é o nome do seu script, e os argumentos começam a
partir de argv[1].
Em linguagens compiladas (como C, C++, Go, Rust), o
argv[0] é o nome do executável compilado.
Exemplo em Python
import sys
print(sys.argv)Execute:
python3 script.py arg1 arg2 arg3Saída:
['script.py', 'arg1', 'arg2', 'arg3']
Exemplo em C
#include <stdio.h>
int main(int argc, char *argv[]) {
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}Compile e execute:
gcc programa.c -o programa
./programa arg1 arg2 arg3Saída:
argv[0] = ./programa
argv[1] = arg1
argv[2] = arg2
argv[3] = arg3
Construindo a Sua CLI
Para construir uma CLI sólida e profissional, siga os passos abaixo:
1. Defina as Actions (Ações)
O primeiro argumento (após o nome do programa) deve ser a action, ou seja, a ação que o usuário deseja executar.
meu_programa <action> [flags e argumentos]Vamos usar o git como exemplo. Ele possui várias actions
como commit, pull, push,
rebase, etc. Veja o comando abaixo:
git commit -m "mensagem do commit"Nesse exemplo: - commit → é a action -
-m → é uma flag -
"mensagem do commit" → é o valor da
flag
Dica para iniciantes: Pense na action como uma função, e nas flags como os parâmetros dessa função.
Como implementar actions
A forma mais simples de implementar actions é usar uma estrutura condicional para verificar o primeiro argumento:
Exemplo em Python:
import sys
def action_hello():
print("Olá! Bem-vindo à minha CLI!")
def action_version():
print("meu_programa v1.0.0")
if len(sys.argv) < 2:
print("Uso: meu_programa <action>")
print("Use 'meu_programa help' para ver as ações disponíveis.")
sys.exit(1)
action = sys.argv[1]
if action == "hello":
action_hello()
elif action == "version":
action_version()
else:
print(f"Ação desconhecida: {action}")
print("Use 'meu_programa help' para ver as ações disponíveis.")2. Defina as Flags
Agora que você separou cada ação possível da sua CLI, você deve definir as flags que cada action pode receber. Flags modificam o comportamento de uma action.
Existem dois tipos de flags:
Boolean Flags (flags sem valor)
São flags que não recebem valor — apenas indicam que algo deve ser
ativado. Geralmente começam com --.
git push --forceAqui, --force é uma flag booleana que indica que o push
deve ser forçado.
Value Flags (flags com valor)
São flags que recebem um valor logo em seguida. Podem usar
- (forma curta) ou -- (forma longa).
git commit -m "mensagem do commit"
git commit --message "mensagem do commit"Aqui, -m (ou --message) é uma flag que
recebe a mensagem como valor.
Como implementar flags
Exemplo em Python:
import sys
def parse_flags(args):
"""Analisa os argumentos e retorna um dicionário de flags."""
flags = {}
i = 0
while i < len(args):
if args[i].startswith("--"):
flag_name = args[i][2:] # Remove o prefixo --
# Verifica se é uma boolean flag ou uma value flag
if i + 1 < len(args) and not args[i + 1].startswith("-"):
flags[flag_name] = args[i + 1]
i += 2
else:
flags[flag_name] = True
i += 1
elif args[i].startswith("-"):
flag_name = args[i][1:] # Remove o prefixo -
if i + 1 < len(args) and not args[i + 1].startswith("-"):
flags[flag_name] = args[i + 1]
i += 2
else:
flags[flag_name] = True
i += 1
else:
i += 1
return flags
# Exemplo de uso:
# meu_programa commit -m "mensagem" --force
action = sys.argv[1]
flags = parse_flags(sys.argv[2:])
print(f"Action: {action}")
print(f"Flags: {flags}")3. Defina um Help (Ajuda)
Todo programa de linha de comando precisa de uma
ação help. Ela deve listar todas as ações e flags
disponíveis, com uma descrição clara de cada uma.
meu_programa helpExemplo de saída:
meu_programa - Uma ferramenta incrível para gerenciar tarefas
Uso: meu_programa <action> [flags]
Ações disponíveis:
help Mostra esta mensagem de ajuda
version Mostra a versão do programa
add Adiciona uma nova tarefa
--title <texto> Título da tarefa (obrigatório)
--priority <n> Prioridade de 1 a 5 (padrão: 3)
list Lista todas as tarefas
--filter <status> Filtra por status (pendente, concluída)
--limit <n> Limita o número de resultados
done Marca uma tarefa como concluída
--id <id> ID da tarefa (obrigatório)
Exemplos:
meu_programa add --title "Comprar café" --priority 1
meu_programa list --filter pendente
meu_programa done --id 42
Dica: Sempre inclua exemplos práticos no help. Isso ajuda muito os iniciantes.
4. Defina um Version (Versão)
Crie uma action chamada version que mostra a versão
atual da sua CLI. Isso é essencial para debugging e para que os usuários
saibam qual versão estão usando.
meu_programa versionExemplo de saída:
meu_programa v1.0.0
Dica: Siga o padrão Semantic Versioning (SemVer) para numerar suas versões:
MAJOR.MINOR.PATCH(ex:1.2.3).
5. Defina Stored Configs (Configurações Armazenadas)
Muitas vezes é conveniente que sua CLI armazene configurações do
usuário para que ele não precise digitá-las toda vez. Isso é muito comum
— pense no git config ou no npm config.
Exemplo:
meu_programa config-user --username "Mateus" --email "mateus@gmail.com" --password "senha"Depois de configurado, nas próximas ações você pode exigir apenas a flag identificadora:
meu_programa set-profile-picture --username "Mateus" --picture foto.pngOnde armazenar as configurações?
É fortemente recomendado que você salve todos os
dados em um único local, de preferência em uma pasta oculta na
home do usuário (diretórios que começam com . são
ocultos no Linux/macOS).
Exemplo: as configurações poderiam ser salvas no arquivo
~/.meu_programa/config.json:
{
"username": "Mateus",
"email": "mateus@gmail.com",
"password": "teste"
}Formas comuns de armazenamento: - JSON → simples e amplamente suportado - SQLite → ideal para dados mais complexos ou relacionais - TOML/YAML → bom para arquivos de configuração legíveis - Arquivos de texto → para dados muito simples
6. Tratamento de Erros
Uma CLI profissional deve tratar erros de forma clara e amigável. Nunca deixe o programa “quebrar” com um erro incompreensível.
Boas práticas:
import sys
if len(sys.argv) < 2:
print("Erro: nenhuma ação fornecida.")
print("Uso: meu_programa <action> [flags]")
print("Use 'meu_programa help' para mais informações.")
sys.exit(1)Dicas para bons erros: - Diga o que deu errado - Diga por que deu errado (se possível) - Sugira como corrigir
Exemplo:
Erro: a flag --title é obrigatória para a ação 'add'.
Uso: meu_programa add --title "Minha tarefa"
7. Códigos de Saída (Exit Codes)
Programas de linha de comando comunicam sucesso ou falha através de códigos de saída. Isso é fundamental para que outros programas e scripts consigam saber se sua CLI executou corretamente.
- Código
0→ sucesso - Código
1ou superior → erro
import sys
# Sucesso
sys.exit(0)
# Erro genérico
sys.exit(1)Isso permite que outros programas usem sua CLI assim:
meu_programa add --title "Tarefa" && echo "Sucesso!" || echo "Falhou!"8. Saída Estruturada (Output para Outras Aplicações)
Se sua CLI pode ser utilizada por outros programas (e ela deveria!), considere oferecer saída em formatos estruturados como JSON.
meu_programa list --output jsonSaída normal (para humanos):
ID | Título | Status
1 | Comprar café | pendente
2 | Estudar CLI | concluída
Saída JSON (para programas):
[
{"id": 1, "titulo": "Comprar café", "status": "pendente"},
{"id": 2, "titulo": "Estudar CLI", "status": "concluída"}
]Isso torna sua CLI facilmente integrável com outros sistemas, scripts e pipelines.
Dicas Extras
Nunca misture padrões de nomenclatura. Se uma action se chama
set-profile-picture(separando por-), use o mesmo padrão em todas as actions. Isso facilita a legibilidade e a intuição de uso.Se as informações forem sensíveis, criptografe-as. Nunca armazene senhas em texto puro. Use alguma forma de criptografia e exija a senha de descriptografia como argumento ou configuração armazenada.
Adicione cores ao output. Cores tornam a saída muito mais legível. Por exemplo, erros em vermelho, sucesso em verde, avisos em amarelo. Na maioria das linguagens existe bibliotecas para isso (como
coloramaem Python ouchalkem Node.js).Suporte auto-complete. Se possível, permita que o usuário configure auto-complete no shell (Bash, Zsh, Fish). Isso melhora drasticamente a experiência de uso.
Escreva uma boa documentação. Além do
helpembutido, considere manter um README ou uma página de documentação com exemplos detalhados.Teste sua CLI. Escreva testes automatizados para cada action e para combinações de flags. Isso evita regressões e garante que tudo funcione como esperado.
Conclusão
Construir uma CLI profissional vai além de apenas ler argumentos do terminal. Envolve pensar na experiência do usuário, na consistência dos comandos, no tratamento de erros e na integrabilidade com outros sistemas. Seguindo os passos deste guia, você terá uma base sólida para criar CLIs que são agradáveis de usar e fáceis de manter.
Lembre-se: uma boa CLI é aquela que o usuário consegue usar sem precisar consultar a documentação a todo momento. Invista em boas mensagens de ajuda, nomes de ações intuitivos e mensagens de erro claras.
