mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 15:32:48 +08:00
feat(update): 新增 --keep-repo 参数,dry-run 模式下保留上游克隆目录便于对比
This commit is contained in:
@@ -98,6 +98,29 @@ php think admin:update --dry-run
|
||||
|
||||
向开发者报告以上信息,由开发者决定是否继续。
|
||||
|
||||
### 4.5 跳过文件处理
|
||||
|
||||
当 dry-run 输出中存在 `[skipped]` 标记的文件时,说明这些冲突文件被跳过了。此时建议重新执行 dry-run 并加 `--keep-repo`,保留上游克隆目录用于对比:
|
||||
|
||||
```bash
|
||||
php think admin:update --dry-run --optional-conflict=skip --force-conflict=overwrite --keep-repo
|
||||
```
|
||||
|
||||
命令结束后,以下目录会被保留:
|
||||
|
||||
| 目录 | 内容 |
|
||||
|------|------|
|
||||
| `runtime/update/current/` | 当前安装版本的原始代码 |
|
||||
| `runtime/update/repo/` | 上游最新版本的代码 |
|
||||
| 项目根目录 | 开发者实际修改的代码 |
|
||||
|
||||
**对比方式**:逐个读取三个版本的跳过文件,辅助开发者判断是否需要合入上游改动。关注点:
|
||||
- 上游改了什么(对比 `current/` vs `repo/`)
|
||||
- 开发者改了什么(对比 `current/` vs 项目根目录)
|
||||
- 两者是否冲突
|
||||
|
||||
**清理方式**:下次运行 `admin:update` 时会自动清理 `runtime/update/` 目录,或手动删除。
|
||||
|
||||
## 5. 参数参考
|
||||
|
||||
| 参数 | 可选值 | 说明 |
|
||||
@@ -106,6 +129,7 @@ php think admin:update --dry-run
|
||||
| `--optional-conflict` | `skip` / `overwrite` / `ask` | 可选文件(app/config/route/extend/think/根目录文件)的冲突处理策略 |
|
||||
| `--force-conflict` | `overwrite` / `skip` / `ask` | 强制文件(extend/base/public/database/think)的冲突处理策略 |
|
||||
| `--show` | `all` / `conflict` | 变更输出范围:all 显示全部文件,conflict 只显示冲突文件 |
|
||||
| `--keep-repo` | (无值) | 预览模式下保留上游克隆目录(runtime/update/current/ 和 runtime/update/repo/),便于手动对比跳过的冲突文件 |
|
||||
| `--reinstall` | (无值) | 即使当前版本已是最新,也强制重新安装代码 |
|
||||
| `--update-master` | (无值) | 更新到 master 分支而非最新 tag |
|
||||
|
||||
@@ -143,6 +167,7 @@ php think admin:update --optional-conflict=skip --force-conflict=skip --show=all
|
||||
|
||||
- **永远不要使用 `ask` 模式**。agent 无法处理交互式确认提示(`$output->confirm()`),会导致命令挂起
|
||||
- **不要省略冲突策略参数**。不传参数时,如果存在冲突文件,命令会回退到交互模式,同样会挂起
|
||||
- **`--keep-repo` 仅在预览模式下有效**:正式执行时自动忽略,不会保留目录
|
||||
|
||||
## 7. 冲突处理指引
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class AdminUpdateServiceBase
|
||||
public $optionalConflict = null; // null=未指定(走交互), skip|overwrite|ask
|
||||
public $forceConflict = null; // null=未指定(走交互), overwrite|skip|ask
|
||||
public $showScope = null; // null=未指定(默认all), all|conflict
|
||||
public $keepRepo = false; // dry-run模式下保留上游克隆目录
|
||||
public $skippedConflictFiles = []; // [file_path => ['type' => 'add|delete|update', 'category' => 'optional|force']]
|
||||
|
||||
/**
|
||||
@@ -351,7 +352,14 @@ class AdminUpdateServiceBase
|
||||
|
||||
if (empty($need_process_files)) {
|
||||
$output->writeln('没有需要更新的文件');
|
||||
$this->cleanWorkpaceDir();
|
||||
|
||||
// 即使没有需要处理的文件,如果有跳过的冲突文件且keepRepo,保留目录并输出摘要
|
||||
if ($this->dryRun && $this->keepRepo && !empty($this->skippedConflictFiles)) {
|
||||
$this->outputSkippedFilesSummary($this->skippedConflictFiles, $output);
|
||||
$this->outputKeepRepoPaths($current_version_dir, $last_version_dir, $now_dir, $output);
|
||||
} else {
|
||||
$this->cleanWorkpaceDir();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -470,6 +478,11 @@ class AdminUpdateServiceBase
|
||||
$output->writeln("风险评估: 强制冲突 {$force_conflict_count}个(高风险) | 可选冲突 {$optional_conflict_count}个(中风险) | 无冲突变更 {$no_conflict_count}个(低风险)");
|
||||
}
|
||||
|
||||
// 跳过文件汇总输出(独立于 --show 参数和 need_process_files)
|
||||
if ($this->dryRun && !empty($this->skippedConflictFiles)) {
|
||||
$this->outputSkippedFilesSummary($this->skippedConflictFiles, $output);
|
||||
}
|
||||
|
||||
// 非 dry-run 模式:仅在显式传了 --show 时输出变更摘要
|
||||
if (!$this->dryRun && $this->showScope !== null && !empty($need_process_files)) {
|
||||
$showScope = $this->showScope ?: 'all';
|
||||
@@ -530,7 +543,11 @@ class AdminUpdateServiceBase
|
||||
}
|
||||
}
|
||||
|
||||
$this->cleanWorkpaceDir();
|
||||
if ($this->dryRun && $this->keepRepo) {
|
||||
$this->outputKeepRepoPaths($current_version_dir, $last_version_dir, $now_dir, $output);
|
||||
} else {
|
||||
$this->cleanWorkpaceDir();
|
||||
}
|
||||
}
|
||||
|
||||
protected function showPostUpdateGuidance(array $need_process_files, Output $output): void
|
||||
@@ -641,6 +658,28 @@ class AdminUpdateServiceBase
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function outputSkippedFilesSummary(array $skippedFiles, Output $output): void
|
||||
{
|
||||
$output->writeln('');
|
||||
$output->writeln('跳过的冲突文件(' . count($skippedFiles) . '个):');
|
||||
foreach ($skippedFiles as $file_path => $info) {
|
||||
$category = $info['category'];
|
||||
$output->writeln(' ' . $file_path . ' [' . $category . ']');
|
||||
$output->writeln(' 对比: diff runtime/update/current/' . $file_path . ' runtime/update/repo/' . $file_path);
|
||||
$output->writeln(' 开发者版本: ' . $file_path);
|
||||
}
|
||||
}
|
||||
|
||||
protected function outputKeepRepoPaths(string $currentDir, string $repoDir, string $nowDir, Output $output): void
|
||||
{
|
||||
$output->writeln('');
|
||||
$output->writeln('已保留更新目录(预览模式 --keep-repo):');
|
||||
$output->writeln(' 当前版本原始代码: ' . $currentDir);
|
||||
$output->writeln(' 上游最新代码: ' . $repoDir);
|
||||
$output->writeln(' 开发者代码: ' . $nowDir);
|
||||
$output->writeln(' 目录将在下次更新时自动清理,或手动删除 runtime/update/');
|
||||
}
|
||||
|
||||
protected function cleanWorkpaceDir()
|
||||
{
|
||||
$dir = App::getRuntimePath() . '/update/';
|
||||
|
||||
@@ -28,6 +28,7 @@ class UpdateBase extends Command
|
||||
->addOption('optional-conflict', null, Option::VALUE_OPTIONAL, '可选文件冲突处理策略: skip|overwrite|ask')
|
||||
->addOption('force-conflict', null, Option::VALUE_OPTIONAL, '强制文件冲突处理策略: overwrite|skip|ask')
|
||||
->addOption('show', null, Option::VALUE_OPTIONAL, '变更输出范围: all|conflict')
|
||||
->addOption('keep-repo', null, Option::VALUE_NONE, '预览模式下保留上游克隆目录,便于手动对比跳过的文件')
|
||||
->setDescription('更新系统代码');
|
||||
}
|
||||
|
||||
@@ -49,6 +50,7 @@ class UpdateBase extends Command
|
||||
$update_service->optionalConflict = $input->getOption('optional-conflict') ?: null;
|
||||
$update_service->forceConflict = $input->getOption('force-conflict') ?: null;
|
||||
$update_service->showScope = $input->getOption('show') ?: null;
|
||||
$update_service->keepRepo = (bool)$input->getOption('keep-repo');
|
||||
|
||||
$update_service->update();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user