From 0dfd3be16e0beb679a4b80ee6eac3bdd1ebb51fd Mon Sep 17 00:00:00 2001 From: Marc Reichel Date: Thu, 5 Mar 2026 12:47:52 +0100 Subject: [PATCH 1/3] feat: Introduce post call hook --- src/Command.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Command.php b/src/Command.php index 89c63db..5b64102 100644 --- a/src/Command.php +++ b/src/Command.php @@ -5,6 +5,7 @@ namespace Artemeon\Console; use Artemeon\Console\Styles\ArtemeonStyle; +use Closure; use Symfony\Component\Console\Command\Command as SymfonyCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -16,6 +17,8 @@ class Command extends SymfonyCommand use Concerns\ConfiguresPrompts; use Concerns\PromptsForMissingInput; + public static ?Closure $postCallClosure = null; + /** * The name and signature of the console command. */ @@ -87,7 +90,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int return self::FAILURE; } - return $callable(); + $exit = $callable(); + + if (self::$postCallClosure instanceof Closure) { + call_user_func(self::$postCallClosure, $exit); + } + + return $exit; } protected function configureUsingFluentDefinition(): void @@ -111,4 +120,12 @@ public function setHidden(bool $hidden = true): static return $this; } + + /** + * @param Closure(int): void $closure + */ + public static function setupPostCallClosure(Closure $closure): void + { + self::$postCallClosure = $closure; + } } From 036dd7aed587033a5529b4af4ef8b2d22daf3955 Mon Sep 17 00:00:00 2001 From: Marc Reichel Date: Thu, 5 Mar 2026 13:04:05 +0100 Subject: [PATCH 2/3] chore: Cleanup --- composer.json | 10 +++++----- rector.php | 1 - src/Concerns/ConfiguresPrompts.php | 2 +- src/Concerns/InteractsWithIO.php | 2 +- src/Concerns/PromptsForMissingInput.php | 8 -------- src/Parser.php | 2 +- 6 files changed, 8 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index 979f9df..7f2923a 100644 --- a/composer.json +++ b/composer.json @@ -37,11 +37,11 @@ "symfony/console": "^5.0|^6.0|^7.0" }, "require-dev": { - "laravel/pint": "^1.20.0", - "phpstan/phpstan": "^2.1.2", - "rector/rector": "^2.0.7", - "pestphp/pest": "^3.8", - "pestphp/pest-plugin-type-coverage": "^3.6" + "laravel/pint": "^1.27.1", + "phpstan/phpstan": "^2.1.40", + "rector/rector": "^2.3.8", + "pestphp/pest": "^3.8.5", + "pestphp/pest-plugin-type-coverage": "^3.6.1" }, "config": { "allow-plugins": { diff --git a/rector.php b/rector.php index 95126cd..1618f89 100644 --- a/rector.php +++ b/rector.php @@ -15,7 +15,6 @@ privatization: true, instanceOf: true, earlyReturn: true, - strictBooleans: true, ) ->withPaths([ __DIR__ . '/src', diff --git a/src/Concerns/ConfiguresPrompts.php b/src/Concerns/ConfiguresPrompts.php index be916c7..523b16b 100644 --- a/src/Concerns/ConfiguresPrompts.php +++ b/src/Concerns/ConfiguresPrompts.php @@ -109,7 +109,7 @@ private function promptUntilValid(Closure $prompt, bool | string $required, ?Clo while (true) { $result = $prompt(); - if ($required && ($result === '' || $result === [] || $result === false)) { + if ($required && in_array($result, ['', [], false], true)) { $this->output->error(is_string($required) ? $required : 'Required.'); continue; diff --git a/src/Concerns/InteractsWithIO.php b/src/Concerns/InteractsWithIO.php index 267452a..ff1353e 100644 --- a/src/Concerns/InteractsWithIO.php +++ b/src/Concerns/InteractsWithIO.php @@ -545,7 +545,7 @@ public function info(array | string $message): void public function line(string $message, ?string $style = null, int | string | null $verbosity = null): void { - $styled = $style !== null && $style !== '' && $style !== '0' ? sprintf('<%s>%s', $style, $message, $style) : $message; + $styled = in_array($style, [null, '', '0'], true) ? sprintf('<%s>%s', $style, $message, $style) : $message; $this->output->writeln($styled, $this->parseVerbosity($verbosity)); } diff --git a/src/Concerns/PromptsForMissingInput.php b/src/Concerns/PromptsForMissingInput.php index 7f92da1..e3ec64e 100644 --- a/src/Concerns/PromptsForMissingInput.php +++ b/src/Concerns/PromptsForMissingInput.php @@ -4,8 +4,6 @@ namespace Artemeon\Console\Concerns; -use Closure; -use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -39,12 +37,6 @@ protected function promptForMissingArguments(InputInterface $input, OutputInterf $label = $this->promptForMissingArgumentsUsing()[$argument->getName()] ?? 'What is ' . lcfirst($description === '' ? 'the ' . $argument->getName() : $description) . '?'; - if ($label instanceof Closure) { - $input->setArgument($argument->getName(), $argument->isArray() ? Arr::wrap($label()) : $label()); - - return; - } - if (is_array($label)) { [$label, $placeholder] = $label; } diff --git a/src/Parser.php b/src/Parser.php index 38ccb16..ca388e1 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -38,7 +38,7 @@ protected static function name(string $expression): string throw new InvalidArgumentException('Unable to determine command name from signature.'); } - return $matches[0]; + return $matches[0] ?? ''; } /** From 5cce5dfa0d7feb964d604436fe25f8efef9fbab5 Mon Sep 17 00:00:00 2001 From: Marc Reichel Date: Thu, 5 Mar 2026 13:06:28 +0100 Subject: [PATCH 3/3] chore: Cleanup --- src/Concerns/PromptsForMissingInput.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Concerns/PromptsForMissingInput.php b/src/Concerns/PromptsForMissingInput.php index e3ec64e..f6bbf0e 100644 --- a/src/Concerns/PromptsForMissingInput.php +++ b/src/Concerns/PromptsForMissingInput.php @@ -4,6 +4,8 @@ namespace Artemeon\Console\Concerns; +use Closure; +use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -37,6 +39,12 @@ protected function promptForMissingArguments(InputInterface $input, OutputInterf $label = $this->promptForMissingArgumentsUsing()[$argument->getName()] ?? 'What is ' . lcfirst($description === '' ? 'the ' . $argument->getName() : $description) . '?'; + if ($label instanceof Closure) { + $input->setArgument($argument->getName(), $argument->isArray() ? Arr::wrap($label()) : $label()); + + return; + } + if (is_array($label)) { [$label, $placeholder] = $label; } @@ -59,7 +67,7 @@ protected function promptForMissingArguments(InputInterface $input, OutputInterf /** * Prompt for missing input arguments using the returned questions. * - * @return array + * @return array */ protected function promptForMissingArgumentsUsing(): array {