From f709f3bb18406b50ac102326478b99f4e8ef6dd1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 18 Jun 2025 20:55:24 +0800 Subject: [PATCH] Add custom package downloader and extractor --- src/SPC/store/Downloader.php | 22 ++++++++++++++++++---- src/SPC/store/PackageManager.php | 15 +++++++++++++++ src/SPC/store/pkg/CustomPackage.php | 17 +++++++++++++++++ src/globals/functions.php | 11 +++++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/SPC/store/pkg/CustomPackage.php diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index b0c663d3..e5cc6aae 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -9,6 +9,7 @@ use SPC\exception\DownloaderException; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\store\pkg\CustomPackage; use SPC\store\source\CustomSourceBase; /** @@ -385,10 +386,13 @@ class Downloader ]); break; case 'custom': // Custom download method, like API-based download or other - $classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\store\source'); + $classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/pkg', 'SPC\store\pkg'); foreach ($classes as $class) { - if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) { - (new $class())->fetch($force); + if (is_a($class, CustomPackage::class, true) && $class !== CustomPackage::class) { + $cls = new $class(); + if (in_array($name, $cls->getSupportName())) { + (new $class())->fetch($name, $force, $pkg); + } break; } } @@ -708,7 +712,6 @@ class Downloader } } // If lock file exists for current arch and glibc target, skip downloading - if (!$force && $download_as === SPC_DOWNLOAD_PRE_BUILT && isset($lock[$lock_name = self::getPreBuiltLockName($name)])) { // lock name with env if ( @@ -719,6 +722,17 @@ class Downloader return true; } } + + // If lock file exists, skip downloading for source mode + if (!$force && $download_as === SPC_DOWNLOAD_PACKAGE && isset($lock[$name])) { + if ( + $lock[$name]['source_type'] === SPC_SOURCE_ARCHIVE && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename']) || + $lock[$name]['source_type'] === SPC_SOURCE_GIT && is_dir(DOWNLOAD_PATH . '/' . $lock[$name]['dirname']) + ) { + logger()->notice("Package [{$name}] already downloaded: " . ($lock[$name]['filename'] ?? $lock[$name]['dirname'])); + return true; + } + } return false; } } diff --git a/src/SPC/store/PackageManager.php b/src/SPC/store/PackageManager.php index ca930228..7e8ae3fd 100644 --- a/src/SPC/store/PackageManager.php +++ b/src/SPC/store/PackageManager.php @@ -6,6 +6,7 @@ namespace SPC\store; use SPC\exception\FileSystemException; use SPC\exception\WrongUsageException; +use SPC\store\pkg\CustomPackage; class PackageManager { @@ -32,6 +33,20 @@ class PackageManager // Download package Downloader::downloadPackage($pkg_name, $config, $force); + if (Config::getPkg($pkg_name)['type'] === 'custom') { + // Custom extract function + $classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/pkg', 'SPC\store\pkg'); + foreach ($classes as $class) { + if (is_a($class, CustomPackage::class, true) && $class !== CustomPackage::class) { + $cls = new $class(); + if (in_array($pkg_name, $cls->getSupportName())) { + (new $class())->extract($pkg_name); + break; + } + } + } + return; + } // After download, read lock file name $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true); $source_type = $lock[$pkg_name]['source_type']; diff --git a/src/SPC/store/pkg/CustomPackage.php b/src/SPC/store/pkg/CustomPackage.php new file mode 100644 index 00000000..89edb17e --- /dev/null +++ b/src/SPC/store/pkg/CustomPackage.php @@ -0,0 +1,17 @@ + 'win', + 'Darwin' => 'macos', + 'Linux' => 'linux', + 'BSD' => 'bsd', + default => throw new WrongUsageException('Not support os: ' . PHP_OS_FAMILY), + }; +} + function shell(?bool $debug = null): UnixShell { /* @noinspection PhpUnhandledExceptionInspection */