From 71dbaa1812ed5e48af80764f29db30d5f2734529 Mon Sep 17 00:00:00 2001 From: taynpg Date: Tue, 22 Oct 2024 12:04:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BA=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .clang-format | 17 +++++ .gitignore | 4 + .vscode/settings.json | 40 ++++++++++ CMakeLists.txt | 21 +++++ README.md | 3 + config/msync.xml | 7 ++ main.cpp | 173 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 265 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 config/msync.xml create mode 100644 main.cpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..402f22e --- /dev/null +++ b/.clang-format @@ -0,0 +1,17 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +PointerAlignment: Left +AccessModifierOffset: -4 +BreakBeforeBraces: Custom +BraceWrapping: + AfterFunction: true + AfterClass: true +Cpp11BracedListStyle: true +ReflowComments: true +SpacesBeforeTrailingComments: 3 +TabWidth: 4 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ColumnLimit: 80 +AllowShortBlocksOnASingleLine: Never +AllowShortFunctionsOnASingleLine: None +AllowShortEnumsOnASingleLine: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b861d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +.vs +.cache +cmake-* \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..64a151f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,40 @@ +{ + "files.autoSave": "onFocusChange", + "editor.fontSize": 14, + "editor.fontFamily": "'FiraCode Nerd Font Mono', 'FiraCode Nerd Font Mono', 'FiraCode Nerd Font Mono'", + "cmake.configureOnOpen": true, + "cmake.debugConfig": { + "console": "integratedTerminal", + "setupCommands": [ + { + "description": "-gdb-set charset utf-8", + "text": "-gdb-set charset UTF-8" + }, + { + "description": "Enable gdb pretty-printing", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "args": [ + "SemiWorkCode", "From" + ] + }, + "cmake.environment": { + "PATH": "${env::PATH};D:/library/wxWidgets/lib/vc_x64_dll" + }, + // "cmake.configureSettings": { + // "CMAKE_TOOLCHAIN_FILE": "${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + // }, + "cmake.options.statusBarVisibility": "visible", + "cmake.generator": "Ninja", + "C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json", + "C_Cpp.default.cppStandard": "c++17", + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "editor.inlayHints.enabled": "off", + "editor.unicodeHighlight.allowedLocales": { + "ja": true, + "zh-hant": true, + "zh-hans": true + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4befd0b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.16) + +project(msync LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +list(APPEND CMAKE_PREFIX_PATH "D:/library/wxWidgets/lib/cmake") + +if (MSVC) + add_compile_options(/source-charset:utf-8) +endif() + +find_package(wxWidgets REQUIRED COMPONENTS core base xml) +include(${wxWidgets_USE_FILE}) + +message(STATUS "System: ${CMAKE_SYSTEM_NAME}") +message(STATUS "Compiler CXX ID: ${CMAKE_CXX_COMPILER_ID}") + +add_executable(msync main.cpp) +target_link_libraries(msync PRIVATE ${wxWidgets_LIBRARIES}) +set_target_properties(msync PROPERTIES WIN32_EXECUTABLE FALSE) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1333e48 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# 说明 + +同步一个文件夹。 \ No newline at end of file diff --git a/config/msync.xml b/config/msync.xml new file mode 100644 index 0000000..4b13401 --- /dev/null +++ b/config/msync.xml @@ -0,0 +1,7 @@ + + + + .git + build + + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..4b92064 --- /dev/null +++ b/main.cpp @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +struct Configure { + wxString name; + wxString work_dir; + wxArrayString exclude; +}; + +static wxString work_path; +static wxString cw_work_path; + +bool parse_xml(const wxString& filepath, const wxString& name, + Configure& config) +{ + wxXmlDocument xmlDoc; + if (!xmlDoc.Load(filepath)) { + return false; + } + + wxXmlNode* root = xmlDoc.GetRoot(); + auto c = root->GetChildren(); + if (!c) { + wxLogMessage("解析Xml失败。"); + return false; + } + bool find = false; + while (c) { + if (c->GetName() != "Item") { + c = c->GetNext(); + continue; + } + if (c->GetAttribute("Name") != name) { + c = c->GetNext(); + continue; + } + find = true; + config.name = name; +#ifdef _WIN32 + config.work_dir = c->GetAttribute("WinWorkPath"); +#else + config.work_dir = c->GetAttribute("UnixWorkPath"); +#endif + auto p = c->GetChildren(); + while (p) { + config.exclude.push_back(p->GetNodeContent()); + p = p->GetNext(); + } + break; + } + if (!find) { + wxLogMessage("未找到%s的配置。", name); + return false; + } else { + wxLogMessage("找到%s的配置。", name); + } + return true; +} + +wxString ConvertToCygwinPath(const wxString& path) +{ +#ifdef _WIN32 + // 提取驱动器字母 + wxString drive = path.BeforeFirst('\\').Upper(); + drive.erase(1, 1); + wxString restPath = path.AfterFirst('\\'); + + // 替换为 Cygwin 格式 + wxString cygwinPath = "/cygdrive/" + drive.Lower(); + if (!restPath.empty()) { + cygwinPath.append("/" + restPath); + } + cygwinPath.Replace("\\", "/"); + return cygwinPath; +#else + return path; +#endif +} + +wxString get_cmd(Configure& config, bool to_cur) +{ + wxString cmd_str; + +#if _WIN32 + wxString cmd = work_path + "cwrsync\\bin\\rsync.exe "; + cmd_str.append(cmd); +#else + cmd_str.append("rsync "); + dest_str = work_path + config.name; + source_str = config.work_dir + config.name; +#endif + + cmd_str.append("-av"); + wxString dir_str; + + if (to_cur) { + fs::path path(config.work_dir.ToStdString()); + path.append(config.name.ToStdString()); + dir_str.append(ConvertToCygwinPath(wxString(path.string()))); + dir_str.append(" " + cw_work_path); + } else { + fs::path path(cw_work_path.ToStdString()); + path.append(config.name.ToStdString()); + dir_str.append(wxString(path.string())); + dir_str.append(" " + ConvertToCygwinPath(config.work_dir)); + } + + for (const auto& data : config.exclude) { + cmd_str.append(" --exclude=" + data); + } + cmd_str.append(" "); + cmd_str.append(dir_str); + wxLogMessage(cmd_str); + return cmd_str; +} + +int main(int argc, char* argv[]) +{ + // 确保当前程序能够与所使用的 wxWidgets 库兼容 + wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program"); + wxInitializer initializer; + if (!initializer) { + std::cout << "初始化失败。" << std::endl; + return -2; + } + + if (argc < 3) { + std::cout << "需要传入文件夹名称[XXX]及方向[From/To]。" << std::endl; + return 0; + } + + wxString oper_dir(argv[1]); + wxString direct(argv[2]); + + if (direct != "From" && direct != "To") { + std::cout << "方向不合法,必须是[From/To]。"; + return -3; + } + + // 读取配置文件 msync.xml + const wxStandardPaths& stdpath = wxStandardPaths::Get(); + wxString exe_path = stdpath.GetExecutablePath(); + wxFileName file_name(exe_path); + work_path = file_name.GetPathWithSep(); + cw_work_path = ConvertToCygwinPath(work_path); + wxString config_path = work_path + "msync.xml"; + + Configure config; + if (!parse_xml(config_path, oper_dir, config)) { + return -1; + } + + auto command = get_cmd(config, direct == "From"); + wxArrayString output; + // 使用 wxExecute 执行命令 + long result = wxExecute(command, output, wxEXEC_SYNC); + wxLogMessage("命令执行结果:%d", result); + wxString out_str; + for (const auto& data : output) { + out_str.append(data + "\n"); + } + wxLogMessage("命令输出:%s", out_str); + return 0; +} \ No newline at end of file