From af0568e87eab26767d5f2f67a25688af84dbde9b Mon Sep 17 00:00:00 2001 From: Death-Satan <49744633+Death-Satan@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:27:11 +0800 Subject: [PATCH] Added plugin create command --- src/app-store/src/Command/AbstractCommand.php | 27 ++++ src/app-store/src/Command/CreateCommand.php | 149 ++++++++++++++++++ ...ownloadCommand.php => DownloadCommand.php} | 2 +- ...nInitialCommand.php => InitialCommand.php} | 2 +- ...nInstallCommand.php => InstallCommand.php} | 2 +- ...tensionListCommand.php => ListCommand.php} | 2 +- ...alListCommand.php => LocalListCommand.php} | 2 +- .../src/Command/Stub/ConfigProvider.stub | 20 +++ .../src/Command/Stub/InstallScript.stub | 11 ++ .../src/Command/Stub/UninstallScript.stub | 11 ++ ...nstallCommand.php => UninstallCommand.php} | 2 +- src/app-store/src/Enums/PluginTypeEnum.php | 44 ++++++ src/app-store/src/Utils/FileSystemUtils.php | 8 + 13 files changed, 276 insertions(+), 6 deletions(-) create mode 100644 src/app-store/src/Command/AbstractCommand.php create mode 100644 src/app-store/src/Command/CreateCommand.php rename src/app-store/src/Command/{ExtensionDownloadCommand.php => DownloadCommand.php} (96%) rename src/app-store/src/Command/{ExtensionInitialCommand.php => InitialCommand.php} (98%) rename src/app-store/src/Command/{ExtensionInstallCommand.php => InstallCommand.php} (97%) rename src/app-store/src/Command/{ExtensionListCommand.php => ListCommand.php} (97%) rename src/app-store/src/Command/{ExtensionLocalListCommand.php => LocalListCommand.php} (96%) create mode 100644 src/app-store/src/Command/Stub/ConfigProvider.stub create mode 100644 src/app-store/src/Command/Stub/InstallScript.stub create mode 100644 src/app-store/src/Command/Stub/UninstallScript.stub rename src/app-store/src/Command/{ExtensionUninstallCommand.php => UninstallCommand.php} (97%) create mode 100644 src/app-store/src/Enums/PluginTypeEnum.php diff --git a/src/app-store/src/Command/AbstractCommand.php b/src/app-store/src/Command/AbstractCommand.php new file mode 100644 index 00000000..0a4c0a59 --- /dev/null +++ b/src/app-store/src/Command/AbstractCommand.php @@ -0,0 +1,27 @@ +commandName()); + } + + abstract public function __invoke(); + + abstract public function commandName(): string; +} diff --git a/src/app-store/src/Command/CreateCommand.php b/src/app-store/src/Command/CreateCommand.php new file mode 100644 index 00000000..eadf8742 --- /dev/null +++ b/src/app-store/src/Command/CreateCommand.php @@ -0,0 +1,149 @@ +input->getArgument('path'); + $name = $this->input->getOption('name'); + $type = $this->input->getOption('type') ?? 'mix'; + $type = PluginTypeEnum::fromValue($type); + if ($type === null) { + $this->output->error('Plugin type is empty'); + return; + } + if (! FileSystemUtils::checkDirectory($name)) { + $this->output->error(sprintf('The given directory name %s is not a valid directory', $path)); + } + $pluginPath = Plugin::PLUGIN_PATH . '/' . $path; + if (file_exists($pluginPath)) { + $this->output->error(sprintf('Plugin directory %s already exists', $path)); + return; + } + if (! mkdir($pluginPath, 0755, true) && ! is_dir($pluginPath)) { + throw new \RuntimeException(sprintf('Directory "%s" was not created', $pluginPath)); + } + + $this->createMineJson($pluginPath, $name, $type); + } + + #[\Override] + public function commandName(): string + { + return 'create'; + } + + public function createMineJson(string $path, string $name, PluginTypeEnum $pluginType): void + { + $output = new \stdClass(); + $output->name = $name; + $output->description = $this->input->getOption('description') ?: 'This is a sample plugin'; + $author = $this->input->getOption('author') ?: 'demo'; + $output->author = [ + [ + 'name' => $author, + ], + ]; + if ($pluginType === PluginTypeEnum::Backend || $pluginType === PluginTypeEnum::Mix) { + $namespace = 'Mine\\' . Str::snake($author) . '\\Example'; + + $this->createInstallScript($namespace, $path); + $this->createUninstallScript($namespace, $path); + $this->createConfigProvider($namespace, $path); + $output->composer = [ + 'require' => [], + 'psr-4' => [ + $namespace . '\\' => 'src', + ], + 'installScript' => $namespace . '\\InstallScript', + 'uninstallScript' => $namespace . '\\UninstallScript', + 'config' => $namespace . '\\ConfigProvider', + ]; + } + + if ($pluginType === PluginTypeEnum::Mix || $pluginType === PluginTypeEnum::Frond) { + $output->package = [ + 'dependencies' => [ + ], + ]; + } + + $output = json_encode($output, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE, 512); + file_put_contents($path . '/mine.json', $output); + $this->output->success(sprintf('%s 创建成功', $path . '/mine.json')); + } + + public function createConfigProvider(string $namespace, string $path): void + { + $installScript = $this->buildStub('ConfigProvider', compact('namespace')); + $installScriptPath = $path . '/src/ConfigProvider.php'; + file_put_contents($installScriptPath, $installScript); + $this->output->success(sprintf('%s Created Successfully', $installScriptPath)); + } + + public function createInstallScript(string $namespace, string $path): void + { + $installScript = $this->buildStub('InstallScript', compact('namespace')); + $installScriptPath = $path . '/src/InstallScript.php'; + file_put_contents($installScriptPath, $installScript); + $this->output->success(sprintf('%s Created Successfully', $installScriptPath)); + } + + public function createUninstallScript(string $namespace, string $path): void + { + $installScript = $this->buildStub('UninstallScript', compact('namespace')); + $installScriptPath = $path . '/src/UninstallScript.php'; + file_put_contents($installScriptPath, $installScript); + $this->output->success(sprintf('%s Created Successfully', $installScriptPath)); + } + + public function buildStub(string $stub, array $replace): string + { + $stubPath = $this->getStubDirectory() . '/' . $stub . '.stub'; + if (! file_exists($stubPath)) { + throw new \RuntimeException(sprintf('File %s does not exist', $stubPath)); + } + $stubBody = file_get_contents($stubPath); + foreach ($replace as $key => $value) { + $stubBody = str_replace('%' . $key . '%', $value, $stubBody); + } + return $stubBody; + } + + public function getStubDirectory(): string + { + return realpath(__DIR__) . '/Stub'; + } + + protected function configure() + { + $this->addArgument('path', InputArgument::REQUIRED, 'Plugin Path'); + $this->addOption('name', 'n', InputOption::VALUE_REQUIRED, 'Plug-in Name'); + $this->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'Plugin type, default mix optional mix,frond,backend'); + $this->addOption('description', 'desc', InputOption::VALUE_OPTIONAL, 'Plug-in Introduction'); + $this->addOption('author', 'desc', InputOption::VALUE_OPTIONAL, 'Plugin Author Information'); + } +} diff --git a/src/app-store/src/Command/ExtensionDownloadCommand.php b/src/app-store/src/Command/DownloadCommand.php similarity index 96% rename from src/app-store/src/Command/ExtensionDownloadCommand.php rename to src/app-store/src/Command/DownloadCommand.php index 4c2907a0..c7650590 100644 --- a/src/app-store/src/Command/ExtensionDownloadCommand.php +++ b/src/app-store/src/Command/DownloadCommand.php @@ -19,7 +19,7 @@ use Xmo\AppStore\Service\AppStoreService; #[Command] -class ExtensionDownloadCommand extends Base +class DownloadCommand extends Base { protected ?string $name = 'mine-extension:download'; diff --git a/src/app-store/src/Command/ExtensionInitialCommand.php b/src/app-store/src/Command/InitialCommand.php similarity index 98% rename from src/app-store/src/Command/ExtensionInitialCommand.php rename to src/app-store/src/Command/InitialCommand.php index 0be70cd2..66bf4509 100644 --- a/src/app-store/src/Command/ExtensionInitialCommand.php +++ b/src/app-store/src/Command/InitialCommand.php @@ -18,7 +18,7 @@ use Symfony\Component\Console\Input\InputOption; #[Command] -class ExtensionInitialCommand extends Base +class InitialCommand extends Base { protected ?string $name = 'mine-extension:initial'; diff --git a/src/app-store/src/Command/ExtensionInstallCommand.php b/src/app-store/src/Command/InstallCommand.php similarity index 97% rename from src/app-store/src/Command/ExtensionInstallCommand.php rename to src/app-store/src/Command/InstallCommand.php index 4a19874a..a68ef2c4 100644 --- a/src/app-store/src/Command/ExtensionInstallCommand.php +++ b/src/app-store/src/Command/InstallCommand.php @@ -20,7 +20,7 @@ use Xmo\AppStore\Service\PluginService; #[Command] -class ExtensionInstallCommand extends Base +class InstallCommand extends Base { protected ?string $name = 'mine-extension:install'; diff --git a/src/app-store/src/Command/ExtensionListCommand.php b/src/app-store/src/Command/ListCommand.php similarity index 97% rename from src/app-store/src/Command/ExtensionListCommand.php rename to src/app-store/src/Command/ListCommand.php index 9641afc5..1ced53c6 100644 --- a/src/app-store/src/Command/ExtensionListCommand.php +++ b/src/app-store/src/Command/ListCommand.php @@ -19,7 +19,7 @@ use Xmo\AppStore\Service\AppStoreService; #[Command] -class ExtensionListCommand extends Base +class ListCommand extends Base { protected ?string $name = 'mine-extension:list'; diff --git a/src/app-store/src/Command/ExtensionLocalListCommand.php b/src/app-store/src/Command/LocalListCommand.php similarity index 96% rename from src/app-store/src/Command/ExtensionLocalListCommand.php rename to src/app-store/src/Command/LocalListCommand.php index 5661dd7f..07df3fc4 100644 --- a/src/app-store/src/Command/ExtensionLocalListCommand.php +++ b/src/app-store/src/Command/LocalListCommand.php @@ -17,7 +17,7 @@ use Xmo\AppStore\Plugin; #[Command] -class ExtensionLocalListCommand extends Base +class LocalListCommand extends Base { protected ?string $name = 'mine-extension:local-list'; diff --git a/src/app-store/src/Command/Stub/ConfigProvider.stub b/src/app-store/src/Command/Stub/ConfigProvider.stub new file mode 100644 index 00000000..5fca456e --- /dev/null +++ b/src/app-store/src/Command/Stub/ConfigProvider.stub @@ -0,0 +1,20 @@ + [ + 'scan' => [ + 'paths' => [ + __DIR__, + ], + ], + ], + ]; + } +} \ No newline at end of file diff --git a/src/app-store/src/Command/Stub/InstallScript.stub b/src/app-store/src/Command/Stub/InstallScript.stub new file mode 100644 index 00000000..6725936d --- /dev/null +++ b/src/app-store/src/Command/Stub/InstallScript.stub @@ -0,0 +1,11 @@ + self::Mix, + 'frond' => self::Frond, + 'backend' => self::Backend, + default => null + }; + } +} diff --git a/src/app-store/src/Utils/FileSystemUtils.php b/src/app-store/src/Utils/FileSystemUtils.php index 5a848348..67e6815c 100644 --- a/src/app-store/src/Utils/FileSystemUtils.php +++ b/src/app-store/src/Utils/FileSystemUtils.php @@ -44,4 +44,12 @@ public static function recovery(string $relationFilePath, string $dist): void FileSystem::copy($backFile, $targetFile); } } + + /** + * Checks if the given name is a valid directory path. + */ + public static function checkDirectory(string $name): bool + { + return (bool) preg_match('/^\/(?:[^\/\0]+\/)*[^\/\0]+$/', $name); + } }