فهرست منبع

refactor: 移除 installedSixShop.php 与 composer hook,运行时从 InstalledVersions 计算并缓存到 runtime/,新增 sixshop:clear-extension-cache 命令

runphp 1 ماه پیش
والد
کامیت
5f505c3dd5

+ 0 - 34
bin/generate-installed-sixshop.php

@@ -1,34 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-defined('EXTENSION_TYPE') || define('EXTENSION_TYPE', 'sixshop-extension');
-
-$dir = __DIR__;
-while (!is_file($dir . '/vendor/composer/installed.php')) {
-    $parent = dirname($dir);
-    if ($parent === $dir) {
-        fwrite(STDERR, "Unable to locate vendor/composer/installed.php\n");
-        exit(1);
-    }
-    $dir = $parent;
-}
-$vendorDir = $dir . '/vendor';
-
-$installed = require $vendorDir . '/composer/installed.php';
-
-$installedSixShopExtensions = [
-    'root' => [],
-    'versions' => [],
-];
-$referenceMap = [];
-foreach ($installed['versions'] as $name => $package) {
-    if (isset($package['type']) && $package['type'] === EXTENSION_TYPE) {
-        $installedSixShopExtensions['versions'][$name] = $package;
-        $referenceMap[$name] = $package['reference'];
-    }
-}
-$installedSixShopExtensions['root']['reference'] = hash('md5', json_encode($referenceMap));
-
-$filePath = $vendorDir . '/composer/installedSixShop.php';
-file_put_contents($filePath, '<?php return ' . var_export($installedSixShopExtensions, true) . ';');

+ 23 - 0
src/Command/ClearExtensionCacheCommand.php

@@ -0,0 +1,23 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SixShop\Core\Command;
+
+use SixShop\Core\Service\CoreService;
+use think\console\Command;
+
+class ClearExtensionCacheCommand extends Command
+{
+    public function configure(): void
+    {
+        $this->setName('sixshop:clear-extension-cache')
+            ->setDescription('Clear extension composer cache files in runtime/');
+    }
+
+    public function handle(): void
+    {
+        $count = CoreService::clearExtensionCache();
+        $this->output->writeln('Cleared ' . $count . ' extension cache file(s).');
+    }
+}

+ 0 - 22
src/Command/GenerateInstalledSixShopCommand.php

@@ -1,22 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace SixShop\Core\Command;
-
-use think\console\Command;
-
-class GenerateInstalledSixShopCommand extends Command
-{
-    public function configure(): void
-    {
-        $this->setName('generate:installed-sixshop')
-            ->setDescription('Generate vendor/composer/installedSixShop.php');
-    }
-
-    public function handle(): void
-    {
-        require dirname(__DIR__, 2) . '/bin/generate-installed-sixshop.php';
-        $this->output->writeln('Generated: ' . $this->app->getRootPath() . 'vendor/composer/installedSixShop.php');
-    }
-}

+ 14 - 5
src/Plugin.php

@@ -20,11 +20,20 @@ class Plugin
         if (self::$installedSixShopExtensions) {
         if (self::$installedSixShopExtensions) {
             return self::$installedSixShopExtensions;
             return self::$installedSixShopExtensions;
         }
         }
-        $composerDir = dirname(InstalledVersions::getInstallPath('composer/composer'), 2);
-        $filePath = $composerDir . '/installedSixShop.php';
-        if (!file_exists($filePath)) {
-            require dirname(__DIR__) . '/bin/generate-installed-sixshop.php';
+        $versions = [];
+        $referenceMap = [];
+        foreach (InstalledVersions::getInstalledPackagesByType(self::EXTENSION_TYPE) as $name) {
+            $versions[$name] = [
+                'name' => $name,
+                'version' => InstalledVersions::getPrettyVersion($name) ?? 'dev-main',
+                'reference' => InstalledVersions::getReference($name),
+                'install_path' => InstalledVersions::getInstallPath($name),
+            ];
+            $referenceMap[$name] = InstalledVersions::getReference($name) ?: $versions[$name]['version'];
         }
         }
