- Uma das formas úteis de a equipe de desenvolvimento coletar e preservar o conhecimento da organização é ampliar o conjunto de snippets, scripts ou workflows úteis
- Por isso, muitos repositórios acabam tendo coisas como
Makefile e scripts em bash
- Mas como lidar com coisas como instalar ferramentas úteis para toda a organização, gerar código boilerplate ou executar comandos complexos da AWS que ninguém consegue lembrar?
- Algumas empresas, como Slack e Shopify, têm sua própria CLI interna
- Terminais modernos como o Warp têm recursos para documentar e compartilhar workflows
- É fácil criar uma CLI para uso interno na organização. Como exemplo, foi criada uma CLI para uma empresa chamada acme
Requisitos de design da CLI
- Ter um ponto de entrada comum para executar comandos de qualquer lugar com
acme <command>
- Todos os desenvolvedores podem disparar comandos executando
acme <command> de qualquer lugar, sem precisar primeiro ir até um repositório específico
- Permitir que desenvolvedores contribuam facilmente com novos comandos
- Permitir distribuir novas versões facilmente com
acme update
- Suporte multiplataforma (por exemplo, se
acme download something for executado, no Linux usa curl e no Windows usa Invoke-WebRequest)
- Permitir ver a lista de comandos disponíveis e uma breve descrição com
acme list
Começando o projeto com just
- just é uma ferramenta parecida com
make, mas especializada em executar comandos
- Ela oferece suporte multiplataforma e também pode executar comandos específicos de cada plataforma
- Outras opções incluem o
magic-cli do Slack (ótimo para começar se você conhece bem Ruby) ou make
Configurando o projeto
- Instale o
just. Siga as instruções aqui
- Crie a pasta
~/acme/cli e adicione o seguinte justfile na raiz:
default:
just --list
# mostrar arch e nome do os
os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
- Na documentação do
just, os comandos são chamados de "recipes"
- Ao executar
just sem uma recipe, ele executa a primeira recipe do justfile. Normalmente, um padrão comum é nomear a primeira recipe como default
$ just
just --list
Available recipes:
default
os-info # Show arch and os name
- A recipe
default executa just list. Ela mostra todas as recipes e seus comentários
- É uma boa ideia ocultar a recipe
default
- Ao executar uma recipe, cada comando é exibido antes de ser executado. Você pode remover essa saída com o prefixo
@. É semelhante ao Makefile
[private]
@default:
just --list
# mostrar arch e nome do os
@os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
Criando o alias acme
Escrevendo novas recipes
Recipe simples
Recipe específica de plataforma
- Snippets que incluem ferramentas como
systemd devem ser expostos apenas se o desenvolvedor estiver usando uma máquina Linux
- Use o atributo
[linux] para expor a recipe somente no Linux
[linux]
@list-systemd-services:
systemctl list-units --type=service
Recipe multiplataforma
Recipe em script
- É possível embutir um script inteiro em uma recipe
- Recipes que começam com Shebang (
#!) são salvas em um arquivo separado e executadas
- Isso é útil quando o workflow precisa de uma lógica um pouco mais complexa, como controle de fluxo (if-else, loops), armazenamento e manipulação de variáveis etc.
# Say hello world in sh
hello-world-sh:
#!/usr/bin/env sh
hello='Yo'
echo "$hello from a shell script!"
- Isso significa que é possível aproveitar linguagens de programação com recursos de script mais poderosos. Algumas tarefas podem ser mais fáceis em Python do que em Bash
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#!/usr/bin/env python3
import PIL.Image
image = PIL.Image.open("{{path}}")
factor = 0.5
image = image.resize((round(image.width * factor), round(image.height * factor)))
image.save("{{path}}.s50.jpg")
- Nem todo desenvolvedor tem Python instalado no computador e, mesmo quando tem, pode não ter o pillow instalado. É possível usar
nix para executar o script com as dependências incluídas:
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3Packages.pillow
import PIL.Image
...
Distribuindo as recipes
- Em vez de criar seu próprio mecanismo de distribuição, use
git
- Crie um repositório no GitHub e envie o que foi feito até agora
$ git init
$ git commit -m "first commit"
$ git branch -M main
$ git remote add origin git@github.com:acme/cli.git
$ git push -u origin main
- Agora, qualquer pessoa com acesso a esse repositório pode criar um PR e contribuir com mudanças
- Automatize o
git pull com uma recipe acme update
# Update the Acme CLI
@update:
git fetch
git checkout main
Documentação
- Adoção é muito importante para o sucesso de uma ferramenta interna, e é essencial ter um bom guia de uso para ajudar novos usuários a instalar e explorar a ferramenta
- Oriente a instalação e o uso no
README
# Acme CLI
## Prerequisites
`just`: Install just [here](https://github.com/casey/just/blob/master/README.md#installation)
## Installation
Clone this repo:
...
Set up the `acme` alias:
...
## Usage
List all available recipes:
...
- Agora, todos os desenvolvedores da Acme Corp podem usar isso!
- Publique uma mensagem no Slack interno incentivando todos a testar, e cada um pode contribuir com seus próprios snippets
Recursos adicionais
- O recurso de autocomplete (Completion) é um mecanismo que permite completar automaticamente subcomandos, caminhos de arquivos, opções etc. ao pressionar a tecla TAB
- A maioria dos shells oferece esse recurso, e a maior parte das principais ferramentas de CLI também fornece uma forma de instalar autocomplete
- A maioria dos principais frameworks de CLI, como Click do Python, Cobra do Golang e clap do Rust, consegue gerar autocomplete automaticamente
- O
just pode gerar Completion executando just --completion <shell>.
1 comentários
Parece que, há algum tempo, o design da DX interna da empresa tem sido um tema importante para a engenharia de plataforma.