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