- Una forma útil para que el equipo de desarrollo recopile y preserve el conocimiento de la organización es ir ampliando una colección de snippets, scripts o flujos de trabajo útiles
- Por eso en muchos repositorios se terminan creando cosas como
Makefile y scripts de bash
- Pero, ¿qué pasa con tareas como instalar herramientas útiles para toda la organización, generar código boilerplate o ejecutar comandos complejos de AWS que nadie recuerda?
- Algunas empresas como Slack o Shopify tienen su propia CLI interna
- Warp, una terminal moderna, tiene funciones para documentar y compartir flujos de trabajo
- Es fácil crear una CLI para uso interno de la organización. Como ejemplo, se construye una CLI para una empresa llamada acme
Requisitos de diseño de la CLI
- Tener un punto de entrada común para poder ejecutar comandos desde cualquier lugar con
acme <command>
- Todos los desarrolladores pueden ejecutar
acme <command> desde cualquier sitio para disparar comandos, sin necesidad de moverse primero a un repositorio específico
- Permitir que los desarrolladores contribuyan nuevos comandos fácilmente
- Permitir desplegar nuevas versiones fácilmente con
acme update
- Soporte multiplataforma (por ejemplo, si ejecutas
acme download something, en Linux usar curl y en Windows Invoke-WebRequest)
- Permitir ver la lista de comandos disponibles y una breve descripción con
acme list
Empezar el proyecto con just
- just es una herramienta similar a
make, pero especializada en la ejecución de comandos
- Soporta multiplataforma y también puede ejecutar comandos específicos de cada plataforma
- Otras opciones son
magic-cli de Slack (excelente para empezar si conoces bien Ruby) o make
Configurar el proyecto
- Instala
just. Sigue las instrucciones aquí
- Crea la carpeta
~/acme/cli y agrega el siguiente justfile en la raíz:
default:
just --list
# Show arch and os name
os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
- En la documentación de
just, a los comandos se les llama "recipes"
- Si ejecutas
just sin indicar una recipe, se ejecuta la primera recipe del justfile. Un patrón común es nombrar la primera recipe como default
$ just
just --list
Available recipes:
default
os-info # Show arch and os name
- La recipe
default ejecuta just list. Muestra todas las recipes y sus comentarios
- Conviene ocultar la recipe
default
- Cuando se ejecuta una recipe, cada comando se imprime antes de ejecutarse. Puedes quitar esa salida con el prefijo
@. Es similar a Makefile
[private]
@default:
just --list
# Show arch and os name
@os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
Crear el alias acme
Escribir nuevas recipes
Recipe simple
Recipe específica por plataforma
- Los snippets que incluyen herramientas como
systemd solo se exponen si el desarrollador usa una máquina Linux
- Usa el atributo
[linux] para que la recipe solo se muestre en Linux
[linux]
@list-systemd-services:
systemctl list-units --type=service
Recipe multiplataforma
Recipes con script
- Puedes incrustar un script completo dentro de una recipe
- Las recipes que empiezan con Shebang(
#!) se guardan en un archivo aparte y luego se ejecutan
- Esto resulta útil cuando un flujo de trabajo necesita lógica un poco más compleja, como control de flujo (if-else, loops), guardar variables o manipularlas
# Say hello world in sh
hello-world-sh:
#!/usr/bin/env sh
hello='Yo'
echo "$hello from a shell script!"
- Esto significa que puedes aprovechar lenguajes de programación con capacidades de scripting potentes. Algunas tareas son más fáciles de hacer en Python que en 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")
- No todos los desarrolladores tienen Python instalado en su computadora, y aunque lo tengan, puede que no tengan instalado pillow. Se puede usar
nix para ejecutar scripts con dependencias incluidas:
# 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
...
Desplegar recipes
- En lugar de crear tu propio mecanismo de despliegue, usa
git
- Crea un repositorio en GitHub y haz push de lo que llevas hasta ahora
$ 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
- Ahora cualquiera que tenga acceso a este repositorio puede crear un PR y contribuir cambios
- Automatiza
git pull con una recipe acme update
# Update the Acme CLI
@update:
git fetch
git checkout main
Documentación
- Para que una herramienta interna tenga éxito, la adopción es muy importante, y hace falta una buena guía de uso para que los nuevos usuarios puedan instalarla y explorarla
- Incluye en el
README instrucciones de instalación y uso
# 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:
...
- ¡Ahora ya puede usarla cualquier desarrollador de Acme Corp!
- Publica un mensaje en el Slack interno para animar a todos a probarla, y que cada quien pueda aportar sus propios snippets
Funciones adicionales
- La función de autocompletado (Completion) es un mecanismo que permite completar automáticamente subcomandos, rutas de archivos, opciones, etc., al presionar la tecla TAB
- La mayoría de los shells ofrecen esta función, y la mayoría de las herramientas CLI importantes explican cómo instalar su autocompletado
- La mayoría de los principales frameworks de CLI, como Click de Python, Cobra de Golang y clap de Rust, pueden generar autocompletado automáticamente
Just puede generar Completion ejecutando just --completion <shell>.
1 comentarios
Parece que, desde hace tiempo, el diseño de la DX interna de la empresa ha sido un tema importante para platform engineering.