-        return self::$installedSixShopExtensions = require $filePath;
+        return self::$installedSixShopExtensions = [
+            'root' => ['reference' => hash('md5', json_encode($referenceMap))],
+            'versions' => $versions,
+        ];
     }
     }
 }
 }

+ 29 - 11
src/Service/CoreService.php

@@ -8,7 +8,7 @@ use Composer\InstalledVersions;
 use Composer\Json\JsonFile;
 use Composer\Json\JsonFile;
 use ReflectionException;
 use ReflectionException;
 use Seld\JsonLint\ParsingException;
 use Seld\JsonLint\ParsingException;
-use SixShop\Core\Command\GenerateInstalledSixShopCommand;
+use SixShop\Core\Command\ClearExtensionCacheCommand;
 use SixShop\Core\Exception\ExceptionHandle;
 use SixShop\Core\Exception\ExceptionHandle;
 use SixShop\Core\Plugin;
 use SixShop\Core\Plugin;
 use SixShop\Core\Request;
 use SixShop\Core\Request;
@@ -67,22 +67,40 @@ class CoreService extends Service
             self::$extensionComposerMap = require $extensionComposerFile;
             self::$extensionComposerMap = require $extensionComposerFile;
             return;
             return;
         }
         }
-        $files = array_diff(scandir($runtimePath), ['.', '..']);
-        foreach ($files as $file) {
-            if (str_starts_with($file, 'extension_') && str_ends_with($file, '.php')) {
-                unlink($runtimePath . $file);
-            }
+        foreach (glob($runtimePath . 'extension_*.php') ?: [] as $file) {
+            unlink($runtimePath . basename($file));
         }
         }
+        self::$extensionComposerMap = self::buildExtensionComposerMap();
+        $header = '// This file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL . 'declare (strict_types = 1);' . PHP_EOL;
+        $content = '<?php ' . PHP_EOL . $header . "return " . var_export(self::$extensionComposerMap, true) . ';';
+        file_put_contents($extensionComposerFile, $content);
+    }
+
+    /**
+     * @throws ParsingException
+     */
+    public static function buildExtensionComposerMap(): array
+    {
+        $map = [];
         foreach (InstalledVersions::getInstalledPackagesByType(Plugin::EXTENSION_TYPE) as $item) {
         foreach (InstalledVersions::getInstalledPackagesByType(Plugin::EXTENSION_TYPE) as $item) {
             $installPath = InstalledVersions::getInstallPath($item);
             $installPath = InstalledVersions::getInstallPath($item);
             $composerJson = new JsonFile($installPath . '/composer.json');
             $composerJson = new JsonFile($installPath . '/composer.json');
             $composer = $composerJson->read();
             $composer = $composerJson->read();
             $extensionID = $composer['extra']['sixshop']['id'] ?? $composer['name'];
             $extensionID = $composer['extra']['sixshop']['id'] ?? $composer['name'];
-            self::$extensionComposerMap[$extensionID] = $composer;
+            $map[$extensionID] = $composer;
         }
         }
-        $header = '// This file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL . 'declare (strict_types = 1);' . PHP_EOL;
-        $content = '<?php ' . PHP_EOL . $header . "return " . var_export(self::$extensionComposerMap, true) . ';';
-        file_put_contents($extensionComposerFile, $content);
+        return $map;
+    }
+
+    public static function clearExtensionCache(): int
+    {
+        $count = 0;
+        foreach (glob(dirname(self::$extensionPath) . '/runtime/extension_*.php') ?: [] as $file) {
+            unlink($file);
+            $count++;
+        }
+        self::$extensionComposerMap = [];
+        return $count;
     }
     }
 
 
     /**
     /**
@@ -111,7 +129,7 @@ class CoreService extends Service
         });
         });
 
 
         $this->commands([
         $this->commands([
-            GenerateInstalledSixShopCommand::class,
+            ClearExtensionCacheCommand::class,
         ]);
         ]);
         $this->app->make(CommandService::class)->init(function ($commands) {
         $this->app->make(CommandService::class)->init(function ($commands) {
             $this->commands($commands);
             $this->commands($commands);