frankliniwobi/laravel-action-command
Laravel Action Command helps you organize business logic into reusable action classes that can also run as Artisan commands, keeping controllers slim and workflows testable, discoverable, and easy to execute from the CLI or directly in code.
composer require frankliniwobi/laravel-action-command:^1.0 — package auto-discovery should register the service provider; there is no manual config/app.php entry needed on Laravel 5.5+.vendor/frankliniwobi/laravel-action-command/src/ — at 1.0.x the surface area is small (a service provider plus the command/action class(es)). Read the provider before anything else; it tells you exactly what is registered, what is publishable, and what the make-command stub looks like.php artisan list and grep for the package's namespace to confirm the command is registered, and php artisan vendor:publish --provider="Frankliniwobi\...\ActionCommandServiceProvider" to see if stubs/config are publishable.^1.0 and commit composer.lock. 1.0.1 is a dependency bump only, so behaviour should be identical to 1.0.0, but see the gotchas below.$signature, argument parsing, and output formatting in the command class; put the actual work in an invokable action class with a typed __invoke()/handle(). This is what makes the action testable and reusable outside the console.Artisan::call(). From controllers, jobs, or other commands, resolve and invoke the action class directly. Reserve Artisan::call('your:command', [...]) for cases where you genuinely need console semantics (output buffering, exit codes, --force style flags).$this->artisan('your:command')->assertExitCode(0) for the command wrapper. If the command writes output, prefer expectsOutput() over asserting on a buffer.routes/console.php/Kernel::schedule(), not the action — you keep withoutOverlapping(), onOneServer(), and runInBackground() for free. Let the command delegate to the action as usual.stubs/ and edit there — never patch vendor/. That keeps composer update safe and gives you a house style for new actions (strict types, readonly DTOs, etc.).Action class you own) so a rename upstream is a one-file fix.illuminate/* constraints can change which framework version Composer resolves. Update on a branch, diff composer.lock, and run the suite before merging. Don't assume "no changelog entry, no risk".php artisan list? Run php artisan optimize:clear (config and compiled caches hide newly discovered providers), and on Lumen register the provider manually in bootstrap/app.php.echo directly are painful to call from HTTP handlers and tests. Route all user-facing output through the command ($this->components->info(), $this->line()) and keep the action silent except for its return value.int from the command's handle() — non-zero on failure — so cron, CI, and Artisan::call() callers can detect failure rather than parsing strings.ops:sync-feed) so they don't clash with framework or other packages' commands; Artisan::call() resolves by name and collisions fail at runtime, not boot.php artisan <command> -vvv gives the exception trace; if an action is swallowed inside Artisan::call(), wrap with $this->artisan(...)->run() in a test or temporarily call the action directly to surface the real error.composer why-not frankliniwobi/laravel-action-command is your friend) — for a pre-1.1 package the constraints are the most likely source of surprise, and 1.0.1 changed exactly those.How can I help you explore Laravel packages today?