# Distribución y Empaquetamiento del CLI en Linux 📦🐧
Dado que `bgustscraper` es una solución de arquitectura híbrida (Rust de alto rendimiento + Node.js/Playwright con modelos locales ONNX), el empaquetamiento y distribución del CLI requiere considerar tanto el binario nativo de Rust como sus dependencias externas.
Esta guía evalúa las mejores estrategias de la industria para empaquetar y distribuir el CLI para plataformas Linux.
---
## 🏗️ 1. Compilación del Ejecutable de Rust
El componente central escrito en Rust se compila de manera estándar generando un ejecutable binario nativo altamente optimizado:
```bash
cargo build --release -p bgustscraper
```
* **Binario Resultante:** Se ubica en `target/release/bgustscraper`.
* **Características:**
* Enlaza de manera estática todas las dependencias escritas en Rust (como `redb`, `ndarray`, `linfa-clustering`, `jsonwebtoken` y `axum`).
* Posee un arranque instantáneo (del orden de microsegundos) y un consumo mínimo de RAM base.
* Se comunica con el worker de Node.js a través de Std Pipes utilizando serialización JSON IPC de alta velocidad.
---
## 📦 2. Estrategias de Empaquetamiento y Distribución
Para empaquetar la solución completa (Rust + Node.js + Playwright + Modelos de IA), existen tres aproximaciones principales:
### Estrategia A: Contenedorización Completa (Docker) — *Recomendada para Daemons y SaaS*
Es la forma más robusta y estándar en la industria. El archivo `Dockerfile` multi-etapa incluido en el repositorio resuelve todas las dependencias automáticamente:
* **¿Cómo funciona?**
1. Compila el binario de Rust en una imagen oficial de Rust.
2. Descarga e instala Node.js y Playwright Chromium con todas sus dependencias de sistema (Gtk, GLib, etc.) necesarias para modo headless.
3. **Pre-carga y cachea los modelos ONNX** de Hugging Face directamente dentro de la imagen.
4. Genera una imagen final lista para correr sin conexión a Internet y 100% aislada.
* **Comando de Construcción:**
```bash
docker build -t bgustscraper .
```
---
### Estrategia B: Distribución en Directorio (Tarball .tar.gz) — *Ideal para CLI de Desarrollador*
Esta estrategia consiste en distribuir un archivo comprimido que contiene la estructura necesaria para que el CLI se ejecute en cualquier máquina Linux con Node.js preinstalado.
#### Estructura del Tarball:
```
bgustscraper-linux-x64/
├── bgustscraper # Ejecutable compilado de Rust
├── worker/
│ ├── index.js # Lógica del orquestador en Node
│ ├── package.json # Dependencias de npm
│ └── package-lock.json
└── install.sh # Script instalador automatizado
```
#### Script de Instalación Automatizada (`install.sh`):
El tarball incluye un script bash que prepara el entorno en la máquina del usuario:
```bash
#!/bin/bash
echo "⚙️ Configurando entorno para bgustscraper CLI..."
# 1. Comprobar si Node.js está disponible
if ! command -v node &> /dev/null; then
echo "❌ Error: Node.js no está instalado. Instálalo antes de continuar."
exit 1
fi
# 2. Instalar dependencias npm del worker
cd worker
npm ci --omit=dev
# 3. Instalar binarios de Chromium para Playwright
npx playwright install chromium
cd ..
# 4. Enlazar el binario al PATH local del sistema
sudo ln -sf "$(pwd)/bgustscraper" /usr/local/bin/bgustscraper
echo "✅ Instalación exitosa. Ahora puedes usar el CLI ejecutando 'bgustscraper' en cualquier terminal."
```
---
### Estrategia C: Empaquetamiento Single-File Simulado (Embebido en Rust)
Para lograr la ilusión de un **único archivo ejecutable distribuible**, es posible incrustar el código del worker de Node.js directamente dentro del binario de Rust en tiempo de compilación utilizando la macro `include_str!`:
```rust
// Ejemplo ilustrativo en Rust (src/worker.rs)
const WORKER_JS: &str = include_str!("../worker/index.js");
```
#### Flujo de Ejecución a nivel CLI:
1. Al arrancar, el binario de Rust comprueba si existe el directorio temporal de ejecución (ej: `~/.bgustscraper/worker/`).
2. Si no existe o si ha cambiado, escribe de manera dinámica el contenido de `WORKER_JS` en el disco.
3. Ejecuta `npm install` de manera interna en segundo plano para inicializar los módulos si no están presentes.
4. Lanza el proceso Node apuntando al archivo desempaquetado.
> [!NOTE]
> Aunque este enfoque unifica la distribución del código fuente, el host de destino todavía requiere disponer de una instalación de Node.js activa en el sistema y acceso a internet para descargar Chromium en su primer arranque.