完成更新的基本流程

This commit is contained in:
2023-09-20 10:14:17 +08:00
parent 8ed5a40147
commit 03ea326e88
5 changed files with 179 additions and 83 deletions

View File

@@ -41,7 +41,7 @@ class Update extends Command
$version_file_regx = "/\bconst VERSION\s*=\s*'[\d\.a-z]+'/";
$output->writeln('下载最新代码');
$output->writeln('获取最新代码');
$last_version_git = new Git();
$last_version_repo = $last_version_git->cloneRepository(self::REPO, $last_version_dir);
@@ -88,7 +88,7 @@ class Update extends Command
// 获取当前版本要替换的文件
$current_version_filesystem = new Filesystem(new LocalFilesystemAdapter($current_version_dir));
$current_version_list_files = $current_version_filesystem->listContents('', Filesystem::LIST_DEEP)
$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;
@@ -121,6 +121,9 @@ class Update extends Command
$output->writeln('对比源码是否被定制');
$now_dir = App::getRootPath();
/**
* @var array<bool|string>
*/
$changed_files = [];
foreach ($current_version_list_files as $file_path) {
@@ -128,8 +131,10 @@ class Update extends Command
$current_version_file_path = $current_version_dir . '/' . $file_path;
if (!PathTools::compareFiles($now_file_path, $current_version_file_path)) {
$changed_files[] = $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;
}
}
@@ -138,18 +143,77 @@ class Update extends Command
if (!empty($changed_files)) {
$output->warning('无法自动更新,以下文件被定制,请还原或手动升级:');
foreach ($changed_files as $file_path) {
foreach ($changed_files as $file_path => $compare_result) {
$output->warning($file_path);
if (is_string($compare_result)) {
$output->writeln($compare_result);
}
}
return;
$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();
// 删除当前版本要替换的文件
foreach ($current_version_list_files as $file_path) {
$now_file_path = $now_dir . '/' . $file_path;
unlink($now_file_path);
}
// 将最新版本要替换的文件替换到项目代码中
foreach ($last_version_list_files as $file_path) {
$last_file_path = $last_version_dir . '/' . $file_path;
$now_file_path = $now_dir . '/' . $file_path;
PathTools::intiDir($now_file_path);
copy($last_file_path, $now_file_path);
}
// 检测now的composer依赖和最新的composer依赖
// 分析出最新需要的但now没有的
// 为用户整理出要手动调整的composer命令
$output->writeln('更新完成');
// 更新完成
}

View File

@@ -2,7 +2,7 @@
namespace app\common\tools;
use Diff;
use Localheinz\Diff\Differ;
use think\facade\App;
class PathTools
@@ -105,49 +105,58 @@ class PathTools
return str_replace('/', '\\', $content);
}
public static function compareFiles($a, $b)
public static function compareFiles($a, $b, $return_diff = false):bool|string
{
$text_mime_type = [];
$text_mime_type[] = 'text/html';
$text_mime_type[] = 'text/plain';
$text_mime_type[] = 'text/css';
$text_mime_type[] = 'image/svg+xml';
$text_mime_type[] = 'text/x-php';
$text_mime_type[] = 'application/json';
$text_mime_type[] = 'application/x-wine-extension-ini';
if (in_array(mime_content_type($a), $text_mime_type) && in_array(mime_content_type($b), $text_mime_type)) {
// 如果都是文本文件,则执行内容对比
$diff = new Diff(file_get_contents($a), file_get_contents($b));
$diff_content = $diff->getGroupedOpcodes();
if (!empty($diff_content)) {
return false;
} else {
return true;
}
}
$result = true;
// Check if filesize is different
if (filesize($a) !== filesize($b)) {
return false;
$result = false;
}
// Check if content is different
$ah = fopen($a, 'rb');
$bh = fopen($b, 'rb');
if ($result) {
// Check if content is different
$ah = fopen($a, 'rb');
$bh = fopen($b, 'rb');
$result = true;
while (!feof($ah)) {
if (fread($ah, 8192) != fread($bh, 8192)) {
$result = false;
break;
while (!feof($ah)) {
if (fread($ah, 8192) != fread($bh, 8192)) {
$result = false;
break;
}
}
fclose($ah);
fclose($bh);
}
if (!$result) {
// 如果前面的方法认为文件变化,那么以文本变化的方式识别是否变化,并给出变化的内容
$text_mime_type = [];
$text_mime_type[] = 'text/html';
$text_mime_type[] = 'text/plain';
$text_mime_type[] = 'text/css';
$text_mime_type[] = 'image/svg+xml';
$text_mime_type[] = 'text/x-php';
$text_mime_type[] = 'application/json';
$text_mime_type[] = 'application/x-wine-extension-ini';
if (in_array(mime_content_type($a), $text_mime_type) && in_array(mime_content_type($b), $text_mime_type)) {
$a_content = file_get_contents($a);
$b_content = file_get_contents($b);
$diff = new Differ();
$diff_content = $diff->diff($a_content, $b_content);
if (!empty($diff_content)) {
$result = $return_diff ? $diff_content : false;
} else {
$result = true;
}
}
}
fclose($ah);
fclose($bh);
return $result;
}
}