mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-17 20:54:52 +08:00
add plugin:pack command and pack events
This commit is contained in:
parent
80c22ceac6
commit
b1aea186ef
@ -16,6 +16,7 @@ class PluginPackCommand extends PluginCommand
|
||||
protected function configure()
|
||||
{
|
||||
$this->addArgument('name', InputArgument::REQUIRED, '要打包的插件名称');
|
||||
$this->addOption('build-dir', 'D', InputOption::VALUE_REQUIRED, '指定输出文件位置', WORKING_DIR . '/build');
|
||||
|
||||
// 下面是辅助用的,和 server:start 一样
|
||||
$this->addOption('config-dir', null, InputOption::VALUE_REQUIRED, '指定其他配置文件目录');
|
||||
@ -27,7 +28,12 @@ class PluginPackCommand extends PluginCommand
|
||||
protected function handle(): int
|
||||
{
|
||||
try {
|
||||
PluginManager::packPlugin($this->input->getArgument('name'));
|
||||
$outpupt = PluginManager::packPlugin(
|
||||
plugin_name: $this->input->getArgument('name'),
|
||||
build_dir: $this->input->getOption('build-dir'),
|
||||
command_context: $this
|
||||
);
|
||||
$this->info("插件打包完成,输出文件:{$outpupt}");
|
||||
} catch (PluginException $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
|
||||
@ -8,8 +8,10 @@ use Jelix\Version\VersionComparator;
|
||||
use ZM\Annotation\AnnotationMap;
|
||||
use ZM\Annotation\AnnotationParser;
|
||||
use ZM\Annotation\Framework\BindEvent;
|
||||
use ZM\Command\Command;
|
||||
use ZM\Exception\PluginException;
|
||||
use ZM\Store\FileSystem;
|
||||
use ZM\Store\PharHelper;
|
||||
|
||||
class PluginManager
|
||||
{
|
||||
@ -270,19 +272,80 @@ class PluginManager
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static function packPlugin(string $name): string
|
||||
public static function packPlugin(string $plugin_name, string $build_dir, ?Command $command_context = null): string
|
||||
{
|
||||
// 必须是源码模式才行
|
||||
if (!isset(self::$plugins[$name]) || self::$plugins[$name]->getPluginType() !== ZM_PLUGIN_TYPE_SOURCE) {
|
||||
throw new PluginException("没有找到名字为 {$name} 的插件(要打包的插件必须是源码模式)。");
|
||||
if (!isset(self::$plugins[$plugin_name]) || self::$plugins[$plugin_name]->getPluginType() !== ZM_PLUGIN_TYPE_SOURCE) {
|
||||
throw new PluginException("没有找到名字为 {$plugin_name} 的插件(要打包的插件必须是源码模式)。");
|
||||
}
|
||||
try {
|
||||
// 创建目录
|
||||
FileSystem::createDir($build_dir);
|
||||
$plugin = self::$plugins[$plugin_name];
|
||||
// 插件目录
|
||||
$dir = $plugin->getRootDir();
|
||||
// 先判断是不是可写的
|
||||
PharHelper::ensurePharWritable();
|
||||
// 拼接 phar 名称,通过插件名和版本号(如果没有版本号则使用 1.0-dev 作为版本号)
|
||||
$phar_name = $plugin->getName() . '_' . $plugin->getVersion() . '.phar';
|
||||
$phar_name = zm_dir($build_dir . '/' . $phar_name);
|
||||
// 判断文件如果存在的话是否是可写的
|
||||
PharHelper::ensurePharFileWritable($phar_name);
|
||||
// 文件存在先删除
|
||||
if (file_exists($phar_name)) {
|
||||
$command_context?->info('Phar 文件 ' . $phar_name . ' 已存在,删除中...');
|
||||
unlink($phar_name);
|
||||
}
|
||||
// 先执行一些打包前检查的 bootstrap
|
||||
// 1. 检查插件是否引用了 require-dev 的内容(检查 --no-dev)
|
||||
if (file_exists($dir . '/composer.json') && file_exists($dir . '/vendor/composer/installed.json')) {
|
||||
$json = json_decode(file_get_contents($dir . '/vendor/composer/installed.json'), true);
|
||||
if (!isset($json['dev'])) {
|
||||
$command_context?->error('插件的 Composer 未正确配置,忽略检查 dev 模式!');
|
||||
} elseif ($json['dev'] === true) {
|
||||
throw new PluginException(
|
||||
"插件的 Composer 配置了 dev 模式,但是打包时没有使用 --no-dev 选项,无法打包\n" .
|
||||
'请先进入插件目录,执行 composer update --no-dev'
|
||||
);
|
||||
}
|
||||
}
|
||||
// 创建 Phar 对象
|
||||
$phar = new \Phar($phar_name, 0);
|
||||
// 调用插件的打包的用户自定义前置方法
|
||||
$plugin->getEntity()?->emitPack();
|
||||
// 扫描插件目录
|
||||
$dir_list = FileSystem::scanDirFiles($dir, true, true);
|
||||
if ($command_context instanceof Command) {
|
||||
$dir_list = $command_context->progress()->iterate($dir_list);
|
||||
}
|
||||
$file_added = 0;
|
||||
$file_ignored = 0;
|
||||
foreach ($dir_list as $v) {
|
||||
// 过滤文件
|
||||
if ($plugin->getEntity()?->emitFilterPack($v) === false) {
|
||||
++$file_ignored;
|
||||
continue;
|
||||
}
|
||||
// 添加文件
|
||||
$phar->addFromString($v, php_strip_whitespace(zm_dir($dir . '/' . $v)));
|
||||
++$file_added;
|
||||
}
|
||||
// 找有没有 main,没有 main 就不添加 stub
|
||||
$main = (json_decode(file_get_contents($dir . '/zmplugin.json'), true)['main'] ?? 'main.php');
|
||||
if (file_exists(zm_dir($dir . '/' . $main)) && $phar->offsetExists($main)) {
|
||||
$command_context?->info('设置插件默认入口文件 ' . $main);
|
||||
$phar->setStub($phar->setDefaultStub($main));
|
||||
} else {
|
||||
$phar->setStub('<?php __HALT_COMPILER();');
|
||||
}
|
||||
// 停止
|
||||
$phar->stopBuffering();
|
||||
// 输出结果
|
||||
$command_context?->info("共添加 {$file_added} 个文件" . ($file_ignored > 0 ? ",忽略 {$file_ignored} 个文件" : ''));
|
||||
return $phar_name;
|
||||
} catch (\PharException $e) {
|
||||
throw new PluginException("插件 {$plugin_name} 打包失败,原因为 Phar 异常:\n" . $e->getMessage(), previous: $e);
|
||||
}
|
||||
|
||||
$plugin = self::$plugins[$name];
|
||||
// 插件目录
|
||||
$dir = $plugin->getRootDir();
|
||||
// TODO: 写到这了
|
||||
// 插件加载方式判断
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -44,7 +44,7 @@ class PluginMeta implements \JsonSerializable
|
||||
// 设置名称
|
||||
$this->name = $meta['name'] ?? '<anonymous>';
|
||||
// 设置版本
|
||||
$this->version = $meta['version'] ?? '1.0.0';
|
||||
$this->version = $meta['version'] ?? '1.0-dev';
|
||||
// 设置描述
|
||||
$this->description = $meta['description'] ?? '';
|
||||
// 设置依赖
|
||||
@ -52,7 +52,7 @@ class PluginMeta implements \JsonSerializable
|
||||
$this->metas = $meta;
|
||||
// 设置插件根目录
|
||||
$this->plugin_type = $plugin_type;
|
||||
// 设置插件类型
|
||||
// 设置插件根目录
|
||||
$this->root_dir = $root_dir;
|
||||
}
|
||||
|
||||
|
||||
51
src/ZM/Plugin/Traits/PluginPackTrait.php
Normal file
51
src/ZM/Plugin/Traits/PluginPackTrait.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Plugin\Traits;
|
||||
|
||||
trait PluginPackTrait
|
||||
{
|
||||
protected mixed $on_pack = null;
|
||||
|
||||
protected mixed $on_pack_filter = null;
|
||||
|
||||
/**
|
||||
* 设置插件被打包前执行的回调函数
|
||||
*
|
||||
* @param callable $callback 回调函数
|
||||
* @return void
|
||||
*/
|
||||
public function onPack(callable $callback): void
|
||||
{
|
||||
$this->on_pack = $callback;
|
||||
}
|
||||
|
||||
public function filterPack(callable $callback): void
|
||||
{
|
||||
$this->on_pack_filter = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function emitPack(): void
|
||||
{
|
||||
if (is_callable($this->on_pack)) {
|
||||
($this->on_pack)();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param string $file 文件名称,由 PluginManager 传入
|
||||
* @return bool 返回 False 代表该文件不需要打包
|
||||
*/
|
||||
public function emitFilterPack(string $file): bool
|
||||
{
|
||||
if (is_callable($this->on_pack_filter)) {
|
||||
return (bool) ($this->on_pack_filter)($file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -17,4 +17,5 @@ class ZMPlugin
|
||||
use Traits\InitTrait;
|
||||
use Traits\PluginLoadTrait;
|
||||
use Traits\RouteTrait;
|
||||
use Traits\PluginPackTrait;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user