修正使用绝对路径时的问题
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
#include <vector>
|
||||
#include <zoost/zoost.h>
|
||||
|
||||
#include "SimMd5.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@@ -33,27 +35,30 @@ struct FileMapping {
|
||||
|
||||
// 操作记录结构
|
||||
struct OperationRecord {
|
||||
fs::path source; // 源文件绝对路径
|
||||
fs::path target; // 目标文件绝对路径
|
||||
fs::path backup; // 备份路径
|
||||
bool exists; // 目标文件是否存在
|
||||
bool isNew; // 是否是新增文件
|
||||
std::string backupRelative; // 相对备份路径
|
||||
fs::path source; // 源文件绝对路径
|
||||
fs::path target; // 目标文件绝对路径
|
||||
fs::path backup; // 备份路径
|
||||
bool exists; // 目标文件是否存在
|
||||
bool isNew; // 是否是新增文件
|
||||
};
|
||||
|
||||
class AutoUpdateTool
|
||||
{
|
||||
private:
|
||||
std::string configFile;
|
||||
fs::path workDir; // 工作目录(新文件所在)
|
||||
fs::path updateDir; // 更新目录(目标目录)
|
||||
fs::path backupDir; // 备份目录
|
||||
std::string fromType; // 源类型:"m" 或 "n"
|
||||
std::string toType; // 目标类型:"m" 或 "n"
|
||||
fs::path workDir; // 工作目录(新文件所在)
|
||||
fs::path updateDir{"."}; // 更新目录(目标目录)
|
||||
fs::path backupDir; // 备份目录
|
||||
std::string fromType; // 源类型:"m" 或 "n"
|
||||
std::string toType; // 目标类型:"m" 或 "n"
|
||||
std::vector<FileMapping> mappings;
|
||||
std::shared_ptr<spdlog::logger> logger;
|
||||
std::string markerDir; // 标记目录名
|
||||
std::string logPath_;
|
||||
std::string logName_{"fileUpdater.log"};
|
||||
bool verify_{true};
|
||||
SimpleMD5 md5_;
|
||||
|
||||
public:
|
||||
AutoUpdateTool()
|
||||
@@ -94,7 +99,7 @@ public:
|
||||
|
||||
app.add_option("-w,--work-dir", workDir, "工作目录(新文件所在)")->default_val(fs::current_path());
|
||||
|
||||
app.add_option("-u,--update-dir", updateDir, "更新目录(目标目录)")->required();
|
||||
app.add_option("-u,--update-dir", updateDir, "更新目录(目标目录)");
|
||||
|
||||
app.add_option("-b,--backup-dir", backupDir, "备份目录")->required();
|
||||
|
||||
@@ -102,6 +107,8 @@ public:
|
||||
|
||||
app.add_option("-t,--to", toType, "目标类型 (m 或 n)")->required()->check(CLI::IsMember({"m", "n"}));
|
||||
|
||||
app.add_flag("-v,--verify", verify_, "是否进行备份校验(默认是)。");
|
||||
|
||||
try {
|
||||
app.parse(argc, argv);
|
||||
|
||||
@@ -223,6 +230,8 @@ public:
|
||||
for (const auto& mapping : mappings) {
|
||||
// 确定源路径和目标路径
|
||||
std::string fromPath, toPath;
|
||||
std::string backupRelativePath;
|
||||
|
||||
if (fromType == "m") {
|
||||
fromPath = mapping.m;
|
||||
} else {
|
||||
@@ -235,9 +244,20 @@ public:
|
||||
toPath = mapping.n;
|
||||
}
|
||||
|
||||
// 构建绝对路径
|
||||
fs::path sourceAbs = workDir / fromPath;
|
||||
fs::path targetAbs = updateDir / toPath;
|
||||
fs::path sourceAbs;
|
||||
fs::path targetAbs;
|
||||
|
||||
if (fs::path(fromPath).is_absolute()) {
|
||||
sourceAbs = fs::path(fromPath);
|
||||
} else {
|
||||
sourceAbs = workDir / fromPath;
|
||||
backupRelativePath = fromPath;
|
||||
}
|
||||
if (fs::path(toPath).is_absolute()) {
|
||||
targetAbs = fs::path(toPath);
|
||||
} else {
|
||||
targetAbs = updateDir / toPath;
|
||||
}
|
||||
|
||||
// 步骤1:检查源路径是否存在
|
||||
if (!checkPath(sourceAbs, mapping.isFile)) {
|
||||
@@ -262,6 +282,7 @@ public:
|
||||
record.target = targetAbs;
|
||||
record.exists = fs::exists(targetAbs);
|
||||
record.isNew = !record.exists;
|
||||
record.backupRelative = backupRelativePath;
|
||||
|
||||
if (mapping.isFile) {
|
||||
// 文件处理
|
||||
@@ -288,6 +309,7 @@ public:
|
||||
dirRecord.target = targetAbs / relPath;
|
||||
dirRecord.exists = fs::exists(dirRecord.target);
|
||||
dirRecord.isNew = !dirRecord.exists;
|
||||
dirRecord.backupRelative = backupRelativePath;
|
||||
records.push_back(dirRecord);
|
||||
}
|
||||
}
|
||||
@@ -327,9 +349,10 @@ public:
|
||||
// 获取用户输入的标记目录
|
||||
bool getMarkerDirectory()
|
||||
{
|
||||
std::cout << "\n请输入标记目录名称(留空使用时间戳): ";
|
||||
std::cout << "\n请输入此次备份标记名称(留空使用时间戳): ";
|
||||
std::getline(boost::nowide::cin, markerDir);
|
||||
|
||||
boost::trim(markerDir);
|
||||
if (markerDir.empty()) {
|
||||
markerDir = getCurrentTimestamp();
|
||||
}
|
||||
@@ -350,8 +373,8 @@ public:
|
||||
{
|
||||
try {
|
||||
// 计算相对更新目录的路径
|
||||
fs::path relPath = fs::relative(record.target, updateDir);
|
||||
fs::path backupPath = backupDir / markerDir / relPath;
|
||||
// fs::path relPath = fs::relative(record.target, updateDir);
|
||||
fs::path backupPath = backupDir / markerDir / record.backupRelative;
|
||||
|
||||
// 创建目标目录
|
||||
fs::create_directories(backupPath.parent_path());
|
||||
@@ -360,8 +383,30 @@ public:
|
||||
fs::copy(record.target, backupPath, fs::copy_options::overwrite_existing);
|
||||
|
||||
logger->debug("已备份: {} -> {}", record.target.string(), backupPath.string());
|
||||
|
||||
if (!verify_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 校验MD5
|
||||
auto hashSrc = md5_.hash_file(record.target.string());
|
||||
std::string hashBk;
|
||||
|
||||
if (fs::is_directory(backupPath)) {
|
||||
hashBk = md5_.hash_file(fs::path(backupPath).append(fs::path(record.target).filename().string()).string());
|
||||
} else {
|
||||
hashBk = md5_.hash_file(backupPath.string());
|
||||
}
|
||||
|
||||
if (hashBk == hashSrc) {
|
||||
logger->info("==> Hash验证已通过。[{}]", hashSrc);
|
||||
} else {
|
||||
logger->error("==> Hash验证未通过。[{}][{}]", hashSrc, hashBk);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
// logger->error("备份失败: {} - {}", record.target.string(), zoostCommon::ToU8Copy(e.what()));
|
||||
logger->error("备份失败: {} - {}", record.target.string(), e.what());
|
||||
return false;
|
||||
}
|
||||
@@ -403,7 +448,8 @@ public:
|
||||
if (backupFile(record)) {
|
||||
backupCount++;
|
||||
} else {
|
||||
logger->warn("备份失败,但继续执行更新");
|
||||
logger->warn("备份失败...,请检查,停止更新动作...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user