增加扩展机制定位文件;将common模块实现扩展模式;发布新版本;

This commit is contained in:
2023-09-25 17:07:38 +08:00
parent 3dcf336bbc
commit 184dae8185
65 changed files with 3093 additions and 2751 deletions

View File

@@ -4,49 +4,8 @@ declare(strict_types=1);
namespace app\common\command\admin;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\App;
use base\common\command\admin\ClearBase;
class Clear extends Command
class Clear extends ClearBase
{
protected function configure()
{
// 指令配置
$this->setName('admin:clear')
->setDescription('删除开发临时生成目录');
}
protected function execute(Input $input, Output $output)
{
// 指令输出
$output->writeln('删除测试目录');
$command_line = '';
$dir = App::getRootPath() . '/runtime/source/';
if (!is_dir($dir)) {
$output->writeln('删除成功');
return;
}
if (strpos(strtolower(PHP_OS), 'win') === 0) {
$command_line = implode(' ', ['rd', '/s', '/q', str_replace('/', '\\', $dir)]);
} else {
$command_line = implode(' ', ['rm', '-rf', $dir]);
}
$output->info('删除目录:' . $command_line);
$output->info('run command: ' . $command_line);
exec($command_line);
$output->info('删除成功');
}
}

View File

@@ -4,47 +4,8 @@ declare(strict_types=1);
namespace app\common\command\admin;
use app\admin\model\SystemAdmin;
use app\common\constants\AdminConstant;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use base\common\command\admin\ResetPasswordBase;
class ResetPassword extends Command
class ResetPassword extends ResetPasswordBase
{
protected function configure()
{
// 指令配置
$this->setName('admin:reset:password')
->addOption('password','p', Option::VALUE_OPTIONAL)
->setDescription('重置超管密码');
}
protected function execute(Input $input, Output $output)
{
// 指令输出
$output->writeln('admin:reset:password');
$model_admin = SystemAdmin::find(AdminConstant::SUPER_ADMIN_ID);
if (empty($model_admin)) {
$output->writeln('管理员不存在');
return false;
}
$password = $input->getOption('password');
if(is_null($password)){
$password = uniqid();
}
$model_admin->save([
'password' => password($password)
]);
$output->writeln('密码修改为:' . $password);
}
}

View File

