Zum Inhalt springen

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

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

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:

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

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
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"

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
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"

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.

Shell
vendor/bin/merql snapshot baseline

Ausgabe:

Code
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.

Shell
vendor/bin/merql diff baseline current

Ausgabe:

Code
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.

Shell
vendor/bin/merql merge base ours theirs

Ausgabe:

Code
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.

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

Ausgabe:

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

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:

PHP
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.