Changelog
All notable changes to Laravel Migration Linter are documented here.
This project follows Semantic Versioning.
๐ [v2.1.1] โ 2026-03-03โ
๐ Fixedโ
-
migrate:lint no longer tries to write HTML report by default
- Fixed --html option parsing so plain php artisan migrate:lint does not attempt report generation.
- Prevents invalid ? path writes on Windows environments (Git Bash / Laragon / XAMPP users).
-
Safer HTML path resolution when --html is provided
- --html now generates to default path storage/app/migration-lint-report.html when no custom path is supplied.
- Custom --html=your/path/report.html behavior remains unchanged.
๐งช Developerโ
- Added regression tests to prevent future --html option handling breakage.
- Removed hardcoded package
versionfrom composer.json so Packagist versioning is fully tag-driven.
๐ [v2.1.0] โ 2025-12-24โ
๐ Addedโ
-
New Rule:
RenamingColumnWithoutIndexโ Detects column rename operations that can cause table locks and downtime- Warns when using
$table->renameColumn()on large tables - Provides 3-phase zero-downtime migration strategy
- Configurable to check large tables only or all tables
- Supports safe comment bypass:
// safe rename
- Warns when using
-
New Rule:
ChangeColumnTypeOnLargeTableโ Detects column type changes that can cause table locks- Detects 25+ column type methods with
->change()modifier (string, integer, decimal, text, datetime, boolean, enum, etc.) - Default severity: error (high impact operation)
- Provides 3 migration strategies: zero-downtime, maintenance window, pt-online-schema-change
- Supports safe comment bypass:
// safe change,// maintenance window
- Detects 25+ column type methods with
-
New Flag:
--no-suggestionsโ Hide migration suggestions for cleaner output- Useful when you only want to see the warnings table
- Can be combined with
--summaryfor minimal output
-
New Flag:
--html=โ Generate interactive HTML reports- Beautiful, responsive HTML reports with charts and visualizations
- Searchable and filterable issue table
- Grouped suggestions organized by rule type
- Rule breakdown with statistics
- Perfect for sharing with team members and CI/CD artifacts
- Example:
php artisan migrate:lint --html=storage/report.html
โ๏ธ Improvedโ
-
Enhanced MigrationParser โ Now properly skips commented-out lines
- Lines starting with
//or/*are ignored during parsing - Prevents false positives from commented code
- Tracks previous line context for safe comment detection
- Lines starting with
-
Better Safe Comment Detection โ Comments on line above operations are now recognized
// safe renameon line before operation works correctly/* safe rename */before operation works correctly- Inline comments continue to work:
$table->renameColumn(...); // safe rename
-
Improved Suggestion Output Formatting โ Cleaner, more organized display
- Suggestions now grouped by rule type instead of repeated for each occurrence
- Added visual hierarchy with section headers and separators
- Shows occurrence count per rule (e.g., "3 occurrences")
- Better indentation and color coding for readability
- Professional CLI output with proper spacing
๐งฐ Developerโ
- Added 13 comprehensive unit tests for
RenamingColumnWithoutIndexrule - Added 16 comprehensive unit tests for
ChangeColumnTypeOnLargeTablerule - Added 12 comprehensive unit tests for
HtmlReporterclass - Total: 84 tests passing (200 assertions)
- Parser improvements benefit all existing rules
- Enhanced rawCode context includes previous line for better analysis
- New
HtmlReporterclass for generating interactive reports
๐ [1.0.0] โ 2025-10-15โ
๐ Addedโ
- Core Artisan command:
php artisan migrate:lint
Base rules:
- AddNonNullableColumnWithoutDefault
- MissingIndexOnForeignKey
- Config publishing (php artisan vendor:publish --tag="migration-linter-config")
- Baseline file support (--generate-baseline, --baseline=path)
- JSON output mode (--json)
- Compact report output for smaller terminals.
๐งฉ [1.1.0] โ 2025-10-21โ
๐ Addedโ
DropColumnWithoutBackuprule โ warns when columns are dropped without confirmation or backup.AddUniqueConstraintOnNonEmptyColumnrule โ warns when adding unique constraints that might fail on existing data.FloatColumnForMoneyrule โ warns when usingfloat()for monetary fields; recommendsdecimal(10,2)instead.
โ๏ธ Improvedโ
- Enhanced output formatting for compact mode (
--compact) on smaller terminals. - Configuration system now supports custom rules from any namespace (e.g.,
App\MigrationRules).
๐งฐ Developerโ
- Added rule discovery improvements in
RuleEngine. - Documentation updates (
rules.md,writing-custom-rules.md, andconfiguration.md).
New Rulesโ
Initial public release with baseline rule set:
- AddNonNullableColumnWithoutDefault
- MissingIndexOnForeignKey
- DropColumnWithoutBackup
- AddUniqueConstraintOnNonEmptyColumn
- FloatColumnForMoney
[v1.2.0] โ 2025-10-30โ
โจ Addedโ
- AddNonNullableColumnWithoutDefault
- Detects
.change()on existing columns. - Skips
Schema::create()(safe for new tables).
- Detects
- MissingIndexOnForeignKey
- Detects
foreignId()without->constrained(). - Detects
morphs()/nullableMorphs()without->index(). - Detects composite
foreign([...])without matchingindex([...]).
- Detects
- DropColumnWithoutBackup
- Detects multiple column drops.
- Supports safe comment whitelist (
// safe dropor/* safe-drop */).
- AddUniqueConstraintOnNonEmptyColumn
- Detects composite unique constraints.
- Detects inline
->unique()and->unique()->change(). - Configurable
check_compositeflag.
- FloatColumnForMoney
- Detects
float(),double(), andreal()for money-like columns. - Smarter pattern matching (price, amount, total, tax, etc.).
- Configurable toggles:
check_doubleandcheck_real.
- Detects
๐งฐ Improvedโ
- Unified severity handling via config.
- More informative lint messages for each rule.
- Enhanced documentation and configuration examples.
๐ Fixedโ
- Config overrides now correctly respect
enabled = false. - RuleEngine dynamically skips disabled rules during lint runs.
๐ ๏ธ [2.0.0] โ 2025-11-20โ
โจ Added (SOLID Principles Refactoring)โ
- 8 Core Interfaces โ Dependency injection contracts
ConfigInterface,FormatterInterface,ParserInterface,RuleInterface,RuleEngineInterfaceSeverityResolverInterface,ReporterInterface,BaselineInterface
- 3 Service Classes โ Reusable business logic
LaravelConfigProviderโ Bridges Laravel config to contractsSeverityResolverโ Priority-based severity determinationLintServiceโ Orchestrates entire linting workflow
- 5 Formatter Classes โ Modular output system
TableFormatterโ Console table format (with Symfony Table component)JsonFormatterโ JSON output for CI/CDCompactFormatterโ Single-line compact formatSummaryFormatterโ Table + statisticsBaseFormatterโ Shared utilities for all formatters
๐ง Improvedโ
- SOLID Principles throughout:
- Single Responsibility โ Each formatter, service, rule has one job
- Open/Closed โ Add new formatters/services without modifying existing code
- Liskov Substitution โ All formatters interchangeable via interface
- Interface Segregation โ Small, focused contracts
- Dependency Inversion โ Depend on interfaces, not implementations
- Table Formatting โ Fixed color code alignment
- Switched to Symfony's native
Tablecomponent - Perfect column alignment regardless of content
- Proper text wrapping and spacing
- Switched to Symfony's native
- Dependency Injection โ Service provider auto-wiring
- Laravel container bindings for all services
- Automatic resolver injection into rules
- Testable with mocked interfaces
โ Qualityโ
- 144 tests passing (259 assertions)
- 100% backward compatible (zero breaking changes)
- ~95% code coverage (excellent test quality)
๐ Migrationโ
All commands work identically โ no breaking changes:
php artisan migrate:lint # Still works
php artisan migrate:lint --json # Still works
php artisan migrate:lint --compact # Still works
php artisan migrate:lint --summary # Still works
php artisan migrate:lint --rules # Still works
๐ฏ [1.4.0] โ 2025-11-15โ
โจ Added (Phase 3: UX Improvements + New Rule)โ
- Actionable Suggestions โ Every issue now includes
suggestionfield with fix recommendations- Suggestions appear in CLI output after the lint table with
[Suggestion #N]headers - Suggestions included in JSON output as
suggestionfield for tool integration - Each suggestion provides clear, actionable next steps
- Suggestions appear in CLI output after the lint table with
- Documentation Links โ Issues now include optional
docsUrlfield- Links appear in CLI with ๐ icon and full URL
- JSON output includes
docs_urlfield for programmatic access - All built-in rules updated with relevant documentation links
- New Rule: SoftDeletesOnProduction โ Warns about soft deletes on large tables
- Detects
softDeletes()on tables inlarge_table_namesconfig - Provides 3 alternatives: archive, hard delete, or add index on deleted_at
- Includes suggestions and documentation links
- Detects
- Enhanced AbstractRule.warn() โ Signature extended to accept
$suggestionand$docsUrlparameters- Fully backward compatible (optional parameters)
- Enables custom rule authors to provide rich feedback
๐งฐ Improvedโ
- Reporter System: Enhanced
renderTable()andrenderJson()to display/include suggestions - Built-in Rules Updated: AddNonNullableColumnWithoutDefault and MissingIndexOnForeignKey now include actionable suggestions
- Documentation: Updated usage.md, rules.md, writing-custom-rules.md, ci-cd.md with new features and rules
- Developer Experience: Custom rule authors can now provide suggestions via
warn()method
๐ Example Outputโ
[warning] SoftDeletesOnProduction
โ Using soft deletes on the 'users' table may impact query performance over time.
[Suggestion #1] SoftDeletesOnProduction:
Option 1: Archive old data to a separate table
Option 2: Use hard deletes if retention isn't required
Option 3: Add an index on 'deleted_at' to improve query performance
๐ Learn more: https://docs.example.com/rules#-softdeletesonproduction
โจ Overviewโ
- Changes fully backward compatible with v1.3.x
- Total rule count: 6 rules (5 original + 1 new)
๐ง Tip: You can always check your installed version via Composer:
composer show sufyandev/laravel-migration-linter
Or compare changes on GitHub:
๐ muhammad-sufyan5/sufyan-laravel-migration-lint-package