Tue, 21 Jan 2025 21:01:54 +0100
add automatic pull/udate of repositories
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/process.cpp | file | annotate | diff | comparison | revisions | |
src/process.h | file | annotate | diff | comparison | revisions |
--- a/src/main.cpp Tue Jan 21 20:24:45 2025 +0100 +++ b/src/main.cpp Tue Jan 21 21:01:54 2025 +0100 @@ -24,6 +24,7 @@ #include "settings.h" #include "repositories.h" +#include "process.h" #include <cstdlib> #include <cstdio> @@ -131,18 +132,49 @@ } int main(int argc, char *argv[]) { + // parse settings fm::settings settings; - if (parse_args(settings, argc, argv)) { return EXIT_FAILURE; } + // check hg and git + fm::process proc; + proc.setbin(settings.hg); + if (proc.exec({"--version"})) { + fprintf(stderr, "Testing hg binary '%s' failed!\n", settings.hg.c_str()); + return EXIT_FAILURE; + } + proc.setbin(settings.git); + if (proc.exec({"--version"})) { + fprintf(stderr, "Testing git binary '%s' failed!\n", settings.git.c_str()); + return EXIT_FAILURE; + } + + // scan for repos fm::repositories repos; for (auto &&path: settings.paths) { repos.scan(path, settings.depth); } - if (!settings.update_repos) { - // TODO: update repositories + + // update repos, if not disabled + if (settings.update_repos) { + for (auto &&repo : repos.list()) { + proc.chdir(repo.path); + if (repo.type == fm::HG) { + proc.setbin(settings.hg); + if (proc.exec({"pull"})) { + fprintf(stderr, "Pulling repo '%s' failed!\nMaybe there is no remote?\n", repo.path.c_str()); + } else if (proc.exec({"update"})) { + fprintf(stderr, "Updating repo '%s' failed!\nMaybe there are local changes?\n", repo.path.c_str()); + } + } else { + proc.setbin(settings.git); + if (proc.exec({"pull"})) { + fprintf(stderr, "Pulling repo '%s' failed!\nMaybe there is no remote or there are local changes?\n", repo.path.c_str()); + } + } + } } // TODO: calculate the heat maps
--- a/src/process.cpp Tue Jan 21 20:24:45 2025 +0100 +++ b/src/process.cpp Tue Jan 21 21:01:54 2025 +0100 @@ -32,16 +32,23 @@ using namespace fm; -process::process(std::string path): m_path(std::move(path)) { +void process::setbin(std::string path) { + m_path = std::move(path); } -bool process::exec(std::vector<std::string> args) { +void process::chdir(std::string path) { + m_dir = std::move(path); +} + +int process::exec(std::vector<std::string> args, bool capture) { + m_output.clear(); + // fd-pair for the pipe int pipefd[2]; if (pipe(pipefd)) { perror("pipe"); - return false; + return -1; } pid_t pid = fork(); @@ -68,34 +75,40 @@ argv[args.size() + 1] = nullptr; // execute the child program + if (::chdir(m_dir.c_str())) { + perror("chdir"); + exit(EXIT_FAILURE); + } if (execv(m_path.c_str(), argv)) { perror("execl"); exit(EXIT_FAILURE); } - return true; // unreachable, but the compiler doesn't know that + return 0; // unreachable, but the compiler doesn't know that } else if (pid > 0) { // close the end of the pipe we don't use close(pipefd[1]); // read all the output - char buf[64]; - ssize_t r; - while ((r = read(pipefd[0], buf, sizeof(buf))) > 0) { - m_output.append(buf, r); + if (capture) { + char buf[64]; + ssize_t r; + while ((r = read(pipefd[0], buf, sizeof(buf))) > 0) { + m_output.append(buf, r); + } + if (r < 0) { + perror("read"); + } + close(pipefd[0]); } - if (r < 0) { - perror("read"); - } - close(pipefd[0]); // wait for the process to completely finish int status = -1; waitpid(pid, &status, 0); - return status == 0; + return status; } else { perror("fork"); - return false; + return -1; } }
--- a/src/process.h Tue Jan 21 20:24:45 2025 +0100 +++ b/src/process.h Tue Jan 21 21:01:54 2025 +0100 @@ -31,13 +31,17 @@ namespace fm { class process final { - std::string m_path; + std::string m_path = "/bin/false"; + std::string m_dir = "."; std::string m_output; public: - explicit process(std::string path); - ~process() = default; + void setbin(std::string path); + void chdir(std::string path); - [[nodiscard]] bool exec(std::vector<std::string> args); + [[nodiscard]] int exec(std::vector<std::string> args, bool capture = false); + [[nodiscard]] int exec_log(std::vector<std::string> args) { + return exec(std::move(args), true); + } [[nodiscard]] const std::string &output() const; };