@@ -4,309 +4,8 @@ declare(strict_types=1);
namespace app\common\command\admin;
use app\common\tools\PathTools;
use CzProject\GitPhp\Git;
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
use League\Flysystem\StorageAttributes;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\App;
use think\facade\Env;
use base\common\command\admin\UpdateBase;
class Update extends Command
class Update extends UpdateBase
{
public const REPO = 'https://gitee.com/ulthon/ulthon_admin.git';
protected function configure()
{
// 指令配置
$this->setName('admin:update')
->addOption('reinstall', null, Option::VALUE_NONE, '重装版本')
->setDescription('the admin:update command');
}
protected function execute(Input $input, Output $output)
{
// 指令输出
$output->writeln('admin:update');
$this->cleanWorkpaceDir();
$current_version = Version::VERSION;
$current_version_dir = App::getRuntimePath() . '/update/' . $current_version;
$last_version_dir = App::getRuntimePath() . '/update/last';
$version_file_regx = "/\bconst VERSION\s*=\s*'[\d\.a-z]+'/";
$output->writeln('获取最新代码');
$last_version_git = new Git();
$last_version_repo = $last_version_git->cloneRepository(self::REPO, $last_version_dir);
$tags = $last_version_repo->getTags();
$update_level = Env::get('adminsystem.update_level', 'production');
if ($update_level == 'production') {
$tags = array_filter($tags, function ($value) {
if (strpos($value, '-')) {
return false;
}
return true;
});
}
usort($tags, function ($a, $b) {
return version_compare($a, $b);
});
$last_version = $tags[count($tags) - 1];
if ($last_version == $current_version) {
$output->writeln('当前版本为最新版本');
$this->cleanWorkpaceDir();
if ($input->hasOption('reinstall')) {
$output->writeln('重装代码');
} else {
return;
}
}
// 将最新代码切换到最新版本,因为最新的提交可能没有发布版本
$output->writeln('切换最新代码的最新版本');
$last_version_repo->checkout($last_version);
$current_version_git = new Git();
$output->writeln('获取当前版本代码');
$current_version_repo = $current_version_git->cloneRepository(self::REPO, $current_version_dir);
$output->writeln('切换版本' . $current_version);
$current_version_repo->checkout($current_version);
// 获取当前版本需要跳过的文件
$current_version_update_config = include $current_version_dir . '/config/update.php';
// 获取当前版本要替换的文件
$current_version_filesystem = new Filesystem(new LocalFilesystemAdapter($current_version_dir));
$current_version_list_files = $current_version_filesystem->listContents('/', Filesystem::LIST_DEEP)
->filter(function (StorageAttributes $attributes) use ($current_version_update_config) {
if ($attributes->isDir()) {
return false;
}
$path = $attributes->path();
$skip_files = $current_version_update_config['skip_files'] ?? [];
if (in_array($path, $skip_files)) {
return false;
}
$skip_dir = $current_version_update_config['skip_dir'] ?? [];
$skip_dir[] = '.git';
foreach ($skip_dir as $dir) {
if (str_starts_with($path, $dir)) {
return false;
}
}
return true;
})
->map(fn (StorageAttributes $attributes) => $attributes->path())
->toArray();
// 对比现在的代码,检查是否有定制修改
$output->writeln('对比源码是否被定制');
$now_dir = App::getRootPath();
/**
* @var array<bool|string>
*/
$changed_files = [];
foreach ($current_version_list_files as $file_path) {
$now_file_path = $now_dir . '/' . $file_path;
$current_version_file_path = $current_version_dir . '/' . $file_path;
$compare_result = PathTools::compareFiles($now_file_path, $current_version_file_path, true);
if (!$compare_result || is_string($compare_result)) {
$changed_files[$file_path] = $compare_result;
}
}
// 有定制修改则退出
if (!empty($changed_files)) {
$output->warning('无法自动更新,以下文件被定制,请还原或手动升级:');
foreach ($changed_files as $file_path => $compare_result) {
$output->warning($file_path);
if (is_string($compare_result)) {
$output->writeln($compare_result);
}
}
$file_count = count($changed_files);
$ask_result = $output->ask($input, "发现{$file_count}个文件被修改,如果您认为以上文件可以被覆盖或为检测错误,可以强制覆盖。\n是否强制继续更新?(y/n)");
if (!$ask_result) {
return;
}
}
// 获取最新版本需要跳过的文件
$last_version_skip_config = include $last_version_dir . '/config/update.php';
// 获取最新版本要替换的文件
$last_version_filesystem = new Filesystem(new LocalFilesystemAdapter($last_version_dir));
$last_version_list_files = $last_version_filesystem->listContents('/', Filesystem::LIST_DEEP)
->filter(function (StorageAttributes $attributes) use ($last_version_skip_config) {
if ($attributes->isDir()) {
return false;
}
$path = $attributes->path();
$skip_files = $last_version_skip_config['skip_files'] ?? [];
if (in_array($path, $skip_files)) {
return false;
}
$skip_dir = $last_version_skip_config['skip_dir'] ?? [];
$skip_dir[] = '.git';
foreach ($skip_dir as $dir) {
if (str_starts_with($path, $dir)) {
return false;
}
}
return true;
})
->map(fn (StorageAttributes $attributes) => $attributes->path())
->toArray();
$delete_files = array_diff($current_version_list_files, $last_version_list_files);
foreach ($delete_files as $file_path) {
$now_file_path = $now_dir . '/' . $file_path;
unlink($now_file_path);
}
foreach ($last_version_list_files as $file_path) {
$now_file_path = $now_dir . '/' . $file_path;
$last_file_path = $last_version_dir . '/' . $file_path;
$file_content = file_get_contents($last_file_path);
PathTools::intiDir($now_file_path);
file_put_contents($now_file_path, $file_content);
}
// 处理append的文件
$last_version_list_skip_files = $last_version_filesystem->listContents('/', Filesystem::LIST_DEEP)
->filter(function (StorageAttributes $attributes) use ($last_version_skip_config) {
if ($attributes->isDir()) {
return false;
}
$path = $attributes->path();
if (str_starts_with($path, '.git')) {
return false;
}
$skip_files = $last_version_skip_config['skip_files'] ?? [];
if (in_array($path, $skip_files)) {
return true;
}
$skip_dir = $last_version_skip_config['skip_dir'] ?? [];
foreach ($skip_dir as $dir) {
if (str_starts_with($path, $dir)) {
return true;
}
}
return true;
})
->map(fn (StorageAttributes $attributes) => $attributes->path())
->toArray();
$last_version_list_append_files = [];
foreach ($last_version_list_skip_files as $file_path) {
if (in_array($file_path, $last_version_skip_config['append_files'])) {
$last_version_list_append_files[] = $file_path;
continue;
}
foreach ($last_version_skip_config['append_dir'] as $dir) {
if (str_starts_with($file_path, $dir)) {
$last_version_list_append_files[] = $file_path;
continue;
}
}
}
foreach ($last_version_list_append_files as $file_path) {
$now_file_path = $now_dir . '/' . $file_path;
$last_file_path = $last_version_dir . '/' . $file_path;
if (file_exists($now_file_path)) {
continue;
}
$file_content = file_get_contents($last_file_path);
PathTools::intiDir($now_file_path);
file_put_contents($now_file_path, $file_content);
}
// 检测now的composer依赖和最新的composer依赖
$last_composer_json = file_get_contents($last_version_dir . '/composer.json');
$output->writeln($last_composer_json);
$output->writeln('请参考以上最新composer文件调整您的依赖');
// 分析出最新需要的但now没有的
// 为用户整理出要手动调整的composer命令
$this->cleanWorkpaceDir();
$output->writeln('更新完成');
// 更新完成
if (!empty(Version::UPDATE_TIPS)) {
foreach (Version::UPDATE_TIPS as $content) {
$output->writeln($content);
}
$output->writeln('删除对应文件之后,可以通过以下命令重新安装');
$output->writeln('php think admin:update --resinstall');
}
}
protected function cleanWorkpaceDir()
{
$dir = App::getRuntimePath() . '/update/';
$this->output->writeln('清理目录 ' . $dir);
PathTools::removeDir($dir);
}
}

