From 2c0bb1f7ba25f2e98eadc400b9e78c180b676174 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 14:31:29 +0800 Subject: [PATCH 01/23] Quiet console output for non --debug mode --- src/SPC/store/Downloader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index fbaeb7a7..5d91f2cd 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -246,6 +246,7 @@ public static function downloadGit(string $name, string $url, string $branch, ?s self::registerCancelEvent($cancel_func); f_passthru( SPC_GIT_EXEC . ' clone' . $check . + (defined('DEBUG_MODE') ? '' : ' --quiet') . ' --config core.autocrlf=false ' . "--branch \"{$branch}\" " . (defined('GIT_SHALLOW_CLONE') ? '--depth 1 --single-branch' : '') . " --recursive \"{$url}\" \"{$download_path}\"" ); From 5648681ecc1d6eb0f778bce08a860c58dbf563de Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 15:17:09 +0800 Subject: [PATCH 02/23] Adjust console output and PHPDoc --- src/SPC/command/DownloadCommand.php | 8 +++---- src/SPC/store/Downloader.php | 37 +++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 7bf82ebb..6286969a 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -212,7 +212,7 @@ public function handle(): int if (isset($config['filename'])) { $new_config['filename'] = $config['filename']; } - logger()->info("Fetching source {$source} from custom url [{$ni}/{$cnt}]"); + logger()->info("[{$ni}/{$cnt}] Downloading source {$source} from custom url: {$new_config['url']}"); Downloader::downloadSource($source, $new_config, true); } elseif (isset($custom_gits[$source])) { $config = Config::getSource($source); @@ -224,7 +224,7 @@ public function handle(): int if (isset($config['path'])) { $new_config['path'] = $config['path']; } - logger()->info("Fetching source {$source} from custom git [{$ni}/{$cnt}]"); + logger()->info("[{$ni}/{$cnt}] Downloading source {$source} from custom git: {$new_config['url']}"); Downloader::downloadSource($source, $new_config, true); } else { $config = Config::getSource($source); @@ -234,13 +234,13 @@ public function handle(): int $find = str_replace(['{name}', '{arch}', '{os}'], [$source, arch2gnu(php_uname('m')), strtolower(PHP_OS_FAMILY)], Config::getPreBuilt('match-pattern')); // find filename in asset list if (($url = $this->findPreBuilt($pre_built_libs, $find)) !== null) { - logger()->info("Fetching pre-built content {$source} [{$ni}/{$cnt}]"); + logger()->info("[{$ni}/{$cnt}] Downloading pre-built content {$source}"); Downloader::downloadSource($source, ['type' => 'url', 'url' => $url], $force_all || in_array($source, $force_list), SPC_LOCK_PRE_BUILT); continue; } logger()->warning("Pre-built content not found for {$source}, fallback to source download"); } - logger()->info("Fetching source {$source} [{$ni}/{$cnt}]"); + logger()->info("[{$ni}/{$cnt}] Downloading source {$source}"); Downloader::downloadSource($source, $config, $force_all || in_array($source, $force_list)); } } diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 5d91f2cd..6ac272e4 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -284,8 +284,22 @@ public static function downloadGit(string $name, string $url, string $branch, ?s } /** + * @param string $name Package name + * @param null|array{ + * type: string, + * repo: ?string, + * url: ?string, + * rev: ?string, + * path: ?string, + * filename: ?string, + * match: ?string, + * prefer-stable: ?bool, + * extract-files: ?array + * } $pkg Package config + * @param bool $force Download all the time even if it exists * @throws DownloaderException * @throws FileSystemException + * @throws WrongUsageException */ public static function downloadPackage(string $name, ?array $pkg = null, bool $force = false): void { @@ -383,8 +397,23 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f /** * Download source by name and meta. * - * @param string $name source name - * @param null|array $source source meta info: [type, path, rev, url, filename, regex, license] + * @param string $name source name + * @param null|array{ + * type: string, + * repo: ?string, + * url: ?string, + * rev: ?string, + * path: ?string, + * filename: ?string, + * match: ?string, + * prefer-stable: ?bool, + * provide-pre-built: ?bool, + * license: array{ + * type: string, + * path: ?string, + * text: ?string + * } + * } $source source meta info: [type, path, rev, url, filename, regex, license] * @param bool $force Whether to force download (default: false) * @param int $lock_as Lock source type (default: SPC_LOCK_SOURCE) * @throws DownloaderException @@ -415,11 +444,11 @@ public static function downloadSource(string $name, ?array $source = null, bool // If lock file exists, skip downloading if (isset($lock[$name]) && !$force && ($lock[$name]['lock_as'] ?? SPC_LOCK_SOURCE) === $lock_as) { if ($lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename'])) { - logger()->notice("source [{$name}] already downloaded: " . $lock[$name]['filename']); + logger()->notice("Source [{$name}] already downloaded: " . $lock[$name]['filename']); return; } if ($lock[$name]['source_type'] === 'dir' && is_dir(DOWNLOAD_PATH . '/' . $lock[$name]['dirname'])) { - logger()->notice("source [{$name}] already downloaded: " . $lock[$name]['dirname']); + logger()->notice("Source [{$name}] already downloaded: " . $lock[$name]['dirname']); return; } } From 87c053562451d58f1fafb16701241079c097a264 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 16:53:14 +0800 Subject: [PATCH 03/23] Allow locking different arch pre-built content --- config/pre-built.json | 1 + src/SPC/builder/LibraryBase.php | 6 +- src/SPC/command/DeleteDownloadCommand.php | 24 ++-- src/SPC/command/DownloadCommand.php | 10 +- src/SPC/command/dev/PackLibCommand.php | 12 +- src/SPC/store/Config.php | 19 ++++ src/SPC/store/Downloader.php | 128 +++++++++++++--------- src/SPC/store/SourceManager.php | 15 ++- src/SPC/store/source/CustomSourceBase.php | 2 +- src/SPC/store/source/PhpSource.php | 2 +- src/SPC/store/source/PostgreSQLSource.php | 2 +- src/globals/defines.php | 5 +- 12 files changed, 150 insertions(+), 76 deletions(-) diff --git a/config/pre-built.json b/config/pre-built.json index 396c8820..1f1803f8 100644 --- a/config/pre-built.json +++ b/config/pre-built.json @@ -1,6 +1,7 @@ { "repo": "static-php/static-php-cli-hosted", "prefer-stable": true, + "match-pattern-linux": "{name}-{arch}-{os}-{libc}.txz", "match-pattern": "{name}-{arch}-{os}.txz", "suffix": "txz" } \ No newline at end of file diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index d76aa209..165e4f13 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -8,6 +8,7 @@ use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\Config; +use SPC\store\Downloader; use SPC\store\FileSystem; use SPC\store\SourceManager; @@ -45,8 +46,9 @@ public function setup(bool $force = false): int $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; $source = Config::getLib(static::NAME, 'source'); // if source is locked as pre-built, we just tryInstall it - if (isset($lock[$source]) && ($lock[$source]['lock_as'] ?? SPC_LOCK_SOURCE) === SPC_LOCK_PRE_BUILT) { - return $this->tryInstall($lock[$source]['filename'], $force); + $pre_built_name = Downloader::getPreBuiltName($source); + if (isset($lock[$pre_built_name]) && ($lock[$pre_built_name]['lock_as'] ?? SPC_DOWN_SOURCE) === SPC_DOWN_PRE_BUILT) { + return $this->tryInstall($lock[$pre_built_name]['filename'], $force); } return $this->tryBuild($force); } diff --git a/src/SPC/command/DeleteDownloadCommand.php b/src/SPC/command/DeleteDownloadCommand.php index a953fbe6..1471451c 100644 --- a/src/SPC/command/DeleteDownloadCommand.php +++ b/src/SPC/command/DeleteDownloadCommand.php @@ -7,6 +7,7 @@ use SPC\exception\DownloaderException; use SPC\exception\FileSystemException; use SPC\exception\WrongUsageException; +use SPC\store\Downloader; use SPC\store\FileSystem; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; @@ -47,30 +48,35 @@ public function handle(): int $chosen_sources = $sources; $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; + $deleted_sources = []; foreach ($chosen_sources as $source) { $source = trim($source); - if (!isset($lock[$source])) { - logger()->warning("Source/Package [{$source}] not locked or not downloaded, skipped."); - continue; + foreach ([$source, Downloader::getPreBuiltName($source)] as $name) { + if (isset($lock[$name])) { + $deleted_sources[] = $name; + } } + } + + foreach ($deleted_sources as $lock_name) { // remove download file/dir if exists - if ($lock[$source]['source_type'] === 'archive') { - if (file_exists($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$source]['filename']))) { + if ($lock[$lock_name]['source_type'] === 'archive') { + if (file_exists($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$lock_name]['filename']))) { logger()->info('Deleting file ' . $path); unlink($path); } else { - logger()->warning("Source/Package [{$source}] file not found, skip deleting file."); + logger()->warning("Source/Package [{$lock_name}] file not found, skip deleting file."); } } else { - if (is_dir($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$source]['dirname']))) { + if (is_dir($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$lock_name]['dirname']))) { logger()->info('Deleting dir ' . $path); FileSystem::removeDir($path); } else { - logger()->warning("Source/Package [{$source}] directory not found, skip deleting dir."); + logger()->warning("Source/Package [{$lock_name}] directory not found, skip deleting dir."); } } // remove locked sources - unset($lock[$source]); + unset($lock[$lock_name]); } FileSystem::writeFile(DOWNLOAD_PATH . '/.lock.json', json_encode($lock, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); logger()->info('Delete success!'); diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 6286969a..85a01b56 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -231,11 +231,17 @@ public function handle(): int // Prefer pre-built, we need to search pre-built library if ($this->getOption('prefer-pre-built') && ($config['provide-pre-built'] ?? false) === true) { // We need to replace pattern - $find = str_replace(['{name}', '{arch}', '{os}'], [$source, arch2gnu(php_uname('m')), strtolower(PHP_OS_FAMILY)], Config::getPreBuilt('match-pattern')); + $replace = [ + '{name}' => $source, + '{arch}' => arch2gnu(php_uname('m')), + '{os}' => strtolower(PHP_OS_FAMILY), + '{libc}' => getenv('SPC_LIBC') ?: 'default', + ]; + $find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern')); // find filename in asset list if (($url = $this->findPreBuilt($pre_built_libs, $find)) !== null) { logger()->info("[{$ni}/{$cnt}] Downloading pre-built content {$source}"); - Downloader::downloadSource($source, ['type' => 'url', 'url' => $url], $force_all || in_array($source, $force_list), SPC_LOCK_PRE_BUILT); + Downloader::downloadSource($source, ['type' => 'url', 'url' => $url], $force_all || in_array($source, $force_list), SPC_DOWN_PRE_BUILT); continue; } logger()->warning("Pre-built content not found for {$source}, fallback to source download"); diff --git a/src/SPC/command/dev/PackLibCommand.php b/src/SPC/command/dev/PackLibCommand.php index 18e02fda..340736d5 100644 --- a/src/SPC/command/dev/PackLibCommand.php +++ b/src/SPC/command/dev/PackLibCommand.php @@ -47,7 +47,7 @@ public function handle(): int // Get lock info $lock = json_decode(file_get_contents(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; $source = Config::getLib($lib->getName(), 'source'); - if (!isset($lock[$source]) || ($lock[$source]['lock_as'] ?? SPC_LOCK_SOURCE) === SPC_LOCK_PRE_BUILT) { + if (!isset($lock[$source]) || ($lock[$source]['lock_as'] ?? SPC_DOWN_SOURCE) === SPC_DOWN_PRE_BUILT) { logger()->critical("The library {$lib->getName()} is downloaded as pre-built, we need to build it instead of installing pre-built."); return static::FAILURE; } @@ -69,7 +69,15 @@ public function handle(): int // write list to packlib_files.txt FileSystem::writeFile(WORKING_DIR . '/packlib_files.txt', implode("\n", $increase_files)); // pack - $filename = WORKING_DIR . '/dist/' . $lib->getName() . '-' . arch2gnu(php_uname('m')) . '-' . strtolower(PHP_OS_FAMILY) . '.' . Config::getPreBuilt('suffix'); + $filename = Config::getPreBuilt('match-pattern'); + $replace = [ + '{name}' => $lib->getName(), + '{arch}' => arch2gnu(php_uname('m')), + '{os}' => strtolower(PHP_OS_FAMILY), + '{libc}' => getenv('SPC_LIBC') ?: 'default', + ]; + $filename = str_replace(array_keys($replace), array_values($replace), $filename); + $filename = WORKING_DIR . '/dist/' . $filename . '.' . Config::getPreBuilt('suffix'); f_passthru('tar -czf ' . $filename . ' -T ' . WORKING_DIR . '/packlib_files.txt'); logger()->info('Pack library ' . $lib->getName() . ' to ' . $filename . ' complete.'); } diff --git a/src/SPC/store/Config.php b/src/SPC/store/Config.php index 07ed2887..f7074d47 100644 --- a/src/SPC/store/Config.php +++ b/src/SPC/store/Config.php @@ -22,11 +22,30 @@ class Config public static ?array $pre_built = null; + /** + * @throws WrongUsageException + * @throws FileSystemException + */ public static function getPreBuilt(string $name): mixed { if (self::$pre_built === null) { self::$pre_built = FileSystem::loadConfigArray('pre-built'); } + $supported_sys_based = ['match-pattern']; + if (in_array($name, $supported_sys_based)) { + $m_key = match (PHP_OS_FAMILY) { + 'Windows' => ['-windows', '-win', ''], + 'Darwin' => ['-macos', '-unix', ''], + 'Linux' => ['-linux', '-unix', ''], + 'BSD' => ['-freebsd', '-bsd', '-unix', ''], + default => throw new WrongUsageException('OS ' . PHP_OS_FAMILY . ' is not supported'), + }; + foreach ($m_key as $v) { + if (isset(self::$pre_built["{$name}{$v}"])) { + return self::$pre_built["{$name}{$v}"]; + } + } + } return self::$pre_built[$name] ?? null; } diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 6ac272e4..ebb814a2 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -189,7 +189,7 @@ public static function getFromFileList(string $name, array $source): array * @throws RuntimeException * @throws WrongUsageException */ - public static function downloadFile(string $name, string $url, string $filename, ?string $move_path = null, int $lock_as = SPC_LOCK_SOURCE): void + public static function downloadFile(string $name, string $url, string $filename, ?string $move_path = null, int $download_as = SPC_DOWN_SOURCE): void { logger()->debug("Downloading {$url}"); $cancel_func = function () use ($filename) { @@ -202,12 +202,23 @@ public static function downloadFile(string $name, string $url, string $filename, self::curlDown(url: $url, path: FileSystem::convertPath(DOWNLOAD_PATH . "/{$filename}"), retry: self::getRetryTime()); self::unregisterCancelEvent(); logger()->debug("Locking {$filename}"); - self::lockSource($name, ['source_type' => 'archive', 'filename' => $filename, 'move_path' => $move_path, 'lock_as' => $lock_as]); + if ($download_as === SPC_DOWN_PRE_BUILT) { + $name = self::getPreBuiltName($name); + } + self::lockSource($name, ['source_type' => 'archive', 'filename' => $filename, 'move_path' => $move_path, 'lock_as' => $download_as]); } /** * Try to lock source. * + * @param string $name Source name + * @param array{ + * source_type: string, + * dirname: ?string, + * filename: ?string, + * move_path: ?string, + * lock_as: int + * } $data Source data * @throws FileSystemException */ public static function lockSource(string $name, array $data): void @@ -228,7 +239,7 @@ public static function lockSource(string $name, array $data): void * @throws RuntimeException * @throws WrongUsageException */ - public static function downloadGit(string $name, string $url, string $branch, ?string $move_path = null, int $retry = 0, int $lock_as = SPC_LOCK_SOURCE): void + public static function downloadGit(string $name, string $url, string $branch, ?string $move_path = null, int $retry = 0, int $lock_as = SPC_DOWN_SOURCE): void { $download_path = FileSystem::convertPath(DOWNLOAD_PATH . "/{$name}"); if (file_exists($download_path)) { @@ -316,50 +327,36 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f FileSystem::createDir(DOWNLOAD_PATH); } - // load lock file - if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) { - $lock = []; - } else { - $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; - } - // If lock file exists, skip downloading - if (isset($lock[$name]) && !$force) { - if ($lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename'])) { - logger()->notice("Package [{$name}] already downloaded: " . $lock[$name]['filename']); - return; - } - if ($lock[$name]['source_type'] === 'dir' && is_dir(DOWNLOAD_PATH . '/' . $lock[$name]['dirname'])) { - logger()->notice("Package [{$name}] already downloaded: " . $lock[$name]['dirname']); - return; - } + if (self::isAlreadyDownloaded($name, $force, SPC_DOWN_PACKAGE)) { + return; } try { switch ($pkg['type']) { case 'bitbuckettag': // BitBucket Tag [$url, $filename] = self::getLatestBitbucketTag($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_LOCK_PRE_BUILT); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); break; case 'ghtar': // GitHub Release (tar) [$url, $filename] = self::getLatestGithubTarball($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_LOCK_PRE_BUILT); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); break; case 'ghtagtar': // GitHub Tag (tar) [$url, $filename] = self::getLatestGithubTarball($name, $pkg, 'tags'); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_LOCK_PRE_BUILT); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); break; case 'ghrel': // GitHub Release (uploaded) [$url, $filename] = self::getLatestGithubRelease($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_LOCK_PRE_BUILT); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); break; case 'filelist': // Basic File List (regex based crawler) [$url, $filename] = self::getFromFileList($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_LOCK_PRE_BUILT); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); break; case 'url': // Direct download URL $url = $pkg['url']; $filename = $pkg['filename'] ?? basename($pkg['url']); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_LOCK_PRE_BUILT); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); break; case 'git': // Git repo self::downloadGit( @@ -368,7 +365,7 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f $pkg['rev'], $pkg['extract'] ?? null, self::getRetryTime(), - SPC_LOCK_PRE_BUILT + SPC_DOWN_PRE_BUILT ); break; case 'custom': // Custom download method, like API-based download or other @@ -414,13 +411,13 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f * text: ?string * } * } $source source meta info: [type, path, rev, url, filename, regex, license] - * @param bool $force Whether to force download (default: false) - * @param int $lock_as Lock source type (default: SPC_LOCK_SOURCE) + * @param bool $force Whether to force download (default: false) + * @param int $download_as Lock source type (default: SPC_LOCK_SOURCE) * @throws DownloaderException * @throws FileSystemException * @throws WrongUsageException */ - public static function downloadSource(string $name, ?array $source = null, bool $force = false, int $lock_as = SPC_LOCK_SOURCE): void + public static function downloadSource(string $name, ?array $source = null, bool $force = false, int $download_as = SPC_DOWN_SOURCE): void { if ($source === null) { $source = Config::getSource($name); @@ -436,49 +433,36 @@ public static function downloadSource(string $name, ?array $source = null, bool } // load lock file - if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) { - $lock = []; - } else { - $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; - } - // If lock file exists, skip downloading - if (isset($lock[$name]) && !$force && ($lock[$name]['lock_as'] ?? SPC_LOCK_SOURCE) === $lock_as) { - if ($lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename'])) { - logger()->notice("Source [{$name}] already downloaded: " . $lock[$name]['filename']); - return; - } - if ($lock[$name]['source_type'] === 'dir' && is_dir(DOWNLOAD_PATH . '/' . $lock[$name]['dirname'])) { - logger()->notice("Source [{$name}] already downloaded: " . $lock[$name]['dirname']); - return; - } + if (self::isAlreadyDownloaded($name, $force, $download_as)) { + return; } try { switch ($source['type']) { case 'bitbuckettag': // BitBucket Tag [$url, $filename] = self::getLatestBitbucketTag($name, $source); - self::downloadFile($name, $url, $filename, $source['path'] ?? null, $lock_as); + self::downloadFile($name, $url, $filename, $source['path'] ?? null, $download_as); break; case 'ghtar': // GitHub Release (tar) [$url, $filename] = self::getLatestGithubTarball($name, $source); - self::downloadFile($name, $url, $filename, $source['path'] ?? null, $lock_as); + self::downloadFile($name, $url, $filename, $source['path'] ?? null, $download_as); break; case 'ghtagtar': // GitHub Tag (tar) [$url, $filename] = self::getLatestGithubTarball($name, $source, 'tags'); - self::downloadFile($name, $url, $filename, $source['path'] ?? null, $lock_as); + self::downloadFile($name, $url, $filename, $source['path'] ?? null, $download_as); break; case 'ghrel': // GitHub Release (uploaded) [$url, $filename] = self::getLatestGithubRelease($name, $source); - self::downloadFile($name, $url, $filename, $source['path'] ?? null, $lock_as); + self::downloadFile($name, $url, $filename, $source['path'] ?? null, $download_as); break; case 'filelist': // Basic File List (regex based crawler) [$url, $filename] = self::getFromFileList($name, $source); - self::downloadFile($name, $url, $filename, $source['path'] ?? null, $lock_as); + self::downloadFile($name, $url, $filename, $source['path'] ?? null, $download_as); break; case 'url': // Direct download URL $url = $source['url']; $filename = $source['filename'] ?? basename($source['url']); - self::downloadFile($name, $url, $filename, $source['path'] ?? null, $lock_as); + self::downloadFile($name, $url, $filename, $source['path'] ?? null, $download_as); break; case 'git': // Git repo self::downloadGit( @@ -487,14 +471,14 @@ public static function downloadSource(string $name, ?array $source = null, bool $source['rev'], $source['path'] ?? null, self::getRetryTime(), - $lock_as + $download_as ); break; case 'custom': // Custom download method, like API-based download or other $classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\store\source'); foreach ($classes as $class) { if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) { - (new $class())->fetch($force, $source, $lock_as); + (new $class())->fetch($force, $source, $download_as); break; } } @@ -609,6 +593,11 @@ public static function curlDown(string $url, string $path, string $method = 'GET } } + public static function getPreBuiltName(string $source): string + { + return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default'); + } + /** * Register CTRL+C event for different OS. * @@ -641,4 +630,39 @@ private static function getRetryTime(): int { return intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0); } + + /** + * @throws FileSystemException + */ + private static function isAlreadyDownloaded(string $name, bool $force, int $download_as = SPC_DOWN_SOURCE): bool + { + if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) { + $lock = []; + } else { + $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; + } + // If lock file exists, skip downloading for source mode + if (!$force && $download_as === SPC_DOWN_SOURCE && isset($lock[$name])) { + if ( + $lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename']) || + $lock[$name]['source_type'] === 'dir' && is_dir(DOWNLOAD_PATH . '/' . $lock[$name]['dirname']) + ) { + logger()->notice("Source [{$name}] already downloaded: " . ($lock[$name]['filename'] ?? $lock[$name]['dirname'])); + return true; + } + } + // If lock file exists for current arch and glibc target, skip downloading + $lock_name = self::getPreBuiltName($name); + if (!$force && $download_as === SPC_DOWN_PRE_BUILT && isset($lock[$lock_name])) { + // lock name with env + if ( + $lock[$lock_name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$lock_name]['filename']) || + $lock[$lock_name]['source_type'] === 'dir' && is_dir(DOWNLOAD_PATH . '/' . $lock[$lock_name]['dirname']) + ) { + logger()->notice("Pre-built content [{$name}] already downloaded: " . ($lock[$lock_name]['filename'] ?? $lock[$lock_name]['dirname'])); + return true; + } + } + return false; + } } diff --git a/src/SPC/store/SourceManager.php b/src/SPC/store/SourceManager.php index 78f68ad4..b18a47be 100644 --- a/src/SPC/store/SourceManager.php +++ b/src/SPC/store/SourceManager.php @@ -54,15 +54,22 @@ public static function initSource(?array $sources = null, ?array $libs = null, ? if (Config::getSource($source) === null) { throw new WrongUsageException("Source [{$source}] does not exist, please check the name and correct it !"); } - if (!isset($lock[$source])) { - throw new WrongUsageException('Source [' . $source . '] not downloaded or not locked, you should download it first !'); + // check source downloaded + $pre_built_name = Downloader::getPreBuiltName($source); + if (!isset($lock[$pre_built_name])) { + if (!isset($lock[$source])) { + throw new WrongUsageException("Source [{$source}] not downloaded or not locked, you should download it first !"); + } + $lock_name = $source; + } else { + $lock_name = $pre_built_name; } // check source dir exist - $check = $lock[$source]['move_path'] === null ? (SOURCE_PATH . '/' . $source) : (SOURCE_PATH . '/' . $lock[$source]['move_path']); + $check = $lock[$lock_name]['move_path'] === null ? (SOURCE_PATH . '/' . $source) : (SOURCE_PATH . '/' . $lock[$lock_name]['move_path']); if (!is_dir($check)) { logger()->debug('Extracting source [' . $source . '] to ' . $check . ' ...'); - FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']); + FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$lock_name]['filename'] ?? $lock[$lock_name]['dirname']), $lock[$lock_name]['move_path']); } else { logger()->debug('Source [' . $source . '] already extracted in ' . $check . ', skip !'); } diff --git a/src/SPC/store/source/CustomSourceBase.php b/src/SPC/store/source/CustomSourceBase.php index 2df8eb7e..243341ad 100644 --- a/src/SPC/store/source/CustomSourceBase.php +++ b/src/SPC/store/source/CustomSourceBase.php @@ -8,5 +8,5 @@ abstract class CustomSourceBase { public const NAME = 'unknown'; - abstract public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_LOCK_SOURCE): void; + abstract public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWN_SOURCE): void; } diff --git a/src/SPC/store/source/PhpSource.php b/src/SPC/store/source/PhpSource.php index d15fd40f..405d6ca6 100644 --- a/src/SPC/store/source/PhpSource.php +++ b/src/SPC/store/source/PhpSource.php @@ -17,7 +17,7 @@ class PhpSource extends CustomSourceBase * @throws DownloaderException * @throws FileSystemException */ - public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_LOCK_SOURCE): void + public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWN_SOURCE): void { $major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.3'; Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force); diff --git a/src/SPC/store/source/PostgreSQLSource.php b/src/SPC/store/source/PostgreSQLSource.php index 113abc98..6c025ef0 100644 --- a/src/SPC/store/source/PostgreSQLSource.php +++ b/src/SPC/store/source/PostgreSQLSource.php @@ -16,7 +16,7 @@ class PostgreSQLSource extends CustomSourceBase * @throws DownloaderException * @throws FileSystemException */ - public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_LOCK_SOURCE): void + public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWN_SOURCE): void { Downloader::downloadSource('postgresql', self::getLatestInfo(), $force); } diff --git a/src/globals/defines.php b/src/globals/defines.php index 46c98915..f3d3187f 100644 --- a/src/globals/defines.php +++ b/src/globals/defines.php @@ -41,8 +41,9 @@ ]; // spc lock type -const SPC_LOCK_SOURCE = 1; // lock source -const SPC_LOCK_PRE_BUILT = 2; // lock pre-built +const SPC_DOWN_SOURCE = 1; // lock source +const SPC_DOWN_PRE_BUILT = 2; // lock pre-built +const SPC_DOWN_PACKAGE = 3; // lock as package // file replace strategy const REPLACE_FILE_STR = 1; From 0e4a3f5e2bdafd65b662f285df8f7a99c6d4ab91 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 19:09:32 +0800 Subject: [PATCH 04/23] Add install-pkg and pre-built test --- src/globals/test-extensions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index cecb8ace..bd3351a6 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -13,9 +13,9 @@ // test php version (8.1 ~ 8.4 available, multiple for matrix) $test_php_version = [ - '8.1', - '8.2', - '8.3', + // '8.1', + // '8.2', + // '8.3', '8.4', ]; @@ -33,14 +33,14 @@ $no_strip = false; // compress with upx -$upx = false; +$upx = true; // prefer downloading pre-built packages to speed up the build process -$prefer_pre_built = false; +$prefer_pre_built = true; // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'pgsql,pdo_pgsql', + 'Linux', 'Darwin' => 'imagick', 'Windows' => 'pgsql,pdo_pgsql', }; From ab4d7fae7de8ec909c504a8c8de9fea53511f62f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 19:16:01 +0800 Subject: [PATCH 05/23] Fix typo --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 29f195bb..5819b4ba 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -185,7 +185,7 @@ jobs: echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV - name: "Prepare UPX for Linux" - if: matrix.os == 'ubunut-latest' + if: matrix.os == 'ubuntu-latest' run: | bin/spc install-pkg upx echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV From 67d2ad5511e9aad3814b7f78de0b17a98b191578 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 19:21:29 +0800 Subject: [PATCH 06/23] Add debug console output for Downloader --- src/SPC/store/Downloader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index ebb814a2..66a47b45 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -124,6 +124,7 @@ public static function getLatestGithubRelease(string $name, array $source, bool if (($source['prefer-stable'] ?? false) === true && $release['prerelease'] === true) { continue; } + logger()->debug("Found {$release['name']} releases assets"); if (!$match_result) { return $release['assets']; } From 631a1b586497558e6fd89d56fa01ddaa60f391dd Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:16:41 +0800 Subject: [PATCH 07/23] Add libc version for pre-built content name --- config/pre-built.json | 2 +- src/SPC/builder/LibraryBase.php | 2 +- src/SPC/builder/linux/SystemUtil.php | 31 +++++++++++++++++++++++ src/SPC/command/DeleteDownloadCommand.php | 2 +- src/SPC/command/DownloadCommand.php | 2 ++ src/SPC/command/dev/PackLibCommand.php | 3 +++ src/SPC/store/Downloader.php | 6 ++--- src/SPC/store/SourceManager.php | 2 +- 8 files changed, 43 insertions(+), 7 deletions(-) diff --git a/config/pre-built.json b/config/pre-built.json index 1f1803f8..829023c7 100644 --- a/config/pre-built.json +++ b/config/pre-built.json @@ -1,7 +1,7 @@ { "repo": "static-php/static-php-cli-hosted", "prefer-stable": true, - "match-pattern-linux": "{name}-{arch}-{os}-{libc}.txz", + "match-pattern-linux": "{name}-{arch}-{os}-{libc}-{libcver}.txz", "match-pattern": "{name}-{arch}-{os}.txz", "suffix": "txz" } \ No newline at end of file diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 165e4f13..5ac43508 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -46,7 +46,7 @@ public function setup(bool $force = false): int $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; $source = Config::getLib(static::NAME, 'source'); // if source is locked as pre-built, we just tryInstall it - $pre_built_name = Downloader::getPreBuiltName($source); + $pre_built_name = Downloader::getPreBuiltLockName($source); if (isset($lock[$pre_built_name]) && ($lock[$pre_built_name]['lock_as'] ?? SPC_DOWN_SOURCE) === SPC_DOWN_PRE_BUILT) { return $this->tryInstall($lock[$pre_built_name]['filename'], $force); } diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index c0ae6766..a2efe9bb 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -182,4 +182,35 @@ public static function getSupportedDistros(): array 'arch', 'manjaro', ]; } + + /** + * Get libc version string from ldd + */ + public static function getLibcVersionIfExists(): ?string + { + if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'glibc') { + $result = shell()->execWithResult('ldd --version'); + if ($result[0] !== 0) { + return null; + } + // get first line + $first_line = $result[1][0]; + // match ldd version: "ldd (some useless text) 2.17" match 2.17 + $pattern = '/ldd\s+\(.*?\)\s+(\d+\.\d+)/'; + if (preg_match($pattern, $first_line, $matches)) { + return $matches[1]; + } + return null; + } + if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { + $result = shell()->execWithResult('ldd 2>&1'); + // Match Version * line + // match ldd version: "Version 1.2.3" match 1.2.3 + $pattern = '/Version\s+(\d+\.\d+\.\d+)/'; + if (preg_match($pattern, $result[1][1], $matches)) { + return $matches[1]; + } + } + return null; + } } diff --git a/src/SPC/command/DeleteDownloadCommand.php b/src/SPC/command/DeleteDownloadCommand.php index 1471451c..b68b8618 100644 --- a/src/SPC/command/DeleteDownloadCommand.php +++ b/src/SPC/command/DeleteDownloadCommand.php @@ -51,7 +51,7 @@ public function handle(): int $deleted_sources = []; foreach ($chosen_sources as $source) { $source = trim($source); - foreach ([$source, Downloader::getPreBuiltName($source)] as $name) { + foreach ([$source, Downloader::getPreBuiltLockName($source)] as $name) { if (isset($lock[$name])) { $deleted_sources[] = $name; } diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 85a01b56..9a7f6310 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -4,6 +4,7 @@ namespace SPC\command; +use SPC\builder\linux\SystemUtil; use SPC\builder\traits\UnixSystemUtilTrait; use SPC\exception\DownloaderException; use SPC\exception\FileSystemException; @@ -236,6 +237,7 @@ public function handle(): int '{arch}' => arch2gnu(php_uname('m')), '{os}' => strtolower(PHP_OS_FAMILY), '{libc}' => getenv('SPC_LIBC') ?: 'default', + '{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default', ]; $find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern')); // find filename in asset list diff --git a/src/SPC/command/dev/PackLibCommand.php b/src/SPC/command/dev/PackLibCommand.php index 340736d5..c10c62f3 100644 --- a/src/SPC/command/dev/PackLibCommand.php +++ b/src/SPC/command/dev/PackLibCommand.php @@ -6,6 +6,7 @@ use SPC\builder\BuilderProvider; use SPC\builder\LibraryBase; +use SPC\builder\linux\SystemUtil; use SPC\command\BuildCommand; use SPC\exception\ExceptionHandler; use SPC\exception\FileSystemException; @@ -23,6 +24,7 @@ class PackLibCommand extends BuildCommand public function configure(): void { $this->addArgument('library', InputArgument::REQUIRED, 'The library will be compiled'); + $this->addOption('show-libc-ver', null, null); } public function handle(): int @@ -75,6 +77,7 @@ public function handle(): int '{arch}' => arch2gnu(php_uname('m')), '{os}' => strtolower(PHP_OS_FAMILY), '{libc}' => getenv('SPC_LIBC') ?: 'default', + '{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default', ]; $filename = str_replace(array_keys($replace), array_values($replace), $filename); $filename = WORKING_DIR . '/dist/' . $filename . '.' . Config::getPreBuilt('suffix'); diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 66a47b45..f133f404 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -204,7 +204,7 @@ public static function downloadFile(string $name, string $url, string $filename, self::unregisterCancelEvent(); logger()->debug("Locking {$filename}"); if ($download_as === SPC_DOWN_PRE_BUILT) { - $name = self::getPreBuiltName($name); + $name = self::getPreBuiltLockName($name); } self::lockSource($name, ['source_type' => 'archive', 'filename' => $filename, 'move_path' => $move_path, 'lock_as' => $download_as]); } @@ -594,7 +594,7 @@ public static function curlDown(string $url, string $path, string $method = 'GET } } - public static function getPreBuiltName(string $source): string + public static function getPreBuiltLockName(string $source): string { return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default'); } @@ -653,7 +653,7 @@ private static function isAlreadyDownloaded(string $name, bool $force, int $down } } // If lock file exists for current arch and glibc target, skip downloading - $lock_name = self::getPreBuiltName($name); + $lock_name = self::getPreBuiltLockName($name); if (!$force && $download_as === SPC_DOWN_PRE_BUILT && isset($lock[$lock_name])) { // lock name with env if ( diff --git a/src/SPC/store/SourceManager.php b/src/SPC/store/SourceManager.php index b18a47be..c36bfc58 100644 --- a/src/SPC/store/SourceManager.php +++ b/src/SPC/store/SourceManager.php @@ -55,7 +55,7 @@ public static function initSource(?array $sources = null, ?array $libs = null, ? throw new WrongUsageException("Source [{$source}] does not exist, please check the name and correct it !"); } // check source downloaded - $pre_built_name = Downloader::getPreBuiltName($source); + $pre_built_name = Downloader::getPreBuiltLockName($source); if (!isset($lock[$pre_built_name])) { if (!isset($lock[$source])) { throw new WrongUsageException("Source [{$source}] not downloaded or not locked, you should download it first !"); From 8e5657eff0a902d967159c48001c57100f0ff1a4 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:20:04 +0800 Subject: [PATCH 08/23] Separate musl-dist and non-musl-dist --- src/SPC/builder/linux/SystemUtil.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index a2efe9bb..b65cb78f 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -203,7 +203,11 @@ public static function getLibcVersionIfExists(): ?string return null; } if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { - $result = shell()->execWithResult('ldd 2>&1'); + if (self::isMuslDist()) { + $result = shell()->execWithResult('ldd 2>&1'); + } else { + $result = shell()->execWithResult('/usr/local/musl/lib/libc.so 2>&1'); + } // Match Version * line // match ldd version: "Version 1.2.3" match 1.2.3 $pattern = '/Version\s+(\d+\.\d+\.\d+)/'; From 4e5c0f0a484b8dca3e4cc537f6763ec3b8b1e013 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:21:56 +0800 Subject: [PATCH 09/23] Add additional log output for pre-built finder --- src/SPC/command/DownloadCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 9a7f6310..46b72f4f 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -360,6 +360,7 @@ private function calculateSourcesByLib(array $libs, bool $include_suggests = tru */ private function findPreBuilt(array $assets, string $filename): ?string { + logger()->debug("Finding pre-built asset {$filename}"); foreach ($assets as $asset) { if ($asset['name'] === $filename) { return $asset['browser_download_url']; From a940200164ebcd4d27cba5610da8fda01956c712 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:34:57 +0800 Subject: [PATCH 10/23] Return default version for musl and musl-wrapper --- src/SPC/builder/linux/SystemUtil.php | 9 ++++++--- src/SPC/store/Config.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index b65cb78f..1e56fc68 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -189,7 +189,7 @@ public static function getSupportedDistros(): array public static function getLibcVersionIfExists(): ?string { if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'glibc') { - $result = shell()->execWithResult('ldd --version'); + $result = shell()->execWithResult('ldd --version', false); if ($result[0] !== 0) { return null; } @@ -202,11 +202,13 @@ public static function getLibcVersionIfExists(): ?string } return null; } + /* + // for musl, disabled temporarily as musl has better compatibility between different patch version? if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { if (self::isMuslDist()) { - $result = shell()->execWithResult('ldd 2>&1'); + $result = shell()->execWithResult('ldd 2>&1', false); } else { - $result = shell()->execWithResult('/usr/local/musl/lib/libc.so 2>&1'); + $result = shell()->execWithResult('/usr/local/musl/lib/libc.so 2>&1', false); } // Match Version * line // match ldd version: "Version 1.2.3" match 1.2.3 @@ -215,6 +217,7 @@ public static function getLibcVersionIfExists(): ?string return $matches[1]; } } + */ return null; } } diff --git a/src/SPC/store/Config.php b/src/SPC/store/Config.php index f7074d47..68ba4399 100644 --- a/src/SPC/store/Config.php +++ b/src/SPC/store/Config.php @@ -31,7 +31,7 @@ public static function getPreBuilt(string $name): mixed if (self::$pre_built === null) { self::$pre_built = FileSystem::loadConfigArray('pre-built'); } - $supported_sys_based = ['match-pattern']; + $supported_sys_based = ['match-pattern', 'prefer-stable', 'repo']; if (in_array($name, $supported_sys_based)) { $m_key = match (PHP_OS_FAMILY) { 'Windows' => ['-windows', '-win', ''], From 01d3cb4b11da004fa81a3f4b83b670dadbf02642 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:53:41 +0800 Subject: [PATCH 11/23] Test arm runner --- .github/workflows/tests.yml | 6 +++--- src/globals/test-extensions.php | 35 +++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5819b4ba..5abfc6e0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -176,16 +176,16 @@ jobs: run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist - name: "Run Build Tests (doctor)" - run: bin/spc doctor --auto-fix --debug + run: php src/globals/test-extensions.php doctor_cmd ${{ matrix.os }} ${{ matrix.php }} - name: "Prepare UPX for Windows" - if: matrix.os == 'windows-latest' + if: ${{ startsWith(matrix.os, 'windows-') }} run: | bin/spc install-pkg upx echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV - name: "Prepare UPX for Linux" - if: matrix.os == 'ubuntu-latest' + if: ${{ startsWith(matrix.os, 'ubuntu-') }} run: | bin/spc install-pkg upx echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index bd3351a6..97f0df8d 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -24,7 +24,9 @@ // 'macos-13', // 'macos-14', 'ubuntu-latest', - 'windows-latest', + 'ubuntu-22.04', + 'ubuntu-22.04-arm', + 'ubuntu-24.04-arm', ]; // whether enable thread safe @@ -115,6 +117,10 @@ function quote2(string $param): string $down_cmd .= $prefer_pre_built ? '--prefer-pre-built ' : ''; } +if ($argv[1] === 'doctor_cmd') { + $doctor_cmd = 'doctor --auto-fix --debug'; +} + // generate build command if ($argv[1] === 'build_cmd' || $argv[1] === 'build_embed_cmd') { $build_cmd = 'build '; @@ -139,30 +145,33 @@ function quote2(string $param): string 'upx' => $upx ? '--with-upx-pack' : '', 'prefer_pre_built' => $prefer_pre_built ? '--prefer-pre-built' : '', 'download_cmd' => $down_cmd, + 'doctor_cmd' => $doctor_cmd, 'build_cmd' => $build_cmd, 'build_embed_cmd' => $build_cmd, default => '', }; +$prefix = match ($argv[2]) { + 'windows-latest', 'windows-2022', 'windows-2019', 'windows-2025' => 'powershell.exe -file .\bin\spc.ps1 ', + 'ubuntu-latest', 'ubuntu-24.04', 'ubuntu-24.04-arm' => './bin/spc ', + 'ubuntu-22.04', 'ubuntu-22.04-arm' => 'bin/spc-gnu-docker ', + 'ubuntu-20.04' => 'bin/spc-alpine-docker ', + default => 'bin/spc ', +}; + if ($argv[1] === 'download_cmd') { - if (str_starts_with($argv[2], 'windows-')) { - passthru('powershell.exe -file .\bin\spc.ps1 ' . $down_cmd, $retcode); - } else { - passthru('./bin/spc ' . $down_cmd, $retcode); - } + passthru($prefix . $down_cmd, $retcode); } elseif ($argv[1] === 'build_cmd') { - if (str_starts_with($argv[2], 'windows-')) { - passthru('powershell.exe -file .\bin\spc.ps1 ' . $build_cmd . ' --build-cli --build-micro', $retcode); - } else { - passthru('./bin/spc ' . $build_cmd . ' --build-cli --build-micro', $retcode); - } + passthru($prefix . $build_cmd . ' --build-cli --build-micro', $retcode); } elseif ($argv[1] === 'build_embed_cmd') { if (str_starts_with($argv[2], 'windows-')) { // windows does not accept embed SAPI - passthru('powershell.exe -file .\bin\spc.ps1 ' . $build_cmd . ' --build-cli', $retcode); + passthru($prefix . $build_cmd . ' --build-cli', $retcode); } else { - passthru('./bin/spc ' . $build_cmd . ' --build-embed', $retcode); + passthru($prefix . $build_cmd . ' --build-embed', $retcode); } +} elseif ($argv[1] === 'doctor_cmd') { + passthru($prefix . $doctor_cmd, $retcode); } else { $retcode = 0; } From 50cfc5899b668bd05143900e503ef1cae59f8e92 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:54:32 +0800 Subject: [PATCH 12/23] Re-enable musl version detect --- src/SPC/builder/linux/SystemUtil.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index 1e56fc68..08867db2 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -202,7 +202,6 @@ public static function getLibcVersionIfExists(): ?string } return null; } - /* // for musl, disabled temporarily as musl has better compatibility between different patch version? if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { if (self::isMuslDist()) { @@ -217,7 +216,6 @@ public static function getLibcVersionIfExists(): ?string return $matches[1]; } } - */ return null; } } From 23bd216cc737b72bd2a7b9cf4ca120443d5ded8a Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 21:03:11 +0800 Subject: [PATCH 13/23] Add upx cmd for tests --- .github/workflows/tests.yml | 4 ++-- src/globals/test-extensions.php | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5abfc6e0..7648873a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -181,13 +181,13 @@ jobs: - name: "Prepare UPX for Windows" if: ${{ startsWith(matrix.os, 'windows-') }} run: | - bin/spc install-pkg upx + php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }} echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV - name: "Prepare UPX for Linux" if: ${{ startsWith(matrix.os, 'ubuntu-') }} run: | - bin/spc install-pkg upx + php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }} echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV - name: "Run Build Tests (download)" diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 97f0df8d..9143a207 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -120,6 +120,9 @@ function quote2(string $param): string if ($argv[1] === 'doctor_cmd') { $doctor_cmd = 'doctor --auto-fix --debug'; } +if ($argv[1] === 'install_upx_cmd') { + $install_upx_cmd = 'install-pkg upx'; +} // generate build command if ($argv[1] === 'build_cmd' || $argv[1] === 'build_embed_cmd') { @@ -145,6 +148,7 @@ function quote2(string $param): string 'upx' => $upx ? '--with-upx-pack' : '', 'prefer_pre_built' => $prefer_pre_built ? '--prefer-pre-built' : '', 'download_cmd' => $down_cmd, + 'install_upx_cmd' => $install_upx_cmd, 'doctor_cmd' => $doctor_cmd, 'build_cmd' => $build_cmd, 'build_embed_cmd' => $build_cmd, @@ -172,6 +176,8 @@ function quote2(string $param): string } } elseif ($argv[1] === 'doctor_cmd') { passthru($prefix . $doctor_cmd, $retcode); +} elseif ($argv[1] === 'install_upx_cmd') { + passthru($prefix . $install_upx_cmd, $retcode); } else { $retcode = 0; } From 2d7c052fd9b4f9cfcc172d5cc4e687b56fc1c18c Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 21:03:19 +0800 Subject: [PATCH 14/23] Remove comment --- src/SPC/builder/linux/SystemUtil.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index 08867db2..8b115663 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -202,7 +202,6 @@ public static function getLibcVersionIfExists(): ?string } return null; } - // for musl, disabled temporarily as musl has better compatibility between different patch version? if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { if (self::isMuslDist()) { $result = shell()->execWithResult('ldd 2>&1', false); From 11f0957963160b5af233881141837ae99d8cfed1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 21:03:40 +0800 Subject: [PATCH 15/23] Add SPC_DOCKER_DEBUG for gnu docker, remove classmap for alpine docker --- bin/spc-alpine-docker | 2 +- bin/spc-gnu-docker | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/spc-alpine-docker b/bin/spc-alpine-docker index 28cc4939..e2e28dcd 100755 --- a/bin/spc-alpine-docker +++ b/bin/spc-alpine-docker @@ -95,7 +95,7 @@ WORKDIR /app ADD ./src /app/src COPY ./composer.* /app/ ADD ./bin /app/bin -RUN composer install --no-dev --classmap-authoritative +RUN composer install --no-dev EOF fi diff --git a/bin/spc-gnu-docker b/bin/spc-gnu-docker index fa84e58c..101994e4 100755 --- a/bin/spc-gnu-docker +++ b/bin/spc-gnu-docker @@ -145,4 +145,8 @@ echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm -lresolv -lutil -lrt"' # shellcheck disable=SC2086 # shellcheck disable=SC2090 -$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH bin/spc $@ +if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then + $DOCKER_EXECUTABLE run --rm -it --privileged $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH +else + $DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH bin/spc $@ +fi From acb8cea437014c4a1aeae2fc38855a5d41b81899 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 21:14:27 +0800 Subject: [PATCH 16/23] Add glibc build for CI --- .github/workflows/build-unix.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-unix.yml b/.github/workflows/build-unix.yml index 0ec63e24..8212a828 100644 --- a/.github/workflows/build-unix.yml +++ b/.github/workflows/build-unix.yml @@ -6,10 +6,13 @@ on: os: required: true description: Build target OS + default: 'linux-x86_64' type: choice options: - 'linux-x86_64' - 'linux-aarch64' + - 'linux-x86_64-glibc' + - 'linux-aarch64-glibc' - 'macos-x86_64' - 'macos-aarch64' php-version: @@ -22,7 +25,6 @@ on: - '8.3' - '8.2' - '8.1' - - '8.0' extensions: description: Extensions to build (comma separated) required: true @@ -77,9 +79,19 @@ jobs: RUNS_ON="ubuntu-latest" ;; linux-aarch64) - DOWN_CMD="SPC_USE_ARCH=aarch64 ./bin/spc-alpine-docker download" - BUILD_CMD="SPC_USE_ARCH=aarch64 ./bin/spc-alpine-docker build" - RUNS_ON="ubuntu-latest" + DOWN_CMD="./bin/spc-alpine-docker download" + BUILD_CMD="./bin/spc-alpine-docker build" + RUNS_ON="ubuntu-24.04-arm" + ;; + linux-x86_64-glibc) + DOWN_CMD="./bin/spc-gnu-docker download" + BUILD_CMD="./bin/spc-gnu-docker build" + RUNS_ON="ubuntu-22.04" + ;; + linux-x86_64-glibc) + DOWN_CMD="./bin/spc-gnu-docker download" + BUILD_CMD="./bin/spc-gnu-docker build" + RUNS_ON="ubuntu-22.04-arm" ;; macos-x86_64) DOWN_CMD="composer update --no-dev --classmap-authoritative && ./bin/spc doctor --auto-fix && ./bin/spc download" From c58ea0c3bd1534feecbb4adf00fb800081d1e848 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 21:24:46 +0800 Subject: [PATCH 17/23] Fix PHP warning in test-extensions.php --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 9143a207..c8e2f8cb 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -155,7 +155,7 @@ function quote2(string $param): string default => '', }; -$prefix = match ($argv[2]) { +$prefix = match ($argv[2] ?? null) { 'windows-latest', 'windows-2022', 'windows-2019', 'windows-2025' => 'powershell.exe -file .\bin\spc.ps1 ', 'ubuntu-latest', 'ubuntu-24.04', 'ubuntu-24.04-arm' => './bin/spc ', 'ubuntu-22.04', 'ubuntu-22.04-arm' => 'bin/spc-gnu-docker ', From 67afffeb9618d1713d634c16cc7ea63a2acbf6e4 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 21:59:58 +0800 Subject: [PATCH 18/23] Remove redundant suffix, add libc version suffix --- config/pre-built.json | 3 +-- src/SPC/command/dev/PackLibCommand.php | 2 +- src/SPC/store/Downloader.php | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/pre-built.json b/config/pre-built.json index 829023c7..31264a35 100644 --- a/config/pre-built.json +++ b/config/pre-built.json @@ -2,6 +2,5 @@ "repo": "static-php/static-php-cli-hosted", "prefer-stable": true, "match-pattern-linux": "{name}-{arch}-{os}-{libc}-{libcver}.txz", - "match-pattern": "{name}-{arch}-{os}.txz", - "suffix": "txz" + "match-pattern": "{name}-{arch}-{os}.txz" } \ No newline at end of file diff --git a/src/SPC/command/dev/PackLibCommand.php b/src/SPC/command/dev/PackLibCommand.php index c10c62f3..fd62f3f1 100644 --- a/src/SPC/command/dev/PackLibCommand.php +++ b/src/SPC/command/dev/PackLibCommand.php @@ -80,7 +80,7 @@ public function handle(): int '{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default', ]; $filename = str_replace(array_keys($replace), array_values($replace), $filename); - $filename = WORKING_DIR . '/dist/' . $filename . '.' . Config::getPreBuilt('suffix'); + $filename = WORKING_DIR . '/dist/' . $filename; f_passthru('tar -czf ' . $filename . ' -T ' . WORKING_DIR . '/packlib_files.txt'); logger()->info('Pack library ' . $lib->getName() . ' to ' . $filename . ' complete.'); } diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index f133f404..984cada8 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -4,6 +4,7 @@ namespace SPC\store; +use SPC\builder\linux\SystemUtil; use SPC\exception\DownloaderException; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; @@ -596,7 +597,7 @@ public static function curlDown(string $url, string $path, string $method = 'GET public static function getPreBuiltLockName(string $source): string { - return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default'); + return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default') . '-' . (SystemUtil::getLibcVersionIfExists() ?: 'default'); } /** From 62d619b6cd74f610b0c95fce50e0730d9df9cf4c Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 22:05:20 +0800 Subject: [PATCH 19/23] Fix redundant pre-built name calling --- src/SPC/builder/linux/SystemUtil.php | 2 +- src/SPC/store/Downloader.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index 8b115663..e49830d2 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -211,7 +211,7 @@ public static function getLibcVersionIfExists(): ?string // Match Version * line // match ldd version: "Version 1.2.3" match 1.2.3 $pattern = '/Version\s+(\d+\.\d+\.\d+)/'; - if (preg_match($pattern, $result[1][1], $matches)) { + if (preg_match($pattern, $result[1][1] ?? '', $matches)) { return $matches[1]; } } diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 984cada8..605cd556 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -654,8 +654,8 @@ private static function isAlreadyDownloaded(string $name, bool $force, int $down } } // If lock file exists for current arch and glibc target, skip downloading - $lock_name = self::getPreBuiltLockName($name); - if (!$force && $download_as === SPC_DOWN_PRE_BUILT && isset($lock[$lock_name])) { + + if (!$force && $download_as === SPC_DOWN_PRE_BUILT && isset($lock[$lock_name = self::getPreBuiltLockName($name)])) { // lock name with env if ( $lock[$lock_name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$lock_name]['filename']) || From 7dec34bdfe418857d5a9ab5a48348bd32b4a2998 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 22:05:50 +0800 Subject: [PATCH 20/23] Fix redundant pre-built name calling --- src/SPC/store/Downloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 605cd556..8652a7bd 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -597,7 +597,7 @@ public static function curlDown(string $url, string $path, string $method = 'GET public static function getPreBuiltLockName(string $source): string { - return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default') . '-' . (SystemUtil::getLibcVersionIfExists() ?: 'default'); + return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default') . '-' . (SystemUtil::getLibcVersionIfExists() ?? 'default'); } /** From 237d39f09c9033eb4afb3943d59f947eeb9348c4 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 23:27:05 +0800 Subject: [PATCH 21/23] Fix CI wrong runner name --- .github/workflows/build-unix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-unix.yml b/.github/workflows/build-unix.yml index 8212a828..457910da 100644 --- a/.github/workflows/build-unix.yml +++ b/.github/workflows/build-unix.yml @@ -88,7 +88,7 @@ jobs: BUILD_CMD="./bin/spc-gnu-docker build" RUNS_ON="ubuntu-22.04" ;; - linux-x86_64-glibc) + linux-aarch64-glibc) DOWN_CMD="./bin/spc-gnu-docker download" BUILD_CMD="./bin/spc-gnu-docker build" RUNS_ON="ubuntu-22.04-arm" From 6dd6d807b6fa46c7d7e4da3d578e6e384e596775 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 23:27:23 +0800 Subject: [PATCH 22/23] Fix end of line space --- config/pre-built.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/pre-built.json b/config/pre-built.json index 31264a35..22991a61 100644 --- a/config/pre-built.json +++ b/config/pre-built.json @@ -3,4 +3,4 @@ "prefer-stable": true, "match-pattern-linux": "{name}-{arch}-{os}-{libc}-{libcver}.txz", "match-pattern": "{name}-{arch}-{os}.txz" -} \ No newline at end of file +} From 5c04638cb4f66d7b94b88fd03d8c204fae911c0f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 23:27:43 +0800 Subject: [PATCH 23/23] Full spell for SPC_DOWNLOAD --- src/SPC/builder/LibraryBase.php | 2 +- src/SPC/command/DownloadCommand.php | 2 +- src/SPC/command/dev/PackLibCommand.php | 2 +- src/SPC/store/Downloader.php | 30 +++++++++++------------ src/SPC/store/source/CustomSourceBase.php | 2 +- src/SPC/store/source/PhpSource.php | 2 +- src/SPC/store/source/PostgreSQLSource.php | 2 +- src/globals/defines.php | 6 ++--- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 5ac43508..2c75f4ca 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -47,7 +47,7 @@ public function setup(bool $force = false): int $source = Config::getLib(static::NAME, 'source'); // if source is locked as pre-built, we just tryInstall it $pre_built_name = Downloader::getPreBuiltLockName($source); - if (isset($lock[$pre_built_name]) && ($lock[$pre_built_name]['lock_as'] ?? SPC_DOWN_SOURCE) === SPC_DOWN_PRE_BUILT) { + if (isset($lock[$pre_built_name]) && ($lock[$pre_built_name]['lock_as'] ?? SPC_DOWNLOAD_SOURCE) === SPC_DOWNLOAD_PRE_BUILT) { return $this->tryInstall($lock[$pre_built_name]['filename'], $force); } return $this->tryBuild($force); diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 46b72f4f..b31db2d5 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -243,7 +243,7 @@ public function handle(): int // find filename in asset list if (($url = $this->findPreBuilt($pre_built_libs, $find)) !== null) { logger()->info("[{$ni}/{$cnt}] Downloading pre-built content {$source}"); - Downloader::downloadSource($source, ['type' => 'url', 'url' => $url], $force_all || in_array($source, $force_list), SPC_DOWN_PRE_BUILT); + Downloader::downloadSource($source, ['type' => 'url', 'url' => $url], $force_all || in_array($source, $force_list), SPC_DOWNLOAD_PRE_BUILT); continue; } logger()->warning("Pre-built content not found for {$source}, fallback to source download"); diff --git a/src/SPC/command/dev/PackLibCommand.php b/src/SPC/command/dev/PackLibCommand.php index fd62f3f1..d7eb750a 100644 --- a/src/SPC/command/dev/PackLibCommand.php +++ b/src/SPC/command/dev/PackLibCommand.php @@ -49,7 +49,7 @@ public function handle(): int // Get lock info $lock = json_decode(file_get_contents(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; $source = Config::getLib($lib->getName(), 'source'); - if (!isset($lock[$source]) || ($lock[$source]['lock_as'] ?? SPC_DOWN_SOURCE) === SPC_DOWN_PRE_BUILT) { + if (!isset($lock[$source]) || ($lock[$source]['lock_as'] ?? SPC_DOWNLOAD_SOURCE) === SPC_DOWNLOAD_PRE_BUILT) { logger()->critical("The library {$lib->getName()} is downloaded as pre-built, we need to build it instead of installing pre-built."); return static::FAILURE; } diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 8652a7bd..7a857c48 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -191,7 +191,7 @@ public static function getFromFileList(string $name, array $source): array * @throws RuntimeException * @throws WrongUsageException */ - public static function downloadFile(string $name, string $url, string $filename, ?string $move_path = null, int $download_as = SPC_DOWN_SOURCE): void + public static function downloadFile(string $name, string $url, string $filename, ?string $move_path = null, int $download_as = SPC_DOWNLOAD_SOURCE): void { logger()->debug("Downloading {$url}"); $cancel_func = function () use ($filename) { @@ -204,7 +204,7 @@ public static function downloadFile(string $name, string $url, string $filename, self::curlDown(url: $url, path: FileSystem::convertPath(DOWNLOAD_PATH . "/{$filename}"), retry: self::getRetryTime()); self::unregisterCancelEvent(); logger()->debug("Locking {$filename}"); - if ($download_as === SPC_DOWN_PRE_BUILT) { + if ($download_as === SPC_DOWNLOAD_PRE_BUILT) { $name = self::getPreBuiltLockName($name); } self::lockSource($name, ['source_type' => 'archive', 'filename' => $filename, 'move_path' => $move_path, 'lock_as' => $download_as]); @@ -241,7 +241,7 @@ public static function lockSource(string $name, array $data): void * @throws RuntimeException * @throws WrongUsageException */ - public static function downloadGit(string $name, string $url, string $branch, ?string $move_path = null, int $retry = 0, int $lock_as = SPC_DOWN_SOURCE): void + public static function downloadGit(string $name, string $url, string $branch, ?string $move_path = null, int $retry = 0, int $lock_as = SPC_DOWNLOAD_SOURCE): void { $download_path = FileSystem::convertPath(DOWNLOAD_PATH . "/{$name}"); if (file_exists($download_path)) { @@ -329,7 +329,7 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f FileSystem::createDir(DOWNLOAD_PATH); } - if (self::isAlreadyDownloaded($name, $force, SPC_DOWN_PACKAGE)) { + if (self::isAlreadyDownloaded($name, $force, SPC_DOWNLOAD_PACKAGE)) { return; } @@ -337,28 +337,28 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f switch ($pkg['type']) { case 'bitbuckettag': // BitBucket Tag [$url, $filename] = self::getLatestBitbucketTag($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWNLOAD_PACKAGE); break; case 'ghtar': // GitHub Release (tar) [$url, $filename] = self::getLatestGithubTarball($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWNLOAD_PACKAGE); break; case 'ghtagtar': // GitHub Tag (tar) [$url, $filename] = self::getLatestGithubTarball($name, $pkg, 'tags'); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWNLOAD_PACKAGE); break; case 'ghrel': // GitHub Release (uploaded) [$url, $filename] = self::getLatestGithubRelease($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWNLOAD_PACKAGE); break; case 'filelist': // Basic File List (regex based crawler) [$url, $filename] = self::getFromFileList($name, $pkg); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWNLOAD_PACKAGE); break; case 'url': // Direct download URL $url = $pkg['url']; $filename = $pkg['filename'] ?? basename($pkg['url']); - self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWN_PACKAGE); + self::downloadFile($name, $url, $filename, $pkg['extract'] ?? null, SPC_DOWNLOAD_PACKAGE); break; case 'git': // Git repo self::downloadGit( @@ -367,7 +367,7 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f $pkg['rev'], $pkg['extract'] ?? null, self::getRetryTime(), - SPC_DOWN_PRE_BUILT + SPC_DOWNLOAD_PRE_BUILT ); break; case 'custom': // Custom download method, like API-based download or other @@ -419,7 +419,7 @@ public static function downloadPackage(string $name, ?array $pkg = null, bool $f * @throws FileSystemException * @throws WrongUsageException */ - public static function downloadSource(string $name, ?array $source = null, bool $force = false, int $download_as = SPC_DOWN_SOURCE): void + public static function downloadSource(string $name, ?array $source = null, bool $force = false, int $download_as = SPC_DOWNLOAD_SOURCE): void { if ($source === null) { $source = Config::getSource($name); @@ -636,7 +636,7 @@ private static function getRetryTime(): int /** * @throws FileSystemException */ - private static function isAlreadyDownloaded(string $name, bool $force, int $download_as = SPC_DOWN_SOURCE): bool + private static function isAlreadyDownloaded(string $name, bool $force, int $download_as = SPC_DOWNLOAD_SOURCE): bool { if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) { $lock = []; @@ -644,7 +644,7 @@ private static function isAlreadyDownloaded(string $name, bool $force, int $down $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; } // If lock file exists, skip downloading for source mode - if (!$force && $download_as === SPC_DOWN_SOURCE && isset($lock[$name])) { + if (!$force && $download_as === SPC_DOWNLOAD_SOURCE && isset($lock[$name])) { if ( $lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename']) || $lock[$name]['source_type'] === 'dir' && is_dir(DOWNLOAD_PATH . '/' . $lock[$name]['dirname']) @@ -655,7 +655,7 @@ private static function isAlreadyDownloaded(string $name, bool $force, int $down } // If lock file exists for current arch and glibc target, skip downloading - if (!$force && $download_as === SPC_DOWN_PRE_BUILT && isset($lock[$lock_name = self::getPreBuiltLockName($name)])) { + if (!$force && $download_as === SPC_DOWNLOAD_PRE_BUILT && isset($lock[$lock_name = self::getPreBuiltLockName($name)])) { // lock name with env if ( $lock[$lock_name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$lock_name]['filename']) || diff --git a/src/SPC/store/source/CustomSourceBase.php b/src/SPC/store/source/CustomSourceBase.php index 243341ad..3fce1568 100644 --- a/src/SPC/store/source/CustomSourceBase.php +++ b/src/SPC/store/source/CustomSourceBase.php @@ -8,5 +8,5 @@ abstract class CustomSourceBase { public const NAME = 'unknown'; - abstract public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWN_SOURCE): void; + abstract public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void; } diff --git a/src/SPC/store/source/PhpSource.php b/src/SPC/store/source/PhpSource.php index 405d6ca6..d2617e3b 100644 --- a/src/SPC/store/source/PhpSource.php +++ b/src/SPC/store/source/PhpSource.php @@ -17,7 +17,7 @@ class PhpSource extends CustomSourceBase * @throws DownloaderException * @throws FileSystemException */ - public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWN_SOURCE): void + public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void { $major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.3'; Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force); diff --git a/src/SPC/store/source/PostgreSQLSource.php b/src/SPC/store/source/PostgreSQLSource.php index 6c025ef0..7c85a8d4 100644 --- a/src/SPC/store/source/PostgreSQLSource.php +++ b/src/SPC/store/source/PostgreSQLSource.php @@ -16,7 +16,7 @@ class PostgreSQLSource extends CustomSourceBase * @throws DownloaderException * @throws FileSystemException */ - public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWN_SOURCE): void + public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void { Downloader::downloadSource('postgresql', self::getLatestInfo(), $force); } diff --git a/src/globals/defines.php b/src/globals/defines.php index f3d3187f..699cecc1 100644 --- a/src/globals/defines.php +++ b/src/globals/defines.php @@ -41,9 +41,9 @@ ]; // spc lock type -const SPC_DOWN_SOURCE = 1; // lock source -const SPC_DOWN_PRE_BUILT = 2; // lock pre-built -const SPC_DOWN_PACKAGE = 3; // lock as package +const SPC_DOWNLOAD_SOURCE = 1; // lock source +const SPC_DOWNLOAD_PRE_BUILT = 2; // lock pre-built +const SPC_DOWNLOAD_PACKAGE = 3; // lock as package // file replace strategy const REPLACE_FILE_STR = 1;