From 1e292a72fe409d91923a74c13da988b576a7c3ae Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Wed, 22 May 2024 16:10:36 +0200 Subject: [PATCH 1/5] Run commands inside the `spin` function. --- src/NewCommand.php | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/NewCommand.php b/src/NewCommand.php index 34e3ae2..d45f57a 100644 --- a/src/NewCommand.php +++ b/src/NewCommand.php @@ -18,6 +18,7 @@ use function Laravel\Prompts\confirm; use function Laravel\Prompts\multiselect; use function Laravel\Prompts\select; +use function Laravel\Prompts\spin; use function Laravel\Prompts\text; class NewCommand extends Command @@ -877,7 +878,7 @@ protected function runCommands($commands, InputInterface $input, OutputInterface }, $commands); } - if ($input->getOption('quiet')) { + if (! $output->isVerbose()) { $commands = array_map(function ($value) { if (str_starts_with($value, 'chmod')) { return $value; @@ -891,7 +892,13 @@ protected function runCommands($commands, InputInterface $input, OutputInterface }, $commands); } - $process = Process::fromShellCommandline(implode(' && ', $commands), $workingPath, $env, null, null); + $commands = implode(' && ', $commands); + + if ($this->canUseSpinner($input, $output)) { + $commands .= ' > /dev/null 2>&1'; + } + + $process = Process::fromShellCommandline($commands, $workingPath, $env, null, null); if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { try { @@ -901,11 +908,13 @@ protected function runCommands($commands, InputInterface $input, OutputInterface } } - $process->run(function ($type, $line) use ($output) { + if ($this->canUseSpinner($input, $output)) { + return spin(fn () => tap($process)->run(), 'Installing...'); + } + + return tap($process)->run(function ($type, $line) use ($output) { $output->write(' '.$line); }); - - return $process; } /** @@ -956,4 +965,16 @@ protected function pregReplaceInFile(string $pattern, string $replace, string $f preg_replace($pattern, $replace, file_get_contents($file)) ); } + + /** + * Checks if its possible to use the spinner. + * + * @return bool + */ + protected function canUseSpinner(InputInterface $input, OutputInterface $output) + { + return function_exists('pcntl_fork') && + ! $output->isVerbose() && + ! $input->getOption('quiet'); + } } From f10025e7e253d3e575701cf685ca5d91c0582e2b Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Wed, 29 May 2024 00:01:55 +0100 Subject: [PATCH 2/5] fix: add `runCommand` method. --- src/NewCommand.php | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/NewCommand.php b/src/NewCommand.php index d45f57a..98e2f15 100644 --- a/src/NewCommand.php +++ b/src/NewCommand.php @@ -12,9 +12,9 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Exception\ProcessStartFailedException; +use Symfony\Component\Console\Terminal; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; - use function Laravel\Prompts\confirm; use function Laravel\Prompts\multiselect; use function Laravel\Prompts\select; @@ -892,13 +892,39 @@ protected function runCommands($commands, InputInterface $input, OutputInterface }, $commands); } - $commands = implode(' && ', $commands); + foreach ($commands as $command) { + $process = $this->runCommand($command, $input, $output, $workingPath, $env); - if ($this->canUseSpinner($input, $output)) { - $commands .= ' > /dev/null 2>&1'; + if (! $process->isSuccessful()) { + $output->writeln(' ERROR '.$process->getErrorOutput().PHP_EOL); + + break; + } } - $process = Process::fromShellCommandline($commands, $workingPath, $env, null, null); + return $process; + } + + /** + * Run the given command. + * + * @param string $command + * @param InputInterface $input + * @param OutputInterface $output + * @param string|null $workingPath + * @param array $env + * @return \Symfony\Component\Process\Process + */ + protected function runCommand(string $command, InputInterface $input, OutputInterface $output, string $workingPath = null, array $env = []) + { + $process = Process::fromShellCommandline($command, $workingPath, $env, null, null); + + if ($this->canUseSpinner($input, $output)) { + $terminalWidth = (new Terminal)->getWidth(); + $description = mb_substr($command, 0, $terminalWidth - 6); + + return spin(fn () => tap($process)->run(), "{$description}..."); + } if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { try { @@ -908,13 +934,7 @@ protected function runCommands($commands, InputInterface $input, OutputInterface } } - if ($this->canUseSpinner($input, $output)) { - return spin(fn () => tap($process)->run(), 'Installing...'); - } - - return tap($process)->run(function ($type, $line) use ($output) { - $output->write(' '.$line); - }); + return tap($process)->run(); } /** From 9111e63359ddf7ba360c4cb56c2615ffc5e3ac2e Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Wed, 29 May 2024 00:03:55 +0100 Subject: [PATCH 3/5] style: fixes. --- src/NewCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NewCommand.php b/src/NewCommand.php index 98e2f15..60f3dc2 100644 --- a/src/NewCommand.php +++ b/src/NewCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\Terminal; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; + use function Laravel\Prompts\confirm; use function Laravel\Prompts\multiselect; use function Laravel\Prompts\select; From d28ba6e2e50208c7f9a8f6f6dc28a32ec2986d47 Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Wed, 29 May 2024 00:16:58 +0100 Subject: [PATCH 4/5] Keep the same output if the spinner is not available. --- src/NewCommand.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/NewCommand.php b/src/NewCommand.php index 60f3dc2..fd3b389 100644 --- a/src/NewCommand.php +++ b/src/NewCommand.php @@ -879,7 +879,7 @@ protected function runCommands($commands, InputInterface $input, OutputInterface }, $commands); } - if (! $output->isVerbose()) { + if (! $output->isVerbose() && $this->canUseSpinner($input, $output)) { $commands = array_map(function ($value) { if (str_starts_with($value, 'chmod')) { return $value; @@ -935,7 +935,11 @@ protected function runCommand(string $command, InputInterface $input, OutputInte } } - return tap($process)->run(); + $process->run(function ($type, $line) use ($output) { + $output->write(' '.$line); + }); + + return $process; } /** From df8dd251263c69d648e1c565660a8d85772a604e Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Mon, 3 Jun 2024 15:59:37 +0100 Subject: [PATCH 5/5] style: fixes. --- src/NewCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NewCommand.php b/src/NewCommand.php index fd3b389..f739e4d 100644 --- a/src/NewCommand.php +++ b/src/NewCommand.php @@ -11,8 +11,8 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Exception\ProcessStartFailedException; use Symfony\Component\Console\Terminal; +use Symfony\Component\Process\Exception\ProcessStartFailedException; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process;