diff --git a/.github/workflows/multi-platform.yml b/.github/workflows/multi-platform.yml index f713975..a1bf5b2 100644 --- a/.github/workflows/multi-platform.yml +++ b/.github/workflows/multi-platform.yml @@ -35,6 +35,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Build the mod uses: geode-sdk/build-geode-mod@main diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1e49aea --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/reproc"] + path = external/reproc + url = https://github.com/DaanDeMeyer/reproc.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 24077eb..ace8359 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ file(GLOB_RECURSE SOURCES src/*.cpp src/*/*.cpp) # Set up the mod binary add_library(${PROJECT_NAME} SHARED ${SOURCES}) +set(REPROC++ ON) +add_subdirectory(external/reproc) +target_link_libraries(${PROJECT_NAME} reproc++) + if (NOT DEFINED ENV{GEODE_SDK}) message(FATAL_ERROR "Unable to find Geode SDK! Please define GEODE_SDK environment variable to point to Geode") else() diff --git a/external/reproc b/external/reproc new file mode 160000 index 0000000..3179928 --- /dev/null +++ b/external/reproc @@ -0,0 +1 @@ +Subproject commit 3179928ae7b085e41dfb846d987519fa7c12ffb3 diff --git a/src/wakatime/cli.cpp b/src/wakatime/cli.cpp index 9e7f979..7fc8eea 100644 --- a/src/wakatime/cli.cpp +++ b/src/wakatime/cli.cpp @@ -10,6 +10,7 @@ #include "../utils/which.hpp" #include "cli.hpp" #include "wakatime.hpp" +#include "reproc++/run.hpp" #ifdef GEODE_IS_WINDOWS #define POPEN _popen @@ -96,24 +97,29 @@ namespace cli { std::string getCurrentVersion() { if (!isInstalled()) return ""; - std::filesystem::path path = getPath(); - - std::string command = fmt::format("{} --version", utils::quote(path.string())); + std::vector args = { getPath().string(), "--version" }; + + std::string result, stderr_output; - std::string result; - char buffer[128]; + reproc::options options; + options.redirect.parent = false; - FILE* pipe = POPEN(command.c_str(), "r"); - if (!pipe) { - geode::log::error("Unable to fetch wakatime-cli version"); + auto [status, ec] = reproc::run(args, options, reproc::sink::string(result), reproc::sink::string(stderr_output)); + + if (ec) { + geode::log::error("WakaTime CLI exited with error code: {}", ec.message()); return ""; } - while (!feof(pipe)) { - if (fgets(buffer, sizeof(buffer), pipe) != nullptr) result += buffer; + if (status != 0) { + geode::log::error("WakaTime CLI exited with status: {}", status); + return ""; } - PCLOSE(pipe); + if (!stderr_output.empty()) { + geode::log::error("WakaTime CLI stderr: {}", stderr_output); + return ""; + } result.erase(0, result.find_first_not_of(" \n\r\t")); result.erase(result.find_last_not_of(" \n\r\t") + 1); @@ -258,29 +264,25 @@ namespace cli { } bool execute(const std::filesystem::path& path, const std::vector& args) { - std::string command = utils::quote(path.string()); - - for (const auto& arg : args) { - command += " " + arg; - } + std::vector command; + command.push_back(path.string()); + command.insert(command.end(), args.begin(), args.end()); geode::log::debug("Executing WakaTime CLI command: {}", command); std::thread([command]() { - std::string fullCommand = utils::quote(command); - #ifdef GEODE_IS_WINDOWS - fullCommand += " >nul 2>&1"; - #else - fullCommand += " >/dev/null 2>&1"; - #endif - - FILE* pipe = POPEN(fullCommand.c_str(), "r"); - if (pipe) { - int result = PCLOSE(pipe); - if (result != 0) geode::log::error("WakaTime CLI command failed with exit code: {}", result); - } else { - geode::log::error("WakaTime CLI command failed to start"); - } + reproc::options options; + options.redirect.parent = false; + + std::string stdout_output, stderr_output; + + auto [status, ec] = reproc::run(command, options, reproc::sink::string(stdout_output), reproc::sink::string(stderr_output)); + + if (ec) geode::log::error("WakaTime CLI exited with error code: {}", ec.message()); + + if (!stderr_output.empty()) geode::log::error("WakaTime CLI command stderr: {}", stderr_output); + + if (status != 0) geode::log::error("WakaTime CLI exited with status: {}", status); }).detach(); return true; diff --git a/src/wakatime/tracker.cpp b/src/wakatime/tracker.cpp index 156cc6b..f385178 100644 --- a/src/wakatime/tracker.cpp +++ b/src/wakatime/tracker.cpp @@ -38,6 +38,7 @@ namespace tracker { active = true; activityStarted = std::chrono::system_clock::now(); geode::log::debug("New activity: {} {}", getCategory(), project); + onActivityChange(); // send heartbeat } void ActivityTracker::checkActivity() {