CLI Referenz
merql enthält eine CLI, mit der du Snapshots erstellen, Unterschiede berechnen und Zusammenführungen direkt im Terminal ausführen kannst. Composer installiert sie unter vendor/bin/merql; in einem Checkout des merql-Repositorys findest du sie unter bin/merql.
vendor/bin/merql funktioniert seit merql 0.4.1 auch bei der Installation als Abhängigkeit. Frühere Versionen suchten den Composer-Autoloader nur im eigenen vendor/-Verzeichnis des Pakets und schlugen fehl, wenn merql als Abhängigkeit installiert war.
Schnellstart
# 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
Für eine Drei-Wege-Zusammenführung müssen ours und theirs von zwei Datenbanken stammen, die sich ausgehend von base auseinanderentwickelt haben. Verweise MERQL_DB_DSN für jeden Snapshot auf die passende Datenbank:
# 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
Alle drei Snapshots nacheinander aus derselben Datenbank zu erstellen, funktioniert nicht als Zusammenführung: theirs würde die Änderungen von ours bereits enthalten, sodass jede von ours eingefügte Zeile als insert_insert-Konflikt gemeldet würde.
Umgebungsvariablen
CLI liest Verbindungsdaten zur Datenbank aus Umgebungsvariablen. Du kannst entweder eine PDO-DSN-Zeichenfolge oder einzelne MySQL-Parameter verwenden.
Verbindung über DSN
Verwende MERQL_DB_DSN für PDO-basierte Verbindungen. Das ist der empfohlene Ansatz
für SQLite und nicht standardmäßige Konfigurationen. Die DSN muss auf eine MySQL-
oder SQLite-Datenbank verweisen: Der CLI kann keine Treiber für andere Engines registrieren.
| Variable | Beschreibung | Beispiel |
|---|---|---|
MERQL_DB_DSN |
Vollständige PDO-DSN-Zeichenfolge | sqlite:/path/to/db.sqlite |
MERQL_DB_USER |
Benutzername (optional mit DSN) | root |
MERQL_DB_PASS |
Passwort (optional mit 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"
Verwende eine dateibasierte SQLite-Datenbank. Jeder CLI-Befehl läuft in einem eigenen Prozess, daher
öffnet sqlite::memory: immer eine neue, leere Datenbank und ein Snapshot davon
enthält keine Tabellen.
MySQL-Kurzform
Wenn MERQL_DB_DSN nicht gesetzt ist, greift CLI auf MySQL-spezifische Variablen zurück.
| Variable | Standardwert | Beschreibung |
|---|---|---|
MERQL_DB_NAME |
(erforderlich) | Datenbankname |
MERQL_DB_HOST |
127.0.0.1 |
MySQL-Host |
MERQL_DB_PORT |
3306 |
MySQL-Port |
MERQL_DB_USER |
root |
MySQL-Benutzername |
MERQL_DB_PASS |
(leer) | MySQL-Passwort |
MERQL_DB_ADAPTER |
pdo |
Auf mysqli setzen, um den mysqli-Adapter zu verwenden |
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"
Befehle
merql snapshot <name>
Erfasse den aktuellen Stand der Datenbank, die durch die Umgebungsvariablen angegeben ist, und speichere ihn als benannten Snapshot. Nur dieser Befehl stellt eine Verbindung zu einer Datenbank her.
vendor/bin/merql snapshot baseline
Ausgabe:
Snapshot 'baseline' saved
Tables: posts, comments, users, settings
Snapshots werden als JSON-Dateien in .merql/snapshots/ im Arbeitsverzeichnis gespeichert (siehe Snapshot-Speicherung). Der Name darf nur alphanumerische Zeichen, Bindestriche und Unterstriche enthalten.
Typischer Ablauf: Erstelle vor Änderungen einen Snapshot und danach einen weiteren. Die beiden Snapshots bilden die Grundlage für einen Vergleich oder eine Zusammenführung.
merql diff <base> <current>
Vergleiche zwei benannte Snapshots und zeige eine Zusammenfassung der Unterschiede an.
vendor/bin/merql diff baseline current
Ausgabe:
Changeset: baseline -> current
Inserts: 3
Updates: 7
Deletes: 1
Beide Snapshots müssen bereits vorhanden sein (zuvor mit merql snapshot erstellt). Der Vergleich benötigt keine Datenbankverbindung, da er mit gespeicherten Snapshot-Dateien arbeitet.
merql merge <base> <ours> <theirs>
Führe drei benannte Snapshots zusammen.
vendor/bin/merql merge base ours theirs
Ausgabe:
Merge: base + ours + theirs
Operations: 12
Conflicts: 0
Clean: yes
Alle drei Snapshots müssen bereits vorhanden sein. Die Zusammenführung benötigt keine Datenbankverbindung, da sie mit gespeicherten Snapshot-Dateien arbeitet, und schreibt niemals in eine Datenbank: Die CLI hat keinen Anwendungsbefehl. Verwende PHP API, um ein Zusammenführungsergebnis anzuwenden.
CLI führt Zusammenführungen auf Spaltenebene aus. TEXT- oder JSON-Spalten werden nicht auf Zellenebene zusammengeführt. Daher führen zwei unterschiedliche Änderungen derselben Spalte hier immer zu einem Konflikt (#7). Verwende ThreeWayMerge mit einem CellMergeConfig in PHP für Zusammenführungen auf Zellenebene.
--dry-run
Füge das Flag --dry-run hinzu, um die SQL-Anweisungen anzuzeigen, die bei der Zusammenführung erzeugt würden, ohne etwas auszuführen. Die Anweisungen zeigen, wie der Basiszustand in das zusammengeführte Ergebnis überführt wird, und enthalten daher die Änderungen beider Seiten.
vendor/bin/merql merge base ours theirs --dry-run
Ausgabe:
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';
Entwicklungsbefehle
Ein Checkout des merql-Repositorys enthält unter bin/ weitere Skripte für die oracle-gesteuerte Testsuite. Sie sind nicht Teil des Composer-Pakets, daher steht bei einer Installation als Abhängigkeit nur vendor/bin/merql zur Verfügung. Führe sie nach composer install im Stammverzeichnis des Repositorys aus.
| Befehl | Beschreibung |
|---|---|
./bin/oracle <name> |
Erwartetes Zusammenführungsergebnis für ein Szenario berechnen |
./bin/actual <name> |
merql für ein Szenario ausführen und die Ausgabe erfassen |
./bin/compare <name> |
oracle- und tatsächliche Ausgabe vergleichen |
./bin/test-scenario <name> |
Vollständige Pipeline: Setup, oracle, tatsächliche Ausgabe, Vergleich |
./bin/test-regression |
Alle Szenarien ausführen |
./bin/test-regression --category clean |
Eine Kategorie ausführen: clean, conflict, identity, types, scale oder edge |
./bin/test-regression --fast |
Nur Erfolg oder Fehler, keine Berichte |
./bin/verify-compliance |
Vollständiger Konformitätsbericht |
./bin/verify-all |
PHPStan + Code-Stil + PHPUnit + oracle-Regression |
bin/test-regression akzeptiert auch --jobs, ignoriert den Wert derzeit jedoch und führt die Szenarien nacheinander aus (#5). Ein unbekanntes --category gibt No scenarios found aus und wird erfolgreich beendet.
Eine Beschreibung des Szenarioaufbaus findest du unter Testing Strategy.
Exit-Status
merql snapshot, diff und merge werden mit Status 1 beendet, wenn ein Argument fehlt; snapshot auch, wenn keine Verbindung konfiguriert ist. Fehlt ein Snapshot, endet der Befehl mit einem nicht abgefangenen SnapshotException und einem Status ungleich null. Ein unbekannter Befehl gibt Unknown command aus, wird derzeit aber mit Status 0 beendet (#3).
Snapshot-Speicherort
Snapshots werden relativ zum Arbeitsverzeichnis unter .merql/snapshots/ gespeichert. Jeder Snapshot ist eine einzelne JSON-Datei namens <name>.json. Führe alle Befehle im selben Verzeichnis aus, damit sie die Snapshots der anderen finden.
Für CLI gibt es keine Option und keine Umgebungsvariable für einen anderen Speicherort (#8). Wechsle vor dem Ausführen in ein anderes Arbeitsverzeichnis, um einen anderen Speicherort zu verwenden. Lege in PHP das Verzeichnis fest, bevor du Snapshots erstellst oder lädst:
use Merql\Snapshot\SnapshotStore;
SnapshotStore::setDirectory('/var/data/merql-snapshots');
Snapshot-Dateien sind portabel. Du kannst sie zwischen Rechnern kopieren, in die Versionsverwaltung übernehmen oder zur gemeinsamen Fehlersuche teilen. Einen mit CLI erstellten Snapshot kannst du mit SnapshotStore::load() in PHP laden und umgekehrt, sofern beide dasselbe Verzeichnis verwenden.