diff --git a/.vimrc_proj b/.vimrc_proj index 8a543ad..2b745b4 100644 --- a/.vimrc_proj +++ b/.vimrc_proj @@ -1 +1 @@ -set makeprg=meson\ compile\ -C \builddir +set makeprg=meson\ compile\ -C\ . diff --git a/meson.build b/meson.build index 221a5a7..25dbab8 100644 --- a/meson.build +++ b/meson.build @@ -24,3 +24,6 @@ dependencies = [ executable('watchgit', 'watchgit.cpp', dependencies: dependencies) + +executable('regtest', 'regtest.cpp', + dependencies: [fmt]) diff --git a/regtest.cpp b/regtest.cpp new file mode 100644 index 0000000..52dac98 --- /dev/null +++ b/regtest.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +using namespace fmt; +using namespace std; + +int main(int argc, char *argv[]) { + smatch matches; + regex to_test(argv[1]); + string line(argv[2]); + + if(argc != 3) { + println("USAGE: regtest "); + } else { + if(regex_match(line, matches, to_test)) { + println("MATCHED: "); + + for(auto &match : matches) { + println("\t{}", match.str()); + } + } else { + println("NO MATCH"); + } + } +} diff --git a/watchgit.cpp b/watchgit.cpp index 020a180..1916240 100644 --- a/watchgit.cpp +++ b/watchgit.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace std; using namespace fmt; @@ -43,32 +44,51 @@ const char *unfuck_path(const git_status_entry *entry) { return nullptr; } -void add_status(const git_status_entry *entry, unsigned int status_flags, vector &updates) { +void add_status(const git_status_entry *entry, unsigned int status_flags, set &updates) { const char *path = unfuck_path(entry); if(status_flags & GIT_STATUS_WT_NEW || status_flags & GIT_STATUS_INDEX_NEW) { - updates.push_back(string{path}); + updates.insert(string{path}); } if(status_flags & GIT_STATUS_WT_MODIFIED || status_flags & GIT_STATUS_INDEX_MODIFIED) { - updates.push_back(string{path}); + updates.insert(string{path}); } // need to confirm this gets the new name if(status_flags & GIT_STATUS_WT_RENAMED || status_flags & GIT_STATUS_INDEX_RENAMED) { - updates.push_back(string{path}); + updates.insert(string{path}); } } +void list_git_changes(set &updates, git_repository* repo) { + git_status_options opts = GIT_STATUS_OPTIONS_INIT; + git_status_list *statuses = nullptr; + + //TODO: does this leak? + int err = git_status_list_new(&statuses, repo, &opts); + dbc::check(err == 0, git_error_last()->message); + size_t count = git_status_list_entrycount(statuses); + + for(size_t i=0; i < count; i++) { + const git_status_entry *entry = git_status_byindex(statuses, i); + add_status(entry, entry->status, updates); + } +} + + class UpdateListener : public efsw::FileWatchListener { public: bool changes = false; + git_repository* repo = nullptr; + + UpdateListener(git_repository *r) : repo(r) {}; void handleFileAction(efsw::WatchID watchid, const std::string& dir, @@ -76,25 +96,11 @@ class UpdateListener : public efsw::FileWatchListener { efsw::Action action, std::string oldFilename) override { - changes = true; - - switch(action) { - case efsw::Actions::Add: - print("ADD {} {} {}\n", dir, filename, oldFilename); - break; - case efsw::Actions::Delete: - print("DEL {} {} {}\n", dir, filename, oldFilename); - break; - case efsw::Actions::Modified: - print("MOD {} {} {}\n", dir, filename, oldFilename); - break; - case efsw::Actions::Moved: - print("MOV {} {} {}\n", dir, filename, oldFilename); - break; - default: - dbc::sentinel("Unknown efsw action."); - } - + set updates; + list_git_changes(updates, repo); + bool in_git = updates.contains(filename); + // this makes it so we only get it set one time when somethign is in git + changes = changes || in_git; } void reset_state() { @@ -102,31 +108,10 @@ class UpdateListener : public efsw::FileWatchListener { } }; -void list_git_changes(git_repository* repo) { - git_status_options opts = GIT_STATUS_OPTIONS_INIT; - git_status_list *statuses = nullptr; - - //TODO: does this leak? - int err = git_status_list_new(&statuses, repo, &opts); - dbc::check(err == 0, git_error_last()->message); - size_t count = git_status_list_entrycount(statuses); - - vector updates; - - for(size_t i=0; i < count; i++) { - const git_status_entry *entry = git_status_byindex(statuses, i); - add_status(entry, entry->status, updates); - } - - for(string path : updates) { - print("PATH {}\n", path); - } -} - void run_build(const char* command) { - regex err_re("(.*?):([0-9]+):([0-9]+):\\s*(.*?):\\s*(.*)"); + regex err_re("(.*?):([0-9]+):([0-9]+):\\s*(.*?):\\s*(.*)\n*"); + char buffer[BUF_MAX]; // BUF_MAX is a define already? - smatch err; ofstream stats_out; stats_out.open("stats.csv", ios::out | ios::app); auto t = time(nullptr); @@ -141,16 +126,23 @@ void run_build(const char* command) { while(fgets(buffer, BUF_MAX, build_out) != nullptr) { string line(buffer); // yeah, that's probably a problem - print("{}\n", line); - if(regex_match(line, err, err_re)) { + smatch err; + bool match = regex_match(line, err, err_re); + + if(match) { string file_name = err[1].str(); - string line = err[2].str(); + string lnumber = err[2].str(); string col = err[3].str(); string type = err[4].str(); string message = err[5].str(); stats_out << put_time(&tm, "%FT%TZ"); - stats_out << format(",{},{},{},{},{}\n", file_name, line, col, type, message); + string result = format(",{},{},{},{},{}\n", file_name, lnumber, col, type, message); + + stats_out << result; + cout << "MATCHED: " << quoted(result); + } else { + //println("NOT MATCHED! {}", line); } } @@ -168,7 +160,7 @@ int main(int argc, char *argv[]) const char *git_path = argv[1]; const char *build_cmd = argv[2]; - print("Using build command: {}", build_cmd); + println("Using build command: {}", build_cmd); efsw::FileWatcher* fileWatcher = new efsw::FileWatcher(); dbc::check(fileWatcher != nullptr, "Failed to create filewatcher."); @@ -177,22 +169,22 @@ int main(int argc, char *argv[]) int err = git_repository_open(&repo, git_path); dbc::check(err == 0, git_error_last()->message); - UpdateListener* listener = new UpdateListener(); + UpdateListener* listener = new UpdateListener(repo); dbc::check(listener != nullptr, "Failed to create listener."); print("Watching directory {} for changes...\n", git_path); efsw::WatchID wid = fileWatcher->addWatch(git_path, listener, true); while(true) { + print("WAITING...\r"); fileWatcher->watch(); if(listener->changes) { sleep(1); - list_git_changes(repo); - listener->reset_state(); + println("CHANGES! Running build {}", build_cmd); run_build(build_cmd); + listener->reset_state(); } - sleep(1); }