codecreate/main.cpp

438 lines
13 KiB
C++

#include "src/pub.h"
#include <CLI11.hpp>
#include <filesystem>
#include <fmt/format.h>
#include <fstream>
#include <iostream>
#include <list>
#include <string>
#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<ProjectType>(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<fs::path> 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<int>(gParam.type)) << "\n";
break;
}
return 0;
}