View File

@@ -4,69 +4,8 @@ declare(strict_types=1);
namespace app\common\command\admin;
use think\App as ThinkApp;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use base\common\command\admin\VersionBase;
class Version extends Command
class Version extends VersionBase
{
public const VERSION = 'v2.0.45';
public const LAYUI_VERSION = '2.8.16';
public const COMMENT = [
'实现view的扩展架构',
'调整think-view依赖',
'发布新版本',
];
public const UPDATE_TIPS = [
'本次更新调整了composer依赖请根据实际情况调整',
'可以删除app下admin的view目录了',
'删除 think-view',
'引入 topthink/think-template-view',
];
protected function configure()
{
// 指令配置
$this->setName('admin:version')
->addOption('push-tag', null, Option::VALUE_NONE, '使用git命令生成tag并推送')
->setDescription('查看当前ulthon_admin的版本号');
}
protected function execute(Input $input, Output $output)
{
// 指令输出
$output->info('当前版本号为:' . $this::VERSION);
$output->info('当前Layui版本号为' . $this::LAYUI_VERSION);
$output->info('当前ThinkPHP版本号为' . ThinkApp::VERSION);
$output->writeln('当前的修改说明:');
$output->writeln('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
foreach ($this::COMMENT as $comment) {
$output->info($comment);
}
$output->writeln('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<');
$output->highlight('代码托管地址https://gitee.com/ulthon/ulthon_admin');
$output->highlight('开发文档地址http://doc.ulthon.com/home/read/ulthon_admin/home.html');
$is_push_tag = $input->hasOption('push-tag');
if ($is_push_tag) {
$output->writeln('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
$version = $this::VERSION;
$comment = implode(';', $this::COMMENT);
$output->info('生成标签:' . $version);
$output->info('标签描述:' . $comment);
exec("git tag -a $version -m \"$comment\"");
$output->info('推送到远程仓库');
exec('git push --tags');
}
}
}