Files
ulthon_admin/extend/base/common/command/admin/VersionBase.php

286 lines
9.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace base\common\command\admin;
use app\common\tools\PathTools;
use think\App as ThinkApp;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
class VersionBase extends Command
{
public const VERSION = 'v2.0.116';
public const PRODUCT_VERSION = '';
public const LAYUI_VERSION = 'v2.10.1';
public const COMMENT = [
'版本更新说明:',
'【新功能】',
'- 升级权限管理模式',
];
protected const COMMIT_TYPES = [
'feat' => '新功能',
'fix' => '修复',
'docs' => '文档',
'style' => '样式',
'refactor' => '重构',
'perf' => '性能优化',
'test' => '测试',
'build' => '构建',
'ci' => '持续集成',
'chore' => '其他',
'revert' => '回退',
];
protected function configure()
{
// 指令配置
$this->setName('admin:version')
->addOption('generate-comment', null, Option::VALUE_NONE, '使用git命令生成说明文件')
->addOption('generate-release', null, Option::VALUE_NONE, '使用git命令生成发布说明文件')
->addOption('release-from-tag', null, Option::VALUE_OPTIONAL, '从指定版本开始生成说明文件')
->addOption('push-tag', null, Option::VALUE_NONE, '使用git命令生成tag并推送')
->setDescription('查看当前ulthon_admin的版本号');
}
protected function execute(Input $input, Output $output)
{
// 指令输出
if (!empty(static::PRODUCT_VERSION)) {
$output->info('当前版本号为:' . static::PRODUCT_VERSION);
}
$output->info('当前ulthon_admin版本号为' . static::VERSION);
$output->info('当前Layui版本号为' . static::LAYUI_VERSION);
$output->info('当前ThinkPHP版本号为' . ThinkApp::VERSION);
$output->writeln('当前的修改说明:');
$output->writeln('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
foreach (static::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) {
$this->pushTag();
}
$is_generate_comment = $input->hasOption('generate-comment');
if ($is_generate_comment) {
$this->generateComment();
}
$is_generate_release = $input->hasOption('generate-release');
if ($is_generate_release) {
$fromTag = $input->getOption('release-from-tag');
$this->generateRelease($fromTag);
}
}
protected function pushTag()
{
$input = $this->input;
$output = $this->output;
$output->writeln('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
$version = static::VERSION;
if (!empty(static::PRODUCT_VERSION)) {
$version = static::PRODUCT_VERSION;
}
// 将提交信息写入临时文件
$comment = implode("\n", static::COMMENT);
$output->info('生成标签:' . $version);
$output->info('标签描述:' . $comment);
// 使用项目的临时文件路径生成方法
$tempFile = PathTools::tempBuildPath('git_tag_message_' . uniqid() . '.txt');
file_put_contents($tempFile, $comment);
// 使用 -F 参数从文件读取提交信息
exec("git tag -a $version -F \"$tempFile\"");
// 删除临时文件
if (file_exists($tempFile)) {
unlink($tempFile);
}
$output->info('推送到远程仓库');
exec('git push --tags');
}
/**
* 生成版本更新说明
* 读取自上次tag到现在所有的提交说明.
* @return string
*/
public function generateComment()
{
$this->output->writeln('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
// 获取最新的tag
$lastTag = shell_exec('git describe --tags --abbrev=0');
$lastTag = trim($lastTag);
// 获取从最新tag到现在的所有提交
$commits = shell_exec("git log {$lastTag}..HEAD --pretty=format:\"%s\"");
if (empty($commits)) {
return '暂无更新说明';
}
$commits = explode("\n", $commits);
// 按类型分组提交
$groupedCommits = [];
foreach ($commits as $commit) {
$matched = false;
foreach (static::COMMIT_TYPES as $type => $desc) {
if (preg_match("/^{$type}:/i", $commit)) {
$message = preg_replace("/^{$type}:/i", '', $commit);
$groupedCommits[$desc][] = trim($message);
$matched = true;
break;
}
}
// 如果没有匹配到任何类型,归类为"其他"
if (!$matched) {
$groupedCommits['其他'][] = trim($commit);
}
}
// 生成更新说明
$comment = "版本更新说明:\n";
foreach ($groupedCommits as $type => $messages) {
$comment .= "\n{$type}\n";
foreach ($messages as $message) {
$comment .= "- {$message}\n";
}
}
$this->output->writeln($comment);
// 生成数组格式文件
$comment_arr = explode("\n", $comment);
$comment_arr = array_filter($comment_arr, function ($item) {
return !empty($item);
});
$comment_arr = array_map(function ($item) {
return "'" . addslashes(trim($item)) . "',";
}, $comment_arr);
$comment_arr_code = implode("\n", $comment_arr);
$tmp_comment_file = PathTools::tempBuildPath('commit_comment.php');
file_put_contents($tmp_comment_file, "<?php\nreturn [\n" . $comment_arr_code . "\n];");
$this->output->info('已生成版本更新代码:' . $tmp_comment_file);
$tmp_comment_markdown_file = PathTools::tempBuildPath('commit_comment.md');
file_put_contents($tmp_comment_markdown_file, $comment);
$this->output->info('已生成版本更新Markdown' . $tmp_comment_markdown_file);
}
/**
* 生成发布说明文件
* 从指定版本开始生成发布说明.
* @param string|null $fromTag 起始版本号如果为空则使用最近的tag
* @return void
*/
public function generateRelease($fromTag = null)
{
$output = $this->output;
// 如果没有指定起始版本则获取最近的tag
if (empty($fromTag)) {
$fromTag = shell_exec('git describe --tags --abbrev=0');
$fromTag = trim($fromTag);
$output->info('未指定起始版本使用最近的tag: ' . $fromTag);
} else {
$output->info('从指定版本开始生成发布说明: ' . $fromTag);
}
// 获取当前版本
$currentVersion = static::VERSION;
if (!empty(static::PRODUCT_VERSION)) {
$currentVersion = static::PRODUCT_VERSION;
}
// 获取从指定tag到现在的所有提交包含提交哈希和提交日期
$commits = shell_exec("git log {$fromTag}..HEAD --pretty=format:\"%h %ad %s\" --date=short");
if (empty($commits)) {
$output->warning('从 ' . $fromTag . ' 到现在没有任何提交');
return;
}
$commits = explode("\n", $commits);
// 按类型分组提交
$groupedCommits = [];
foreach ($commits as $commit) {
$matched = false;
// 提取提交哈希和日期
preg_match('/^([a-f0-9]+)\s(\d{4}-\d{2}-\d{2})\s(.+)$/', $commit, $matches);
if (count($matches) >= 4) {
$hash = $matches[1];
$date = $matches[2];
$message = $matches[3];
foreach (static::COMMIT_TYPES as $type => $desc) {
if (preg_match("/^{$type}:/i", $message)) {
$cleanMessage = preg_replace("/^{$type}:/i", '', $message);
$groupedCommits[$desc][] = [
'message' => trim($cleanMessage),
'hash' => $hash,
'date' => $date,
];
$matched = true;
break;
}
}
// 如果没有匹配到任何类型,归类为"其他"
if (!$matched) {
$groupedCommits['其他'][] = [
'message' => trim($message),
'hash' => $hash,
'date' => $date,
];
}
}
}
// 生成发布说明
$releaseTitle = "# {$currentVersion} 发布说明\n\n";
$releaseDate = '发布日期: ' . date('Y-m-d') . "\n\n";
$releaseContent = "本次发布包含了从 {$fromTag}{$currentVersion} 的所有更新。\n\n";
foreach ($groupedCommits as $type => $messages) {
$releaseContent .= "## {$type}\n\n";
foreach ($messages as $item) {
$releaseContent .= "- [{$item['date']}] {$item['message']} (#{$item['hash']})\n";
}
$releaseContent .= "\n";
}
$release = $releaseTitle . $releaseDate . $releaseContent;
// 生成发布说明文件
$releaseFile = PathTools::tempBuildPath("release_{$currentVersion}.md");
file_put_contents($releaseFile, $release);
$output->info('已生成发布说明文件: ' . $releaseFile);
}
}