CLI 참조
merql에는 터미널에서 직접 스냅샷을 만들고 차이를 계산하며 병합을 실행하는 CLI이 포함되어 있습니다. Composer은 이를 vendor/bin/merql로 설치하며, merql 저장소를 체크아웃하면 bin/merql입니다.
merql이 0.4.1을 제공하므로 vendor/bin/merql은 종속성으로 설치해도 작동합니다. 이전 릴리스는 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
3방향 병합을 하려면 base에서 분기된 두 데이터베이스에서 ours와 theirs 스냅샷을 캡처해야 합니다. 각 스냅샷에 맞는 데이터베이스를 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
스냅샷은 작업 디렉터리 아래 .merql/snapshots/에 JSON 파일로 저장됩니다(스냅샷 저장 참고). 이름에는 영숫자, 하이픈, 밑줄만 사용할 수 있습니다.
일반적인 워크플로는 변경 전 스냅샷을 캡처한 뒤 변경 후에 하나 더 캡처하는 것입니다. 두 스냅샷을 바탕으로 차이를 계산하거나 병합합니다.
merql diff <base> <current>
이름이 지정된 두 스냅샷을 비교하고 차이 요약을 표시합니다.
vendor/bin/merql diff baseline current
출력:
Changeset: baseline -> current
Inserts: 3
Updates: 7
Deletes: 1
두 스냅샷이 모두 이미 있어야 합니다(merql snapshot으로 이전에 캡처). 저장된 스냅샷 파일을 대상으로 작업하므로 diff에는 데이터베이스 연결이 필요하지 않습니다.
merql merge <base> <ours> <theirs>
이름이 지정된 세 스냅샷을 3방향으로 병합합니다.
vendor/bin/merql merge base ours theirs
출력:
Merge: base + ours + theirs
Operations: 12
Conflicts: 0
Clean: yes
세 스냅샷이 모두 이미 있어야 합니다. 저장된 스냅샷 파일을 대상으로 작업하고 데이터베이스에 기록하지 않으므로 병합에는 데이터베이스 연결이 필요하지 않습니다. CLI에는 apply 명령이 없습니다. 병합 결과를 적용하려면 PHP API를 사용합니다.
CLI은 열 수준에서 병합합니다. TEXT 또는 JSON 열에는 셀 수준 병합을 적용하지 않으므로 같은 열을 서로 다르게 편집하면 항상 충돌합니다(#7). 셀 수준 병합에는 PHP의 CellMergeConfig와 함께 ThreeWayMerge를 사용합니다.
--dry-run
--dry-run 플래그를 추가하면 아무 작업도 실행하지 않고 병합으로 생성될 SQL 문을 미리 볼 수 있습니다. 이 문은 base 상태를 병합된 결과로 바꾸는 방법을 나타내므로 양쪽의 변경 사항이 모두 포함됩니다.
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로 명령이 끝나고 0이 아닌 상태를 반환합니다. 알 수 없는 명령은 Unknown command를 출력하지만 현재 상태 0으로 종료합니다(#3).
스냅샷 저장
스냅샷은 작업 디렉터리 기준 .merql/snapshots/에 저장됩니다. 각 스냅샷은 <name>.json라는 이름의 단일 JSON 파일입니다. 서로의 스냅샷을 찾을 수 있도록 모든 명령을 같은 디렉터리에서 실행합니다.
CLI에는 다른 위치를 지정하는 옵션이나 환경 변수가 없습니다(#8). 다른 위치를 사용하려면 실행 전에 작업 디렉터리를 변경합니다. PHP에서 스냅샷을 캡처하거나 불러오기 전에 디렉터리를 설정합니다.
use Merql\Snapshot\SnapshotStore;
SnapshotStore::setDirectory('/var/data/merql-snapshots');
스냅샷 파일은 이식 가능합니다. 컴퓨터 간에 복사하거나 버전 관리에 커밋하거나 공동 디버깅을 위해 공유할 수 있습니다. CLI으로 캡처한 스냅샷은 두 환경에서 같은 디렉터리를 사용하는 경우 PHP에서 SnapshotStore::load()로 불러올 수 있으며, 반대 방향도 가능합니다.