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
# 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:
# 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 |
# 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 |
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.
vendor/bin/merql snapshot baseline
Salida:
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.
vendor/bin/merql diff baseline current
Salida:
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.
vendor/bin/merql merge base ours theirs
Salida:
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.
vendor/bin/merql merge base ours theirs --dry-run
Salida:
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:
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.