Saltar al contenido

Referencia de CLI

merql incluye una CLI para capturar instantáneas, calcular diferencias y ejecutar fusiones directamente desde el terminal. Composer la instala como vendor/bin/merql; en una copia del repositorio de merql, es bin/merql.

vendor/bin/merql funciona tras instalar una dependencia porque merql 0.4.1. Las versiones anteriores buscaban el cargador automático de Composer solo en el directorio vendor/ del paquete y fallaban cuando merql se instalaba como dependencia.

Inicio rápido

Shell
# Capture a baseline from your database.
export MERQL_DB_DSN="sqlite:/path/to/db.sqlite"
vendor/bin/merql snapshot base

# Make some changes, then capture again.
vendor/bin/merql snapshot current

# See what changed.
vendor/bin/merql diff base current

Una fusión de tres vías requiere capturar ours y theirs de dos bases de datos que divergieron de base. Indique a MERQL_DB_DSN la base de datos correcta para cada instantánea:

Shell
# Base: live before the sandbox was copied from it.
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot base

# ... copy live.sqlite to sandbox.sqlite, then both databases change ...

MERQL_DB_DSN="sqlite:/data/sandbox.sqlite" vendor/bin/merql snapshot ours
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot theirs

# Three-way merge with dry-run preview.
vendor/bin/merql merge base ours theirs --dry-run

Tomar las tres instantáneas de la misma base de datos, una tras otra, no sirve para una fusión: theirs ya contendría los cambios de ours, por lo que cada fila insertada por ours se marcaría como un conflicto insert_insert.

Variables de entorno

CLI lee los detalles de conexión a la base de datos de las variables de entorno. Puede conectarse mediante una cadena DSN de PDO o parámetros MySQL individuales.

Conexión mediante DSN

Use MERQL_DB_DSN para conexiones basadas en PDO. Es el enfoque recomendado para SQLite y para configuraciones no estándar. El DSN debe apuntar a una base de datos MySQL o SQLite: CLI no puede registrar un controlador para otros motores.

Variable Descripción Ejemplo
MERQL_DB_DSN Cadena DSN de PDO completa sqlite:/path/to/db.sqlite
MERQL_DB_USER Nombre de usuario (opcional con DSN) root
MERQL_DB_PASS Contraseña (opcional con DSN) secret
Shell
# SQLite file.
export MERQL_DB_DSN="sqlite:/var/data/myapp.sqlite"

# MySQL via DSN.
export MERQL_DB_DSN="mysql:host=127.0.0.1;dbname=mydb;charset=utf8mb4"
export MERQL_DB_USER="root"
export MERQL_DB_PASS="secret"

Use una base de datos SQLite respaldada por un archivo. Cada comando CLI se ejecuta en su propio proceso, así que sqlite::memory: siempre abre una base de datos nueva y vacía, y la instantánea que se obtiene no contiene tablas.

Forma abreviada de MySQL

Si no se establece MERQL_DB_DSN, la CLI recurre a las variables específicas de MySQL.

Variable Valor predeterminado Descripción
MERQL_DB_NAME (obligatorio) Nombre de la base de datos
MERQL_DB_HOST 127.0.0.1 Host de MySQL
MERQL_DB_PORT 3306 Puerto de MySQL
MERQL_DB_USER root Nombre de usuario de MySQL
MERQL_DB_PASS (vacío) Contraseña de MySQL
MERQL_DB_ADAPTER pdo Establezca el valor mysqli para usar el adaptador mysqli
Shell
export MERQL_DB_NAME="wordpress"
export MERQL_DB_HOST="127.0.0.1"
export MERQL_DB_PORT="3306"
export MERQL_DB_USER="root"
export MERQL_DB_PASS="password"

Comandos

merql snapshot <name>

Capture el estado actual de la base de datos indicada por las variables de entorno y guárdelo como una instantánea con nombre. Este es el único comando que se conecta a una base de datos.

Shell
vendor/bin/merql snapshot baseline

Salida:

Código
Snapshot 'baseline' saved
Tables: posts, comments, users, settings

Las instantáneas se guardan como archivos JSON en .merql/snapshots/, dentro del directorio de trabajo (consulte Almacenamiento de instantáneas). El nombre solo puede contener caracteres alfanuméricos, guiones y guiones bajos.

Flujo de trabajo habitual: capture una instantánea antes de hacer cambios y, después, capture otra. Las dos instantáneas sirven de base para una comparación o una fusión.

merql diff <base> <current>

Compare dos instantáneas con nombre y muestre un resumen de las diferencias.

