feat(update): 新增 --keep-repo 参数,dry-run 模式下保留上游克隆目录便于对比

This commit is contained in:
augushong
2026-05-26 21:38:16 +08:00
parent 58d87d9980
commit 3f8f79b445
3 changed files with 68 additions and 2 deletions

View File

@@ -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/';