This commit is contained in:
taynpg 2024-10-22 12:04:57 +08:00
commit 71dbaa1812
7 changed files with 265 additions and 0 deletions

17
.clang-format Normal file
View File

@ -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

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build
.vs
.cache
cmake-*

40
.vscode/settings.json vendored Normal file
View File

@ -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
}
}

21
CMakeLists.txt Normal file
View File

@ -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)

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# 说明
同步一个文件夹。

7
config/msync.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Item Name="SemiWorkCode" WinWorkPath="D:/work" UnixWorkPath="/home/lebo/mwork">
<Exclude>.git</Exclude>
<Exclude>build</Exclude>
</Item>
</Root>

173
main.cpp Normal file
View File

@ -0,0 +1,173 @@
#include <filesystem>
#include <iostream>
#include <wx/app.h>
#include <wx/arrstr.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
#include <wx/utils.h>
#include <wx/xml/xml.h>
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;
}