Перейти до вмісту

Довідник CLI

До складу merql входить CLI для створення знімків, обчислення відмінностей і виконання злиття безпосередньо з термінала. Composer встановлює його як vendor/bin/merql; у клонованому репозиторії merql його шлях — bin/merql.

vendor/bin/merql працює після встановлення залежності, оскільки merql 0.4.1. У попередніх випусках Composer шукав автозавантажувач лише у власному каталозі пакета vendor/ і не працював, коли merql було встановлено як залежність.

Швидкий початок

Командна оболонка
# 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

Для тристороннього злиття потрібно створити знімки ours і theirs із двох баз даних, що розійшлися з base. Для кожного знімка вкажіть MERQL_DB_DSN правильну базу даних:

Командна оболонка
# 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

Створення всіх трьох знімків поспіль з однієї бази даних не дасть змоги виконати злиття: theirs уже міститиме зміни ours, тому кожен вставлений ours рядок буде позначено як конфлікт insert_insert.

Змінні середовища

CLI зчитує дані для підключення до бази даних зі змінних середовища. Підключитися можна за допомогою рядка PDO DSN або окремих параметрів MySQL.

Підключення на основі DSN

Для підключень на основі PDO використовуйте MERQL_DB_DSN. Цей рекомендований спосіб підходить для SQLite і нестандартних конфігурацій. DSN має вказувати на базу даних MySQL або SQLite: CLI не має способу зареєструвати драйвер для інших рушіїв.

Змінна Опис Приклад
MERQL_DB_DSN Повний рядок PDO DSN sqlite:/path/to/db.sqlite
MERQL_DB_USER Ім’я користувача (необов’язкове з DSN) root
MERQL_DB_PASS Пароль (необов’язковий з 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"

Використовуйте базу даних SQLite на основі файлу. Кожна команда CLI виконується в окремому процесі, тому sqlite::memory: щоразу відкриває нову порожню базу даних, а її знімок не містить таблиць.

Скорочений запис MySQL

Якщо MERQL_DB_DSN не задано, CLI використовує запасний варіант — змінні для MySQL.

Змінна Типове значення Опис
MERQL_DB_NAME (обов’язково) Назва бази даних
MERQL_DB_HOST 127.0.0.1 Хост MySQL
MERQL_DB_PORT 3306 Порт MySQL
MERQL_DB_USER root Ім’я користувача MySQL
MERQL_DB_PASS (порожнє) Пароль MySQL
MERQL_DB_ADAPTER pdo Установіть значення mysqli, щоб використовувати адаптер 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"

Команди

merql snapshot <name>

Зробіть знімок поточного стану бази даних, назву якої задано змінними середовища, і збережіть його під указаною назвою. Це єдина команда, яка підключається до бази даних.

Командна оболонка
vendor/bin/merql snapshot baseline

Вивід:

Код
Snapshot 'baseline' saved
Tables: posts, comments, users, settings

Знімки зберігаються як файли JSON у .merql/snapshots/ у робочому каталозі (див. Зберігання знімків). Назва має складатися лише з літер і цифр, дефісів та символів підкреслення.

Типовий робочий процес: створіть знімок до внесення змін, а потім ще один після них. Ці два знімки стануть основою для порівняння або злиття.

merql diff <base> <current>

Порівняйте два знімки за назвами й перегляньте зведення відмінностей.

Командна оболонка
vendor/bin/merql diff baseline current

Вивід:

Код
Changeset: baseline -> current
  Inserts: 3
  Updates: 7
  Deletes: 1

Обидва знімки мають уже існувати (їх потрібно попередньо створити за допомогою merql snapshot). Для порівняння не потрібне підключення до бази даних, оскільки операція працює зі збереженими файлами знімків.

merql merge <base> <ours> <theirs>

Виконайте тристороннє злиття трьох іменованих знімків.

Командна оболонка
vendor/bin/merql merge base ours theirs

Вивід:

Код
Merge: base + ours + theirs
  Operations: 12
  Conflicts:  0
  Clean:      yes

Усі три знімки мають уже існувати. Для злиття не потрібне підключення до бази даних, оскільки операція працює зі збереженими файлами знімків і ніколи не записує дані до бази: у CLI немає команди застосування. Щоб застосувати результат злиття, використовуйте PHP API.

CLI виконує злиття на рівні стовпців. Він не зливає на рівні комірок стовпці TEXT або JSON, тож дві різні зміни того самого стовпця завжди вважаються конфліктом (#7). Для злиття на рівні комірок використовуйте ThreeWayMerge із CellMergeConfig у PHP.

--dry-run

Додайте прапорець --dry-run, щоб попередньо переглянути оператори SQL, які згенерувало б злиття, нічого не виконуючи. Оператори описують перетворення базового стану на об’єднаний результат, тому містять зміни обох сторін.

Командна оболонка
vendor/bin/merql merge base ours theirs --dry-run

Вивід:

Код
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';

Команди розробки

У клонованому репозиторії merql є додаткові скрипти в bin/ для тестового набору, керованого оракулом. Вони не входять до пакета Composer, тому після встановлення залежності доступна лише vendor/bin/merql. Запускайте їх із кореня репозиторію після composer install.

Команда Опис
./bin/oracle <name> Обчислити очікуваний результат злиття для сценарію
./bin/actual <name> Запустити merql для сценарію та зберегти вивід
./bin/compare <name> Порівняти вивід оракула з фактичним
./bin/test-scenario <name> Повний конвеєр: налаштування, оракул, фактичний результат, порівняння
./bin/test-regression Запустити всі сценарії
./bin/test-regression --category clean Запустити одну категорію: clean, conflict, identity, types, scale або edge
./bin/test-regression --fast Лише результат «пройдено/не пройдено», без звітів
./bin/verify-compliance Повний звіт про відповідність
./bin/verify-all PHPStan + стиль коду + PHPUnit + регресійне тестування оракула

bin/test-regression також приймає --jobs, але наразі ігнорує його значення та запускає сценарії один за одним (#5). Якщо --category невідомий, виводиться No scenarios found, а команда завершується успішно.

Розташування сценаріїв описано в розділі Стратегія тестування.

Код завершення

merql snapshot, diff і merge завершуються зі статусом 1, якщо бракує аргументу; snapshot також завершується зі статусом 1, якщо не налаштовано підключення. Якщо знімка немає, команда завершується через необроблений виняток SnapshotException і повертає ненульовий статус. Якщо команда невідома, виводиться Unknown command, але наразі вона завершується зі статусом 0 (#3).

Зберігання знімків

Знімки зберігаються в .merql/snapshots/ відносно робочого каталогу. Кожен знімок — це окремий файл JSON з назвою <name>.json. Запускайте всі команди з одного каталогу, щоб вони знаходили знімки одна одної.

У CLI немає параметра чи змінної середовища для вибору іншого розташування (#8). Щоб використати інше розташування, перейдіть до іншого робочого каталогу перед запуском. У PHP задайте каталог перед збереженням або завантаженням знімків:

PHP
use Merql\Snapshot\SnapshotStore;

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

Файли знімків можна переносити. Ви можете копіювати їх між комп’ютерами, додавати до системи контролю версій або ділитися ними для спільного налагодження. Знімок, створений за допомогою CLI, можна завантажити в PHP за допомогою SnapshotStore::load(), і навпаки, якщо обидва використовують той самий каталог.