Difflock - це Laravel-пакет від Rati Rukhadze, призначений для перевірки міграцій відносно бази даних, яку вони змінюватимуть. Він читає вихідний код міграції без її завантаження чи виконання, а потім використовує поточну схему та метадані про розмір таблиць, щоб позначити зміни, які потребують уважнішого огляду перед розгортанням.
Основні можливості Difflock
Пакет включає наступний функціонал:
- Лінтинг міграцій для виявлення деструктивних операцій, змін колонок, індексів, зовнішніх ключів та чутливих назв колонок
- Базові знімки схеми, збережені у форматі JSON, які дозволяють порівнювати базу даних із збереженим знімком або іншим підключенням
- Захист міграцій, що виконує перевірки перед передачею контролю команді
migrate Laravel
- Перевірки для CI з кодами виходу для ризикованих міграцій, відхилень схеми та помилок конфігурації
- Інструменти MCP для перевірки таблиці, файлу міграції або вихідного коду міграції, утримуваного в контексті агента
Перевірка міграцій, що очікують виконання
Команда difflock:lint за замовчуванням аналізує міграції, які очікують на виконання. Міграція, подібна до наведеної нижче, може виглядати звичайно у pull request:
Schema::table('orders', function (Blueprint $table) {
$table->string('channel');
$table->foreignId('customer_id')->constrained()->cascadeOnDelete();
$table->string('card_number', 32)->nullable();
$table->index('status');
});
Schema::table('customers', function (Blueprint $table) {
$table->dropColumn('legacy_token');
$table->renameColumn('name', 'full_name');
});
На заповненій базі даних Difflock може позначити колонку channel без значення за замовчуванням (non-null), деструктивний виклик dropColumn() та перейменування колонки. Він також повідомляє, що cascadeOnDelete() видаляє дочірні рядки безпосередньо в базі даних, що обходить події моделей, спостерігачів та м'яке видалення.
Пакет має правила для змін, які статичні перевірки порожньої тестової бази даних можуть пропустити. Правило change-column порівнює виклик ->change() з поточним визначенням колонки. unindexed-foreign-key перевіряє, чи додає рушій бази даних індекс, необхідний для зовнішнього ключа. redundant-index повідомляє про певний випадок префіксу, наприклад, додавання індексу на (status), коли (status, created_at) вже існує.
Варіанти використання команди
Використовуйте прапорець -v для розгорнутого відображення результатів або --rule= для фокусування на одному правилі:
php artisan difflock:lint
php artisan difflock:lint -v
php artisan difflock:lint --rule=drop-column
Коли у додатку немає міграцій, що очікують виконання, команда перевіряє всі файли міграцій замість того, щоб видавати порожній звіт. Існуючі проекти можуть прийняти свій поточний беклог за допомогою php artisan difflock:lint --all --accept, а потім використовувати отриманий файл database/difflock/accepted.json як базовий для нових знахідок.
Відстеження відхилень схеми
Difflock записує спостережувану схему замість відновлення очікуваної схеми з файлів міграцій. Це дозволяє уникнути спроб інтерпретації міграцій, що містять умовні конструкції, цикли або сирий SQL.
php artisan difflock:diff --save
Ця команда записує файл database/difflock/schema.json, який можна зберегти у системі контролю версій. Пізніше команда php artisan difflock:diff порівнює поточне підключення з цим файлом. Ви також можете порівняти два налаштованих підключення:
php artisan difflock:diff --from=staging --to=production
Базовий знімок містить структуру схеми, включаючи таблиці, колонки, індекси, значення за замовчуванням та зовнішні ключі. Він не включає рядки таблиць або облікові дані. Налаштування snapshot.defaults, snapshot.comments та ignore.tables дозволяють обмежити те, що записується.
Захист міграцій та інтеграція з CI
Встановлення Difflock не змінює поведінку команди php artisan migrate. Пакет захищає міграції лише коли ви використовуєте його власну команду:
php artisan difflock:migrate
Вона спочатку аналізує міграції, що очікують виконання. Коли знахідки досягають налаштованого рівня блокування, вона зупиняється до того, як Laravel почне запис у базу даних. Прапорець --allow-risky навмисно обходить захист Difflock, тоді як прапорець --force Laravel залишається окремим прапорцем для підтвердження на продакшені.
Використання в CI/CD
Для CI запускайте перевірку відхилень та лінтинг міграцій разом:
run: php artisan difflock:check --ci
Команда завершується з кодом 0, коли перевірка пройшла успішно, 1 - для відхилень або знахідок на налаштованому порозі, та 2 - коли перевірку неможливо виконати. Вона все ще може аналізувати правила, що стосуються лише вихідного коду, без підключення до бази даних, але повідомляє, що дані таблиці були недоступні.
Підтримка MCP
Команда php artisan difflock:mcp запускає автономний MCP-сервер через stdio. Його чотири інструменти надають контекст таблиці, лінтинг міграцій, перевірки відхилень схеми та документацію правил.
Інструмент міграції приймає або шлях до файлу, або текст вихідного коду. AI-агент кодування може перевірити міграцію перед записом файлу, використовуючи поточну схему бази даних та статистику таблиць. Пакет також включає команду difflock:explain, яка створює Markdown-брифінг для міграції без виклику мовної моделі чи будь-якого зовнішнього API.
Встановлення та налаштування
Difflock 1.0.0 потребує PHP 8.3 і підтримує Laravel 12 та 13. Він працює з MySQL, MariaDB, PostgreSQL та SQLite.
composer require heyosseus/difflock --dev
php artisan vendor:publish --tag=difflock-config
php artisan difflock:doctor
Команда difflock:doctor виводить інформацію про підключення, доступні таблиці, міграції, що очікують виконання, зареєстровані правила та чи може налаштована роль бази даних виконувати запис. Роль лише для читання є розумним вибором, коли ви хочете, щоб Difflock перевіряв продакшн-підключення.
Difflock доступний на GitHub.