50 pontos por xguru 2024-09-03 | 1 comentários | Compartilhar no WhatsApp
  • 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

  • Para executar no formato acme <command>, adicione um alias ao .bashrc
    alias acme='just --justfile ~/acme/cli/justfile'  
    
  • Carregue o novo alias com source ~/.bashrc ou exec bash

Escrevendo novas recipes

Recipe simples

  • Buscar informações do usuário/role do AWS IAM
    @aws-id:  
      aws sts get-caller-identity  
    
    • Simplificar comandos que ninguém consegue lembrar é provavelmente o principal caso de uso de uma CLI interna
    • Como estamos assumindo que o awscli é multiplataforma, essa recipe funciona independentemente de onde for chamada

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

  • Implementando o cálculo do tamanho de uma pasta separadamente no Windows e no Linux
    [windows]  
    [no-cd]  
    get-folder-size path:  
      (Get-ChildItem "{{path}}" -Recurse -Force | Measure-Object -Property Length -Sum).Sum / 1MB  
    
    [linux]  
    [no-cd]  
    get-folder-size path:  
      du -sh {{path}}  
    

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

 
bus710 2024-09-03

Parece que, há algum tempo, o design da DX interna da empresa tem sido um tema importante para a engenharia de plataforma.