Shell
vendor/bin/merql diff baseline current

Salida:

Código
Changeset: baseline -> current
  Inserts: 3
  Updates: 7
  Deletes: 1

Ambas instantáneas deben existir de antemano (capturadas previamente con merql snapshot). La comparación no requiere conexión a una base de datos, ya que opera sobre archivos de instantáneas guardados.

merql merge <base> <ours> <theirs>

Realice una fusión de tres vías de tres instantáneas con nombre.

Shell
vendor/bin/merql merge base ours theirs

Salida:

Código
Merge: base + ours + theirs
  Operations: 12
  Conflicts:  0
  Clean:      yes

Las tres instantáneas deben existir de antemano. La fusión no requiere conexión a una base de datos, ya que opera sobre archivos de instantáneas guardados, y nunca escribe en una base de datos: CLI no tiene un comando apply. Use PHP API para aplicar el resultado de la fusión.

CLI fusiona a nivel de columna. No aplica la fusión a nivel de celda a las columnas TEXT ni JSON, por lo que dos modificaciones distintas en la misma columna siempre generan un conflicto (#7). Para fusionar a nivel de celda, use ThreeWayMerge con un CellMergeConfig en PHP.

--dry-run

Añada la opción --dry-run para previsualizar las instrucciones SQL que generaría la fusión, sin ejecutar nada. Las instrucciones describen cómo transformar el estado base en el resultado fusionado, por lo que incluyen los cambios de ambos lados.

Shell
vendor/bin/merql merge base ours theirs --dry-run

Salida:

Código
Merge: base + ours + theirs
  Operations: 3
  Conflicts:  0
  Clean:      yes

Dry run SQL:
  INSERT INTO `posts` (`id`, `title`, `status`) VALUES ('10', 'New Post', 'draft');
  UPDATE `posts` SET `title` = 'Updated Title' WHERE `id` = '5';
  DELETE FROM `comments` WHERE `id` = '3';

Comandos de desarrollo

Una copia del repositorio de merql incluye más scripts en bin/ para su conjunto de pruebas basado en un oráculo. No forman parte del paquete Composer, por lo que al instalarlo como dependencia solo se dispone de vendor/bin/merql. Ejecútelos desde la raíz del repositorio después de composer install.

Comando Descripción
./bin/oracle <name> Calcular el resultado esperado de una fusión para un escenario
./bin/actual <name> Ejecutar merql en un escenario y capturar la salida
./bin/compare <name> Comparar la salida del oráculo con la real
./bin/test-scenario <name> Flujo completo: configuración, oráculo, ejecución y comparación
./bin/test-regression Ejecutar todos los escenarios
./bin/test-regression --category clean Ejecutar una categoría: clean, conflict, identity, types, scale o edge
./bin/test-regression --fast Solo aprobado/suspenso, sin informes
./bin/verify-compliance Informe completo de cumplimiento
./bin/verify-all PHPStan + estilo de código + PHPUnit + regresión del oráculo

bin/test-regression también acepta --jobs, pero por ahora ignora el valor y ejecuta los escenarios uno tras otro (#5). Si se indica un --category desconocido, se muestra No scenarios found y se sale correctamente.

Consulte Estrategia de pruebas para ver la estructura de los escenarios.

Estado de salida

merql snapshot, diff y merge salen con el código 1 si falta un argumento; snapshot también lo hace si no hay ninguna conexión configurada. Si falta una instantánea, el comando termina con una SnapshotException no capturada y un código distinto de cero. Si se indica un comando desconocido, se muestra Unknown command, pero por ahora se sale con el código 0 (#3).

Almacenamiento de instantáneas

Las instantáneas se guardan en .merql/snapshots/, en relación con el directorio de trabajo. Cada instantánea es un único archivo JSON llamado <name>.json. Ejecute todos los comandos desde el mismo directorio para que encuentren las instantáneas de los demás.

CLI no ofrece ninguna opción ni variable de entorno para especificar otra ubicación (#8). Para usar otra, cambie a un directorio de trabajo distinto antes de ejecutarlo. En PHP, establezca el directorio antes de capturar o cargar instantáneas:

PHP
use Merql\Snapshot\SnapshotStore;

SnapshotStore::setDirectory('/var/data/merql-snapshots');

Los archivos de instantáneas son portátiles. Puede copiarlos entre máquinas, confirmarlos en el control de versiones o compartirlos para depurar en equipo. Una instantánea capturada por CLI se puede cargar en PHP con SnapshotStore::load(), y viceversa, siempre que ambos usen el mismo directorio.