Aller au contenu

Référence CLI

merql inclut une CLI pour capturer des instantanés, calculer des différences et exécuter des fusions directement depuis le terminal. Composer l'installe sous le nom vendor/bin/merql ; dans une copie du dépôt merql, il s'agit de bin/merql.

vendor/bin/merql fonctionne après une installation de dépendance, car merql 0.4.1. Les versions précédentes recherchaient le chargeur automatique Composer uniquement dans le répertoire vendor/ propre au paquet et échouaient lorsque merql était installé comme dépendance.

Démarrage rapide

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

Une fusion à trois voies nécessite que les instantanés « ours » et « theirs » proviennent de deux bases de données qui ont divergé à partir de « base ». Indiquez à MERQL_DB_DSN la base de données appropriée pour chaque instantané :

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

Prendre les trois instantanés de la même base de données l'un après l'autre ne fonctionne pas pour une fusion : « theirs » contiendrait déjà les changements de « ours », et chaque ligne insérée par « ours » serait signalée comme un conflit insert_insert.

Variables d’environnement

CLI lit les détails de connexion à la base de données dans les variables d'environnement. Vous pouvez vous connecter à l'aide d'une chaîne DSN PDO ou de paramètres MySQL individuels.

Connexion basée sur DSN

Utilisez MERQL_DB_DSN pour les connexions basées sur PDO. C'est l'approche recommandée pour SQLite et les configurations non standard. Le DSN doit pointer vers une base de données MySQL ou SQLite : CLI ne peut pas enregistrer de pilote pour d'autres moteurs.

Variable Description Exemple
MERQL_DB_DSN Chaîne DSN PDO complète sqlite:/path/to/db.sqlite
MERQL_DB_USER Nom d'utilisateur (facultatif avec DSN) root
MERQL_DB_PASS Mot de passe (facultatif avec 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"

Utilisez une base de données SQLite adossée à un fichier. Chaque commande CLI s'exécute dans son propre processus ; sqlite::memory: ouvre donc toujours une nouvelle base de données vide, dont l'instantané ne contient aucune table.

Raccourci MySQL

Lorsque MERQL_DB_DSN n'est pas défini, CLI utilise les variables propres à MySQL en solution de repli.

Variable Valeur par défaut Description
MERQL_DB_NAME (requis) Nom de la base de données
MERQL_DB_HOST 127.0.0.1 Hôte MySQL
MERQL_DB_PORT 3306 Port MySQL
MERQL_DB_USER root Nom d'utilisateur MySQL
MERQL_DB_PASS (vide) Mot de passe MySQL
MERQL_DB_ADAPTER pdo Définissez sur mysqli pour utiliser l'adaptateur 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"

Commandes

merql snapshot <name>

Capturez l'état actuel de la base de données désignée par les variables d'environnement et enregistrez-le sous forme d'instantané nommé. C'est la seule commande qui se connecte à une base de données.

Shell
vendor/bin/merql snapshot baseline

Sortie :

Code
Snapshot 'baseline' saved
Tables: posts, comments, users, settings

Les instantanés sont enregistrés sous forme de fichiers JSON dans .merql/snapshots/, sous le répertoire de travail (voir Stockage des instantanés). Le nom ne doit contenir que des caractères alphanumériques, des tirets et des traits de soulignement.

Workflow courant : capturez un instantané avant d'effectuer des modifications, puis capturez-en un autre après. Les deux instantanés servent de base à une comparaison ou à une fusion.

merql diff <base> <current>

Comparez deux instantanés nommés et affichez un résumé des différences.

Shell
vendor/bin/merql diff baseline current

Sortie :

Code
Changeset: baseline -> current
  Inserts: 3
  Updates: 7
  Deletes: 1

Les deux instantanés doivent déjà exister (avoir été capturés précédemment avec merql snapshot). La comparaison ne nécessite pas de connexion à une base de données, car elle utilise les fichiers d'instantané enregistrés.

merql merge <base> <ours> <theirs>

Effectuez une fusion à trois voies de trois instantanés nommés.

Shell
vendor/bin/merql merge base ours theirs

Sortie :

Code
Merge: base + ours + theirs
  Operations: 12
  Conflicts:  0
  Clean:      yes

Les trois instantanés doivent déjà exister. La fusion ne nécessite pas de connexion à une base de données, car elle utilise les fichiers d'instantané enregistrés, et elle n'écrit jamais dans une base de données : la CLI ne possède pas de commande d'application. Utilisez la PHP API pour appliquer un résultat de fusion.

La CLI effectue les fusions au niveau des colonnes. Elle ne fusionne pas les cellules des colonnes TEXT ou JSON ; deux modifications différentes de la même colonne constituent donc toujours un conflit (#7). Utilisez ThreeWayMerge avec une CellMergeConfig dans PHP pour fusionner au niveau des cellules.

--dry-run

Ajoutez l'option --dry-run pour prévisualiser les instructions SQL que la fusion générerait, sans rien exécuter. Ces instructions décrivent comment transformer l'état de base en résultat fusionné ; elles incluent donc les changements des deux côtés.

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

Sortie :

Code
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';

Commandes de développement

Une copie du dépôt merql contient davantage de scripts dans bin/ pour sa suite de tests pilotée par oracle. Ils ne font pas partie du paquet Composer ; une installation de dépendance ne fournit donc que vendor/bin/merql. Exécutez-les depuis la racine du dépôt après composer install.

Commande Description
./bin/oracle <name> Calculer le résultat de fusion attendu pour un scénario
./bin/actual <name> Exécuter merql pour un scénario et capturer la sortie
./bin/compare <name> Comparer la sortie de l'oracle à la sortie réelle
./bin/test-scenario <name> Pipeline complet : configuration, oracle, exécution, comparaison
./bin/test-regression Exécuter tous les scénarios
./bin/test-regression --category clean Exécuter une catégorie : clean, conflict, identity, types, scale ou edge
./bin/test-regression --fast Réussite ou échec seulement, sans rapports
./bin/verify-compliance Rapport de conformité complet
./bin/verify-all PHPStan + style de code + PHPUnit + régression de l'oracle

bin/test-regression accepte aussi --jobs, mais ignore actuellement la valeur et exécute les scénarios l'un après l'autre (#5). Une valeur --category inconnue affiche No scenarios found et se termine avec succès.

Voir Stratégie de test pour la structure des scénarios.

Code de sortie

merql snapshot, diff et merge se terminent avec le code 1 lorsqu'un argument est manquant, et snapshot le fait aussi lorsqu'aucune connexion n'est configurée. Un instantané manquant interrompt la commande avec une SnapshotException non interceptée et un code différent de zéro. Une commande inconnue affiche Unknown command, mais se termine actuellement avec le code 0 (#3).

Stockage des instantanés

Les instantanés sont stockés dans .merql/snapshots/ par rapport au répertoire de travail. Chaque instantané est un fichier JSON unique nommé <name>.json. Exécutez toutes les commandes depuis le même répertoire afin qu'elles trouvent les instantanés des autres.

La CLI ne propose aucune option ni variable d'environnement pour choisir un autre emplacement (#8). Pour en utiliser un autre, changez de répertoire de travail avant de l'exécuter. Dans PHP, définissez le répertoire avant de capturer ou de charger des instantanés :

PHP
use Merql\Snapshot\SnapshotStore;

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

Les fichiers d'instantané sont portables. Vous pouvez les copier d'une machine à l'autre, les valider dans le contrôle de version ou les partager pour déboguer en collaboration. Un instantané capturé par la CLI peut être chargé dans PHP avec SnapshotStore::load(), et inversement, à condition que les deux utilisent le même répertoire.