close
Skip to content

Register the native database commands under their own names - #142

Open
gwleuverink wants to merge 3 commits into
mainfrom
fix/native-command-signatures
Open

Register the native database commands under their own names#142
gwleuverink wants to merge 3 commits into
mainfrom
fix/native-command-signatures

Conversation

@gwleuverink

@gwleuverink gwleuverink commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

On Laravel 13.24 and up, FreshCommand and WipeDatabaseCommand register under Laravel's names instead of their own. artisan list dies with "The native:migrate:fresh command cannot be found because it is registered under multiple names" (#134), and php artisan migrate:fresh silently wipes database/nativephp.sqlite instead of the app's database (#135).

Both commands rename their parent by setting $name. Laravel 13.24 changed Illuminate\Database\Console\Migrations\FreshCommand and Illuminate\Database\Console\WipeCommand to declare $signature where they used $name before. Illuminate\Console\Command::__construct() checks isset($this->signature) first, and the child inherits the parent's, so $name is never read. native:db:wipe becomes a second db:wipe, and because Laravel's own migrate:fresh calls db:wipe by name, it lands in NativePHP's version, which switches the default connection to nativephp before dropping every table.

Declaring $signature on both keeps the native name and carries the parent's options across, which parent::handle() still reads. The option lists are identical on Laravel 10, 11, 12 and 13, so this holds everywhere the package is supported.

While in here, all four native database commands are put on one convention, since the inconsistency between them is what made this bite. Illuminate\Console\Application::resolve() reads #[AsCommand] by reflection and registers the class lazily under that name, then construction names it again from the signature. When the two disagree you get #134, so they have to stay in step. WipeDatabaseCommand had no attribute at all and was the only one being eagerly instantiated, so it gets one.

The attribute's description argument was dead on all of them. Command::__construct() applies $this->description after configureFromAttributes(), so native:migrate and native:seed were inheriting Laravel's wording and listing as "Run the database migrations" and "Seed the database with records", with nothing to say they target the development database. Descriptions now live in $description and the attribute carries the name only, which is what the framework's own commands do.

Checked in a throwaway Laravel 13.26 app on nativephp/desktop 2.2.1. Before: artisan list errors, and one migrate:fresh drops all 10 tables from nativephp.sqlite while database.sqlite is left untouched. After: all four native commands list separately with their own descriptions and their options intact, migrate:fresh hits the app database again, and native:db:wipe still drops only the NativePHP one. Suite is green on 11, 12 and 13, and the added tests fail on 13.26 without these changes.

Fixes #134
Fixes #135

gwleuverink and others added 2 commits August 18, 2026 15:55
Laravel 13.24 changed FreshCommand and WipeCommand to declare $signature where they used $name. Illuminate\Console\Command::__construct() gives $signature precedence, and the child inherits the parent's, so overriding $name no longer renames anything. Both commands ended up registered under Laravel's names, which breaks artisan list and points migrate:fresh at the NativePHP database.

Declaring the signature keeps the native name and carries the parent's options across, which parent::handle() still reads.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gwleuverink
gwleuverink marked this pull request as ready for review August 18, 2026 14:16
@gwleuverink
gwleuverink requested review from SRWieZ and simonhamp and removed request for simonhamp August 20, 2026 11:29

@SRWieZ SRWieZ left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great explanation. Good fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants