Ellrion
8/12/2016 - 2:06 PM

Make simple method for add and running shell commands like composer or npm "scripts" (`php artisan list run`)

Make simple method for add and running shell commands like composer or npm "scripts" (php artisan list run)

<?php declare(strict_types=1);

namespace App\Console\Commands\Foundation;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

class RunScriptCommand extends Command
{
    /**
     * @var string[]
     */
    protected $exec;

    /**
     * Create a new command instance.
     *
     * @param string $name
     * @param string|string[] $exec
     */
    public function __construct(string $name, $exec)
    {
        $this->exec = (array) (is_string($exec) ? [$exec] : $exec);
        $this->signature = 'run:' . $name
            . ' {--timeout=0 : Set the script timeout in seconds, or 0 for no timeout.}';
        $this->description = 'Execute a `$ ' . implode('` and `$ ', $this->exec) . '`';

        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @param  \Symfony\Component\Console\Input\InputInterface $input
     * @param  \Symfony\Component\Console\Output\OutputInterface $output
     * @return mixed
     * @throws \Symfony\Component\Process\Exception\RuntimeException
     * @throws \Symfony\Component\Process\Exception\LogicException
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        foreach ($this->exec as $exec) {
            $this->info($exec);

            $process = new Process($exec, base_path(), null, $this->option('timeout'), null);

            $process->run(function ($type, $data) use ($output) {
                $output->write($data);

            });
        }
    }
}
<?php declare(strict_types=1);

namespace App\Console;

use App\Console\Commands\Foundation\RunScriptCommand;
use Illuminate\Console\Events\ArtisanStarting;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
      //
    ];

    /**
     * Declare script commands there.
     * 
     * @var array
     */
    protected $scripts = [
        'test' => 'php -v',
        'meta' => [
            'php artisan ide-helper:meta',
            'php artisan ide-helper:model -W --dir="app/Entities"'
        ]
    ];

    public function __construct(Application $app, Dispatcher $events)
    {
        parent::__construct($app, $events);
        $this->scripts();
    }

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        //
    }

    /**
     * Register a Scripts based command with the application.
     */
    protected function scripts()
    {
        $commands = $this->scripts;

        $this->app->make('events')->listen(ArtisanStarting::class, function ($event) use ($commands) {
            foreach ($commands as $name => $command) {
                $event->artisan->add(new RunScriptCommand($name, $command));
            }
        });
    }
}