#include "src/pub.h" #include #include #include #include #include #include #include #define CODECREATE_VERSION "1.0.0" enum ProjectType { TYPE_CONSOLE = 0, TYPE_QT_CONSOLE, TYPE_QT_WIDGET }; struct MParam { std::string point_code{}; std::string qt_path{}; std::string exe_dir{}; std::string des_path{}; std::string des_dir{}; std::string name{}; std::string shortkey{}; ProjectType type{TYPE_CONSOLE}; }; MParam gParam; namespace fs = std::filesystem; bool parse_cmd(int argc, char** argv, MParam& param) { std::string intro(""); intro.append(CODECREATE_VERSION); CLI::App app(intro); std::string type; app.add_option("-p,--path", param.des_path, "project position"); app.add_option("-n,--name", param.name, "project name"); app.add_option("-t,--type", type, "0-console,1-qtconsole,2-qtdialog"); app.add_option("-q,--qt", param.qt_path, "qt path, bin dir's parent dir."); app.add_option("-k,--key", param.shortkey, "if not empty, set f5 and alt+g."); try { CLI11_PARSE(app, argc, argv); param.type = static_cast(std::stoi(type)); param.qt_path = CUtil::replace(param.qt_path, "\\", "/"); return true; } catch (const CLI::ParseError& e) { std::cerr << "Error parsing command line: " << e.what() << std::endl; return false; } } bool copy_dir(const std::string& source_dir, const std::string& des_dir, bool add_dir = true) { if (!fs::exists(source_dir) || !fs::exists(des_dir)) { return false; } auto replaceAll = [](const std::string& str, const std::string& from, const std::string& to) { std::string tp(str); if (from.empty()) { return str; } std::size_t start_pos = 0; while ((start_pos = tp.find(from, start_pos)) != std::string::npos) { tp.replace(start_pos, from.length(), to); start_pos += to.length(); } return tp; }; fs::path des_parent_dir; if (add_dir) { des_parent_dir = fs::path(des_dir).append(fs::path(source_dir).filename().string()); if (!fs::exists(des_parent_dir)) { fs::create_directories(des_parent_dir); } } else { des_parent_dir = fs::path(des_dir); } std::list paths{}; for (const auto& entry : fs::directory_iterator(source_dir)) { paths.push_back(entry); } while (!paths.empty()) { fs::path path = paths.front(); paths.pop_front(); fs::path destination(replaceAll(path.string(), source_dir, des_parent_dir.string())); if (fs::is_directory(path)) { if (!fs::exists(destination)) { fs::create_directories(destination); } for (const auto& entry : fs::directory_iterator(path)) { paths.push_back(entry); } continue; } fs::copy_file(path, destination, fs::copy_options::overwrite_existing); } return true; } bool create_base() { if (gParam.name.empty()) { std::cout << fmt::format("project name is empty.") << std::endl; return false; } if (!fs::exists(gParam.des_path)) { std::cout << fmt::format("{} is not exit.", gParam.des_path) << std::endl; return false; } fs::path des_dir(gParam.des_path); gParam.des_dir = des_dir.append(gParam.name).string(); if (fs::exists(des_dir)) { std::cout << fmt::format("{} is already exist.", des_dir.string()) << "\n"; return false; } if (!fs::create_directory(des_dir)) { std::cout << fmt::format("{} create failed.", des_dir.string()) << std::endl; return false; } else { std::cout << fmt::format("{} create success.", des_dir.string()) << std::endl; } fs::path point_code_dir(des_dir); gParam.point_code = point_code_dir.append(".vscode").string(); if (!fs::exists(point_code_dir)) { if (fs::create_directory(point_code_dir)) { std::cout << fmt::format("{} create success.", point_code_dir.string()) << std::endl; } else { std::cout << fmt::format("{} create failed.", point_code_dir.string()) << std::endl; return false; } } fs::path settings_file(point_code_dir); fs::path clang_file(des_dir); settings_file.append("settings.json"); clang_file.append(".clang-format"); fs::path source_settings(gParam.exe_dir); fs::path clang_format(gParam.exe_dir); source_settings.append(".vscode").append("settings.json"); clang_format.append("template").append(".clang-format"); std::cout << fmt::format("source settings is: {}", source_settings.string()) << std::endl; std::cout << fmt::format("clang_format is: {}", clang_format.string()) << std::endl; if (fs::copy_file(source_settings, settings_file)) { std::cout << fmt::format("copy to {} success.", settings_file.string()) << std::endl; } else { std::cout << fmt::format("copy to {} success.", settings_file.string()) << std::endl; } if (fs::copy_file(clang_format, clang_file)) { std::cout << fmt::format("copy to {} success.", clang_format.string()) << std::endl; } else { std::cout << fmt::format("copy to {} success.", clang_format.string()) << std::endl; } return true; } bool copy_console() { fs::path console_path(gParam.exe_dir); console_path.append("template").append("console"); copy_dir(console_path.string(), gParam.des_dir, false); fs::path cmakelist(gParam.des_dir); cmakelist.append("CMakeLists.txt"); std::string str_content; if (!CUtil::read_txt(cmakelist.string(), str_content)) { std::cout << fmt::format("can't open file {}", cmakelist.string()); return false; } std::string rep("replace"); std::string ncontent = CUtil::replace(str_content, rep, gParam.name); if (!CUtil::save_txt(cmakelist.string(), ncontent)) { std::cout << fmt::format("can't write file {}", cmakelist.string()); return false; } return true; } bool copy_qt_widget() { fs::path widget_path(gParam.exe_dir); widget_path.append("template").append("qt-widget"); copy_dir(widget_path.string(), gParam.des_dir, false); fs::path cmakelist(gParam.des_dir); cmakelist.append("CMakeLists.txt"); std::string str_content; if (!CUtil::read_txt(cmakelist.string(), str_content)) { std::cout << fmt::format("can't open file {}", cmakelist.string()); return false; } std::string rep("QT_PATH"); std::string rep2("untitled3"); std::string ncontent = CUtil::replace(str_content, rep, gParam.qt_path); ncontent = CUtil::replace(ncontent, rep2, gParam.name); if (!CUtil::save_txt(cmakelist.string(), ncontent)) { std::cout << fmt::format("can't write file {}", cmakelist.string()); return false; } fs::path settings(gParam.point_code); settings.append("settings.json"); std::string settings_content; if (!CUtil::read_txt(settings.string(), settings_content)) { std::cout << fmt::format("can't open file {}", settings.string()); return false; } std::string from("replace"); std::string to(gParam.qt_path + "/bin"); settings_content = CUtil::replace(settings_content, from, to); if (!CUtil::save_txt(settings.string(), settings_content)) { std::cout << fmt::format("can't write file {}", settings.string()); return false; } return true; } bool copy_qt_console() { fs::path qt_console_path(gParam.exe_dir); qt_console_path.append("template").append("qt-console"); fs::path cmakelist(qt_console_path); fs::path main_file(qt_console_path); cmakelist.append("CMakeLists.txt"); main_file.append("main.cpp"); fs::path save_main(gParam.des_dir); save_main.append("main.cpp"); if (!fs::copy_file(main_file, save_main)) { std::cout << fmt::format("can't copy main file {}", main_file.string()); return false; } std::string str_content; if (!CUtil::read_txt(cmakelist.string(), str_content)) { std::cout << fmt::format("can't open file {}", cmakelist.string()); return false; } std::string rep("QT_PATH"); std::string rep2("PROJECT_NAME"); std::string ncontent = CUtil::replace(str_content, rep, gParam.qt_path); ncontent = CUtil::replace(ncontent, rep2, gParam.name); fs::path save_cmake(gParam.des_dir); save_cmake.append("CMakeLists.txt"); if (!CUtil::save_txt(save_cmake.string(), ncontent)) { std::cout << fmt::format("can't write file {}", save_cmake.string()); return false; } fs::path settings(gParam.point_code); settings.append("settings.json"); std::string settings_content; if (!CUtil::read_txt(settings.string(), settings_content)) { std::cout << fmt::format("can't open file {}", settings.string()); return false; } std::string from("replace"); std::string to(gParam.qt_path + "/bin"); settings_content = CUtil::replace(settings_content, from, to); if (!CUtil::save_txt(settings.string(), settings_content)) { std::cout << fmt::format("can't write file {}", settings.string()); return false; } return true; } bool set_key() { std::string shortkey_file = CUtil::get_keybindings_file(); return true; } bool handle_gdb_qtprinter() { #if _MSC_VER fs::path template_dir(gParam.exe_dir); template_dir.append("template"); fs::path qt5_file(template_dir); fs::path qt6_file(template_dir); qt5_file.append("qt5.natvis"); qt6_file.append("qt6.natvis"); fs::path des_qt5_file(gParam.point_code); fs::path des_qt6_file(gParam.point_code); des_qt5_file.append("qt5.natvis"); des_qt6_file.append("qt6.natvis"); if (fs::copy_file(qt5_file, des_qt5_file)) { std::cout << fmt::format("copy to {} success.", des_qt5_file.string()) << std::endl; } else { std::cout << fmt::format("copy to {} success.", des_qt5_file.string()) << std::endl; } if (fs::copy_file(qt6_file, des_qt6_file)) { std::cout << fmt::format("copy to {} success.", des_qt6_file.string()) << std::endl; } else { std::cout << fmt::format("copy to {} success.", des_qt6_file.string()) << std::endl; } #endif std::string home = CUtil::get_home(); if (home.empty()) { std::cout << "can't get home dir.\n"; return false; } fs::path gdb_des(home); gdb_des.append(".gdbinit"); fs::path gdb_source(gParam.exe_dir); gdb_source.append("template").append("qt-printer").append(".gdbinit"); if (!fs::exists(gdb_des)) { if (fs::copy_file(gdb_source, gdb_des)) { std::cout << fmt::format("copy to {} success.", gdb_des.string()) << std::endl; } else { std::cout << fmt::format("copy to {} success.", gdb_des.string()) << std::endl; } } fs::path gdb_path(home); fs::path gdb_source_path(gParam.exe_dir); gdb_path.append(".gdb"); gdb_source_path.append("template").append("qt-printer").append("QtPrinters"); if (fs::exists(gdb_path)) { return true; } fs::create_directory(gdb_path); copy_dir(gdb_source_path.string(), gdb_path.string(), true); return true; } int main(int argc, char** argv) { std::cout << "\n"; if (!parse_cmd(argc, argv, gParam)) { return -1; } #if _DEBUG std::cout << "Debug Mode." << std::endl; fs::path exe_path(CUtil::get_exe_path()); gParam.exe_dir = exe_path.parent_path().parent_path().string(); std::cout << fmt::format("current_path is: {}", gParam.exe_dir) << "\n"; #else std::cout << "Release Mode." << std::endl; fs::path exe_path(CUtil::get_exe_path()); gParam.exe_dir = exe_path.parent_path().string(); std::cout << fmt::format("current_path is: {}", gParam.exe_dir) << "\n"; #endif // if (!gParam.shortkey.empty()) { // set_key(); // return 0; // } switch (gParam.type) { case TYPE_CONSOLE: { if (!create_base()) { return -1; } copy_console(); break; } case TYPE_QT_CONSOLE: { if (gParam.qt_path.empty()) { std::cout << "qt path is empty.\n"; break; } if (!create_base()) { return -1; } copy_qt_console(); handle_gdb_qtprinter(); break; } case TYPE_QT_WIDGET: { if (gParam.qt_path.empty()) { std::cout << "qt path is empty.\n"; break; } if (!create_base()) { return -1; } copy_qt_widget(); handle_gdb_qtprinter(); break; } default: std::cout << fmt::format("{} is not support.", static_cast(gParam.type)) << "\n"; break; } return 0; }