From 594fdfd9d360955faa2fd7f6246349b8a08178d7 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 16 Jun 2026 14:30:36 +0800 Subject: [PATCH 1/2] feat: enhance type hints and improve verbosity handling in commands --- phpstan.neon | 2 +- src/StaticPHP/Command/CraftCommand.php | 15 ++++++---- src/StaticPHP/Command/Dev/TestBotCommand.php | 2 +- src/StaticPHP/DI/ApplicationContext.php | 6 ++-- src/StaticPHP/Package/PackageInstaller.php | 3 ++ .../Runtime/Executor/UnixAutoconfExecutor.php | 4 +-- .../Runtime/Executor/UnixCMakeExecutor.php | 4 +-- .../Runtime/Executor/WindowsCMakeExecutor.php | 4 +-- src/StaticPHP/Util/InteractiveTerm.php | 30 +++++++++---------- 9 files changed, 39 insertions(+), 31 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index f54fc35fc..46efc171a 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,6 @@ parameters: reportUnmatchedIgnoredErrors: false - level: 4 + level: 5 phpVersion: 80400 paths: - ./src/ diff --git a/src/StaticPHP/Command/CraftCommand.php b/src/StaticPHP/Command/CraftCommand.php index f390e4335..864949020 100644 --- a/src/StaticPHP/Command/CraftCommand.php +++ b/src/StaticPHP/Command/CraftCommand.php @@ -110,7 +110,7 @@ public function handle(): int * shared-extensions: array, * packages: array, * sapi: array, - * verbosity: int, + * verbosity: 128|16|256|32|64|8, * debug: bool, * clean-build: bool, * build-options: array, @@ -171,11 +171,16 @@ private function validateAndParseCraftFile(string $craft_file): array } // verbosity - $verbosity_level = $craft['verbosity'] ?? OutputInterface::VERBOSITY_NORMAL; $debug = $craft['debug'] ?? false; - if ($debug) { - $verbosity_level = OutputInterface::VERBOSITY_DEBUG; - } + $verbosity_level = $debug + ? OutputInterface::VERBOSITY_DEBUG + : match ((int) ($craft['verbosity'] ?? 0)) { + OutputInterface::VERBOSITY_QUIET => OutputInterface::VERBOSITY_QUIET, + OutputInterface::VERBOSITY_VERBOSE => OutputInterface::VERBOSITY_VERBOSE, + OutputInterface::VERBOSITY_VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE, + OutputInterface::VERBOSITY_DEBUG => OutputInterface::VERBOSITY_DEBUG, + default => OutputInterface::VERBOSITY_NORMAL, + }; $craft['verbosity'] = $verbosity_level; // clean-build (if true, reset before all builds) diff --git a/src/StaticPHP/Command/Dev/TestBotCommand.php b/src/StaticPHP/Command/Dev/TestBotCommand.php index dc34444df..e5739a727 100644 --- a/src/StaticPHP/Command/Dev/TestBotCommand.php +++ b/src/StaticPHP/Command/Dev/TestBotCommand.php @@ -154,7 +154,7 @@ public function handle(): int 'targets' => array_values($targets), 'gen_matrix_args' => $gen_matrix_args, 'gen_matrix_args_tier2' => $gen_matrix_args_tier2, - 'php_versions' => array_values($php_versions), + 'php_versions' => $php_versions, 'tier2' => $tier2, 'comment_body' => $comment_body, ]; diff --git a/src/StaticPHP/DI/ApplicationContext.php b/src/StaticPHP/DI/ApplicationContext.php index 73ff9f2d4..f46ea8ba2 100644 --- a/src/StaticPHP/DI/ApplicationContext.php +++ b/src/StaticPHP/DI/ApplicationContext.php @@ -79,11 +79,11 @@ public static function getContainer(): Container /** * Get a service from the container. * - * @template T + * @template T of object * - * @param class-string $id Service identifier + * @param class-string|string $id Service identifier * - * @return null|T + * @return ($id is class-string ? T : mixed) */ public static function get(string $id): mixed { diff --git a/src/StaticPHP/Package/PackageInstaller.php b/src/StaticPHP/Package/PackageInstaller.php index 9cd0a1067..5652507f1 100644 --- a/src/StaticPHP/Package/PackageInstaller.php +++ b/src/StaticPHP/Package/PackageInstaller.php @@ -75,6 +75,9 @@ public function addBuildPackage(LibraryPackage|string|TargetPackage $package): s } // special check for php target packages if (in_array($package->getName(), ['php', 'php-cli', 'php-fpm', 'php-micro', 'php-cgi', 'php-embed', 'frankenphp'], true)) { + if (!$package instanceof TargetPackage) { + throw new WrongUsageException("Package '{$package->getName()}' is expected to be a TargetPackage."); + } $this->handlePhpTargetPackage($package); return $this; } diff --git a/src/StaticPHP/Runtime/Executor/UnixAutoconfExecutor.php b/src/StaticPHP/Runtime/Executor/UnixAutoconfExecutor.php index c59859cf4..2cce15c5d 100644 --- a/src/StaticPHP/Runtime/Executor/UnixAutoconfExecutor.php +++ b/src/StaticPHP/Runtime/Executor/UnixAutoconfExecutor.php @@ -117,7 +117,7 @@ public function optionalPackage(string $name, \Closure|string $true_args, string /** * Add configure args. */ - public function addConfigureArgs(...$args): static + public function addConfigureArgs(string ...$args): static { $this->configure_args = [...$this->configure_args, ...$args]; return $this; @@ -126,7 +126,7 @@ public function addConfigureArgs(...$args): static /** * Remove some configure args, to bypass the configure option checking for some libs. */ - public function removeConfigureArgs(...$args): static + public function removeConfigureArgs(string ...$args): static { $this->configure_args = array_diff($this->configure_args, $args); return $this; diff --git a/src/StaticPHP/Runtime/Executor/UnixCMakeExecutor.php b/src/StaticPHP/Runtime/Executor/UnixCMakeExecutor.php index 9fc008408..d8ff5148d 100644 --- a/src/StaticPHP/Runtime/Executor/UnixCMakeExecutor.php +++ b/src/StaticPHP/Runtime/Executor/UnixCMakeExecutor.php @@ -135,7 +135,7 @@ public function optionalPackage(string $name, \Closure|string $true_args, string /** * Add configure args. */ - public function addConfigureArgs(...$args): static + public function addConfigureArgs(string ...$args): static { $this->configure_args = [...$this->configure_args, ...$args]; return $this; @@ -144,7 +144,7 @@ public function addConfigureArgs(...$args): static /** * Remove some configure args, to bypass the configure option checking for some libs. */ - public function removeConfigureArgs(...$args): static + public function removeConfigureArgs(string ...$args): static { $this->ignore_args = [...$this->ignore_args, ...$args]; return $this; diff --git a/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php b/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php index 1f057f126..ce6f2fe4d 100644 --- a/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php +++ b/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php @@ -99,7 +99,7 @@ public function optionalPackage(string $name, \Closure|string $true_args, string /** * Add configure args. */ - public function addConfigureArgs(...$args): static + public function addConfigureArgs(string ...$args): static { $this->configure_args = [...$this->configure_args, ...$args]; return $this; @@ -108,7 +108,7 @@ public function addConfigureArgs(...$args): static /** * Remove some configure args, to bypass the configure option checking for some libs. */ - public function removeConfigureArgs(...$args): static + public function removeConfigureArgs(string ...$args): static { $this->ignore_args = [...$this->ignore_args, ...$args]; return $this; diff --git a/src/StaticPHP/Util/InteractiveTerm.php b/src/StaticPHP/Util/InteractiveTerm.php index 0570f31c6..d84933cd9 100644 --- a/src/StaticPHP/Util/InteractiveTerm.php +++ b/src/StaticPHP/Util/InteractiveTerm.php @@ -17,8 +17,8 @@ class InteractiveTerm public static function notice(string $message, bool $indent = false): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); + $output = ApplicationContext::get(OutputInterface::class); if ($output->isVerbose()) { logger()->notice(strip_ansi_colors($message)); } else { @@ -29,8 +29,8 @@ public static function notice(string $message, bool $indent = false): void public static function success(string $message, bool $indent = false): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); + $output = ApplicationContext::get(OutputInterface::class); if ($output->isVerbose()) { logger()->info(strip_ansi_colors($message)); } else { @@ -41,8 +41,8 @@ public static function success(string $message, bool $indent = false): void public static function plain(string $message, string $level = 'info'): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); + $output = ApplicationContext::get(OutputInterface::class); if ($output->isVerbose()) { match ($level) { 'debug' => logger()->debug(strip_ansi_colors($message)), @@ -59,8 +59,8 @@ public static function plain(string $message, string $level = 'info'): void public static function info(string $message): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); + $output = ApplicationContext::get(OutputInterface::class); if (!$output->isVerbose()) { $output->writeln(($no_ansi ? 'strip_ansi_colors' : 'strval')(ConsoleColor::green('▶ ') . $message)); } @@ -69,8 +69,8 @@ public static function info(string $message): void public static function error(string $message, bool $indent = true): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); + $output = ApplicationContext::get(OutputInterface::class); if ($output->isVerbose()) { logger()->error(strip_ansi_colors($message)); } else { @@ -86,16 +86,16 @@ public static function advance(): void public static function setMessage(string $message): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); self::$indicator?->setMessage(($no_ansi ? 'strip_ansi_colors' : 'strval')($message)); logger()->debug(strip_ansi_colors($message)); } public static function finish(string $message, bool $status = true): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); $message = $no_ansi ? strip_ansi_colors($message) : $message; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $output = ApplicationContext::get(OutputInterface::class); if ($output->isVerbose()) { if ($status) { logger()->info($message); @@ -116,8 +116,8 @@ public static function finish(string $message, bool $status = true): void public static function indicateProgress(string $message): void { - $no_ansi = ApplicationContext::get(InputInterface::class)?->getOption('no-ansi') ?? false; - $output = ApplicationContext::get(OutputInterface::class) ?? new ConsoleOutput(); + $no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi'); + $output = ApplicationContext::get(OutputInterface::class); if ($output->isVerbose()) { logger()->info(strip_ansi_colors($message)); return; From 7ca1cd4ff6d5fbb249e30eaa9e64a3421b6dce82 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 16 Jun 2026 14:50:09 +0800 Subject: [PATCH 2/2] fix: update Windows runner to use windows-2025 --- src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php index a17432004..448168635 100644 --- a/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php +++ b/src/StaticPHP/Command/Dev/GenExtTestMatrixCommand.php @@ -16,7 +16,7 @@ class GenExtTestMatrixCommand extends BaseCommand private const array OS_RUNNERS = [ 'linux' => ['arch' => 'x86_64', 'runner' => 'ubuntu-latest', 'os_key' => 'Linux'], - 'windows' => ['arch' => 'x86_64', 'runner' => 'windows-latest', 'os_key' => 'Windows'], + 'windows' => ['arch' => 'x86_64', 'runner' => 'windows-2025', 'os_key' => 'Windows'], 'macos' => ['arch' => 'aarch64', 'runner' => 'macos-15', 'os_key' => 'Darwin'], ];