Instalación y Uso de Just Command Runner
Just es un ejecutor de comandos moderno escrito en Rust que usa archivos justfile con una sintaxis limpia y expresiva, diseñado específicamente como alternativa a Make para automatización de proyectos. A diferencia de Makefile, Just no confunde tarea con sistema de archivos y tiene manejo de errores predecible. Esta guía cubre la instalación, sintaxis y patrones más útiles para automatizar proyectos en Linux.
Requisitos Previos
- Linux (Ubuntu/Debian o CentOS/Rocky)
- Terminal con bash o zsh
- Acceso sudo para instalación global (opcional)
Instalación de Just
# Método 1: Con el gestor de paquetes cargo (Rust)
cargo install just
# Método 2: Script de instalación (recomendado, sin necesitar Rust)
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin
# Método 3: Con Homebrew en Linux
brew install just
# Método 4: En Ubuntu/Debian con apt (versión puede ser antigua)
sudo apt install just
# Método 5: Descarga manual del binario desde GitHub
curl -L https://github.com/casey/just/releases/latest/download/just-x86_64-unknown-linux-musl.tar.gz | tar xz
sudo mv just /usr/local/bin/
# Verificar la instalación
just --version
Configurar autocompletado
# Generar completado para bash
just --completions bash > /etc/bash_completion.d/just
# Para zsh (agregar a ~/.zshrc)
just --completions zsh > ~/.zfunc/_just
echo 'fpath=(~/.zfunc $fpath)' >> ~/.zshrc
autoload -Uz compinit && compinit
# Para fish
just --completions fish > ~/.config/fish/completions/just.fish
Sintaxis Básica de Justfile
Crea un archivo llamado justfile (o Justfile) en la raíz del proyecto:
# justfile - comentarios con #
# La receta por defecto se ejecuta con solo 'just'
default:
just --list
# Receta simple de construcción
build:
echo "Compilando proyecto..."
go build -o bin/app ./cmd/main.go
# Receta con descripción (aparece en just --list)
# Compilar y ejecutar la aplicación
run: build
./bin/app
# Receta con dependencias (se ejecutan antes)
test: lint
go test ./... -v
lint:
golangci-lint run ./...
# Receta de limpieza
clean:
rm -rf bin/
rm -rf dist/
# Listar todas las recetas disponibles
just --list
# Ejecutar la receta por defecto
just
# Ejecutar una receta específica
just build
# Ejecutar múltiples recetas en orden
just clean build test
# Ver los comandos que ejecutaría sin ejecutarlos
just --dry-run build
Argumentos y Parámetros
# Receta con argumento obligatorio
deploy entorno:
echo "Desplegando en {{entorno}}"
./scripts/deploy.sh {{entorno}}
# Receta con argumento con valor por defecto
saludo nombre="mundo":
echo "Hola, {{nombre}}!"
# Múltiples argumentos
crear-usuario nombre email rol="usuario":
echo "Creando usuario {{nombre}} ({{email}}) con rol {{rol}}"
./scripts/crear-usuario.sh "{{nombre}}" "{{email}}" "{{rol}}"
# Argumento variádico (captura todo lo que queda)
ejecutar +args:
echo "Argumentos: {{args}}"
./bin/app {{args}}
# Argumento variádico opcional
probar *flags:
go test ./... {{flags}}
# Llamar con argumentos posicionales
just deploy produccion
just saludo "Juan"
just crear-usuario "Ana García" "[email protected]" "admin"
# Llamar con argumentos nombrados
just deploy entorno=staging
just saludo nombre="María"
# Argumento variádico
just probar -race -count=2 ./pkg/...
Variables y Expresiones
# Variables estáticas
app := "mi-aplicacion"
version := "1.0.0"
registry := "registry.empresa.com"
# Variables calculadas con backtick (se evalúan al cargar)
git_hash := `git rev-parse --short HEAD`
fecha := `date +%Y%m%d`
# Variables de entorno (con valor por defecto)
entorno := env_var_or_default("DEPLOY_ENV", "development")
puerto := env_var_or_default("PORT", "8080")
# Variable que puede fallar
usuario := `whoami`
# Mostrar información del proyecto
info:
echo "Aplicación: {{app}}"
echo "Versión: {{version}}"
echo "Commit: {{git_hash}}"
echo "Entorno: {{entorno}}"
echo "Puerto: {{puerto}}"
# Usar variables en comandos complejos
build:
docker build \
--build-arg VERSION={{version}} \
--build-arg GIT_HASH={{git_hash}} \
-t {{registry}}/{{app}}:{{version}}-{{git_hash}} \
.
Cargar desde archivo .env
# Cargar variables desde .env automáticamente
set dotenv-load
# Ahora las variables de .env están disponibles
conectar-db:
psql $DATABASE_URL
Condicionales y Plataformas
# Detectar sistema operativo
os := os()
arch := arch()
# Seleccionar binario según plataforma
binario := if os() == "linux" {
"app-linux"
} else if os() == "macos" {
"app-macos"
} else {
"app-windows.exe"
}
# Receta condicional
instalar-deps:
#!/usr/bin/env bash
# Usar bash para lógica compleja
if command -v apt-get &>/dev/null; then
sudo apt-get install -y curl git jq postgresql-client
elif command -v dnf &>/dev/null; then
sudo dnf install -y curl git jq postgresql
else
echo "Gestor de paquetes no reconocido"
exit 1
fi
# Verificar precondiciones
deploy entorno:
#!/usr/bin/env bash
# Verificar que estamos en la rama correcta
rama_actual=$(git branch --show-current)
if [ "{{entorno}}" = "produccion" ] && [ "$rama_actual" != "main" ]; then
echo "Error: solo se puede desplegar en producción desde la rama main"
exit 1
fi
echo "Desplegando en {{entorno}}..."
kubectl apply -f k8s/{{entorno}}/
Recetas específicas por shell
# Por defecto just usa sh, pero puedes cambiar el intérprete
set shell := ["bash", "-uc"]
# O por receta individual
tarea-python:
#!/usr/bin/env python3
import os
print(f"Ejecutando desde Python: {os.getcwd()}")
tarea-node:
#!/usr/bin/env node
console.log("Ejecutando desde Node.js");
tarea-bash:
#!/usr/bin/env bash
set -euo pipefail
echo "Script bash con manejo de errores estricto"
for archivo in src/*.go; do
echo "Procesando: $archivo"
done
Patrones Avanzados
Justfile para proyecto completo
# justfile completo para aplicación web con Docker
set dotenv-load
set shell := ["bash", "-uc"]
# Variables del proyecto
app := "portal-web"
registry := env_var_or_default("REGISTRY", "registry.empresa.com")
version := `git describe --tags --always --dirty 2>/dev/null || echo "0.0.0-dev"`
imagen := registry + "/" + app + ":" + version
# Muestra ayuda por defecto
default:
@just --list
# Entorno de desarrollo
dev:
docker compose -f docker-compose.dev.yml up --build
# Calidad de código
lint:
eslint src/ --ext .js,.ts
prettier --check "src/**/*.{js,ts,css}"
# Pruebas
test *flags:
jest --coverage {{flags}}
test-watch:
jest --watch
# Construcción
build: lint test
npm run build
@echo "Construcción completada: dist/"
# Docker
docker-build:
docker build -t {{imagen}} --build-arg VERSION={{version}} .
@echo "Imagen creada: {{imagen}}"
docker-push: docker-build
docker push {{imagen}}
@echo "Imagen publicada: {{imagen}}"
# Despliegue
[confirm("¿Estás seguro de desplegar en producción?")]
deploy-prod: docker-push
kubectl set image deployment/{{app}} app={{imagen}}
kubectl rollout status deployment/{{app}} --timeout=5m
deploy-staging: docker-push
kubectl set image deployment/{{app}}-staging app={{imagen}} -n staging
kubectl rollout status deployment/{{app}}-staging -n staging
# Base de datos
db-migrate:
./bin/migrate -database $DATABASE_URL up
db-rollback:
./bin/migrate -database $DATABASE_URL down 1
db-shell:
psql $DATABASE_URL
# Limpieza
clean:
rm -rf dist/ node_modules/.cache
docker image prune -f
Recetas con confirmación
# Pedir confirmación antes de ejecutar (just >= 1.17)
[confirm]
limpiar-bd:
psql $DATABASE_URL -c "TRUNCATE TABLE sesiones CASCADE"
# Con mensaje personalizado
[confirm("Esto eliminará datos de producción. ¿Continuar?")]
reset-produccion:
./scripts/reset-prod.sh
Importar justfiles externos
# Importar recetas de otro archivo
import "justfiles/docker.just"
import "justfiles/kubernetes.just"
import? "justfiles/local.just" # El ? hace que sea opcional
Solución de Problemas
Receta no encontrada
# Verificar que el archivo se llama 'justfile' o 'Justfile'
ls -la justfile Justfile 2>/dev/null
# Just busca el justfile en el directorio actual y superiores
just --list --justfile /ruta/a/tu/justfile
Error de sintaxis en justfile
# Verificar la sintaxis del justfile
just --evaluate
# Just es sensible a la indentación: usa TABS, no espacios
# Revisar con:
cat -A justfile | head -20
# Los tabs aparecen como ^I, los espacios como espacios
Variable de entorno no disponible
# Verificar que .env está en el directorio correcto
# y que tiene 'set dotenv-load' en el justfile
# Depurar variables
just --evaluate | grep MI_VARIABLE
Conflicto de nombre con dependencia del sistema
# Just busca recetas, no ejecutables del sistema
# Si necesitas ejecutar un comando del sistema con el mismo nombre:
test-real:
/usr/bin/test -f archivo.txt
Conclusión
Just ofrece una experiencia de automatización superior a Make para proyectos modernos: sintaxis clara, soporte nativo de argumentos con valores por defecto, variables expresivas y manejo de errores predecible. Su diseño específico para ejecutar recetas (no para gestión de dependencias de archivos) evita la confusión más común de Make y lo convierte en una herramienta ideal para estandarizar comandos de desarrollo, build y despliegue en cualquier tipo de proyecto.


