digitalnoise/command-launcher
Laravel package for launching and managing console commands programmatically. Provides a simple API to trigger Artisan commands, pass arguments/options, and handle execution flow for scheduled tasks, integrations, and background processes.
Installation
composer require digitalnoise/command-launcher
Register the service provider in config/app.php:
'providers' => [
DigitalNoise\CommandLauncher\CommandLauncherServiceProvider::class,
],
First Command Execution Define and run a simple command in a controller or service:
use DigitalNoise\CommandLauncher\CommandLauncher;
public function runExampleCommand()
{
$launcher = app(CommandLauncher::class);
$output = $launcher->run('echo "Hello from CLI!"');
return $output; // Returns the command output
}
Key Configuration
Configure timeouts and retries in config/command-launcher.php (if needed):
'default_timeout' => 30, // seconds
'max_retries' => 3,
Synchronous Execution Run commands directly in a request lifecycle:
$launcher = app(CommandLauncher::class);
$result = $launcher->run('php artisan optimize:clear');
Asynchronous Dispatch Offload commands to queues for background processing:
$launcher->dispatch('php artisan queue:work --once')
->onQueue('cli-jobs')
->delay(now()->addMinutes(5));
Chaining Commands Execute multiple commands sequentially:
$launcher->run('composer install')
->then('php artisan migrate')
->then('php artisan optimize');
Error Handling Define fallback actions for failed commands:
$launcher->run('php artisan queue:work --once')
->onFailure(function ($command, $output) {
Log::error("Command failed: {$command}", ['output' => $output]);
// Send notification or retry logic
});
Leverage Laravel’s Service Container Bind the launcher to a custom interface for better testability:
$this->app->bind(CommandLauncherInterface::class, function ($app) {
return $app->make(CommandLauncher::class);
});
Queue-Based Workflows
Extend ShouldQueue for complex CLI jobs:
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessMediaJob implements ShouldQueue
{
use Queueable;
public function handle()
{
app(CommandLauncher::class)->run('ffmpeg -i input.mp4 output.mp4');
}
}
Dynamic Command Building
Use Laravel’s Process facade for dynamic commands:
use Symfony\Component\Process\Process;
$process = new Process(['php', 'artisan', 'command', '--option=value']);
$launcher->run($process);
Logging and Monitoring Integrate with Laravel’s logging channels:
$launcher->run('php artisan command')
->setLogger(app(\Psr\Log\LoggerInterface::class));
Command Injection Risks
Process facade with predefined command arrays:
$launcher->run(['php', 'artisan', 'command']); // Safer than strings
Blocking Queues
dispatchSync() sparingly.Environment Dependencies
ffmpeg) are missing.CommandNotFoundHandler:
$launcher->setCommandNotFoundHandler(function ($command) {
throw new \RuntimeException("Command '{$command}' not found. Install required tools.");
});
Output Handling
$launcher->run('command')->setOutputLimit(1024); // Limit to 1KB
Retry Logic
onRetry():
$launcher->run('command')
->retry(3)
->onRetry(function ($attempt, $command) {
Log::warning("Retrying command {$command} (attempt {$attempt})");
});
Inspect Command Outputs Use Laravel’s logging to debug:
$launcher->run('command')->setLogger(app(\Psr\Log\LoggerInterface::class));
Simulate Failures Test error handling with forced failures:
$launcher->run('false-command')->onFailure(function ($command, $output) {
// Handle failure
});
Check Worker Logs Monitor queue workers for timeouts or crashes:
tail -f storage/logs/laravel.log | grep "CommandLauncher"
Custom Command Handlers Extend the launcher to support custom logic:
$launcher->extend('custom', function ($command) {
return shell_exec($command); // Or custom logic
});
Plugin System Add plugins for additional features (e.g., Slack notifications):
$launcher->addPlugin(new SlackNotificationPlugin());
Event Listeners
Listen to command events (e.g., CommandStarted, CommandFailed):
event(new CommandStarted($command, $output));
Timeout Units Timeouts are in seconds by default. Adjust in config:
'default_timeout' => 60, // 1 minute
Queue Priorities Use Laravel’s queue priorities for critical commands:
$launcher->dispatch('command')->onHighPriorityQueue();
Environment-Specific Commands Override commands per environment:
if (app()->environment('production')) {
$launcher->setCommand('deploy', 'deploy:prod');
}
Batch Processing
Use Laravel’s batch() for bulk commands:
$launcher->batch(['command1', 'command2', 'command3'])->run();
Parallel Execution Offload independent commands to separate workers:
$launcher->dispatch('command1')->onQueue('high');
$launcher->dispatch('command2')->onQueue('low');
Resource Limits Set memory/time limits for commands:
$launcher->run('command')->setMemoryLimit('128M')->setTimeout(120);
How can I help you explore Laravel packages today?