add repository scanner

Tue, 21 Jan 2025 20:24:45 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 21 Jan 2025 20:24:45 +0100
changeset 3
c87bde92805f
parent 2
7384ebae6b7c
child 4
82680ce258d6

add repository scanner

src/Makefile file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/process.h file | annotate | diff | comparison | revisions
src/repositories.cpp file | annotate | diff | comparison | revisions
src/repositories.h file | annotate | diff | comparison | revisions
src/settings.h file | annotate | diff | comparison | revisions
--- a/src/Makefile	Tue Jan 21 18:25:59 2025 +0100
+++ b/src/Makefile	Tue Jan 21 20:24:45 2025 +0100
@@ -23,7 +23,7 @@
 
 include ../config.mk
 
-SRC=main.cpp process.cpp
+SRC=main.cpp process.cpp repositories.cpp
 OBJ=$(SRC:%.cpp=../build/%.o)
 OUTPUT=../build/fallusmeter
 
@@ -40,7 +40,7 @@
 
 FORCE:
 
-../build/main.o: main.cpp settings.h
+../build/main.o: main.cpp settings.h repositories.h
 	@echo "Compiling $<"
 	$(CXX) -o $@ $(CXXFLAGS)  -c $<
 
@@ -48,3 +48,7 @@
 	@echo "Compiling $<"
 	$(CXX) -o $@ $(CXXFLAGS)  -c $<
 
+../build/repositories.o: repositories.cpp repositories.h
+	@echo "Compiling $<"
+	$(CXX) -o $@ $(CXXFLAGS)  -c $<
+
--- a/src/main.cpp	Tue Jan 21 18:25:59 2025 +0100
+++ b/src/main.cpp	Tue Jan 21 20:24:45 2025 +0100
@@ -23,6 +23,7 @@
  */
 
 #include "settings.h"
+#include "repositories.h"
 
 #include <cstdlib>
 #include <cstdio>
@@ -48,13 +49,14 @@
         "When you do not specify \033[1m--no-pull\033[22m, this tool will execute the pull command\n"
         "(and for hg the update command) before retrieving the commit log, assuming\n"
         "to be on the default branch with \033[4mno uncommitted changes\033[24m.\n\n"
-        "The default output format prints an HTML page to stdout. In all cases, a\n"
-        "separate heat map is generated for each author, but all repositories are,\n"
-        "accumulated unless the \033[1m--separate\033[22m option is specified.\n"
+        "Afterwards, this tool prints an HTML page to stdout. A separate heap map is\n"
+        "generated for each author showing commits across all repositories, unless the\n"
+        "\033[1m--separate\033[22m option is specified in which case each repository is displayed with\n"
+        "its own heat map.\n"
         , stderr);
 }
 
-static bool chk_arg(const char* arg, const char* opt1, const char* opt2) {
+static bool chk_arg(const char *arg, const char *opt1, const char *opt2) {
     return strcmp(arg, opt1) == 0 || (opt2 != nullptr && strcmp(arg, opt2) == 0);
 }
 
@@ -88,7 +90,7 @@
                 return -1;
             }
         } else if (chk_arg(argv[i], "-n", "--no-pull")) {
-            settings.nopull = true;
+            settings.update_repos = false;
         } else if (chk_arg(argv[i], "-s", "--separate")) {
             settings.separate = true;
         } else if (chk_arg(argv[i], "--hg", nullptr)) {
@@ -120,6 +122,14 @@
     return 0;
 }
 
+static void print_html_header() {
+    puts("<html>\n\t<body>");
+}
+
+static void print_html_footer() {
+    puts("\t</body>\n</html>");
+}
+
 int main(int argc, char *argv[]) {
     fm::settings settings;
 
@@ -127,6 +137,18 @@
         return EXIT_FAILURE;
     }
 
+    fm::repositories repos;
+    for (auto &&path: settings.paths) {
+        repos.scan(path, settings.depth);
+    }
+    if (!settings.update_repos) {
+        // TODO: update repositories
+    }
+    // TODO: calculate the heat maps
+
+    print_html_header();
+    // TODO: output the heat maps here
+    print_html_footer();
+
     return EXIT_SUCCESS;
 }
-
--- a/src/process.h	Tue Jan 21 18:25:59 2025 +0100
+++ b/src/process.h	Tue Jan 21 20:24:45 2025 +0100
@@ -30,7 +30,7 @@
 
 namespace fm {
 
-class process {
+class process final {
     std::string m_path;
     std::string m_output;
 public:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/repositories.cpp	Tue Jan 21 20:24:45 2025 +0100
@@ -0,0 +1,66 @@
+/* Copyright 2025 Mike Becker. All rights reserved.
+*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "repositories.h"
+
+#include <utility>
+#include <filesystem>
+
+using namespace fm;
+namespace fs = std::filesystem;
+
+void repositories::scan(std::string path, unsigned depth) {
+    // check the base path
+    {
+        auto p = fs::path{path};
+        if (is_directory(p / ".hg")) {
+            m_repositories.emplace_back(repository{canonical(p), HG});
+            return;
+        } else if (is_directory(p / ".git")) {
+            m_repositories.emplace_back(repository{canonical(p), GIT});
+            return;
+        } else if (depth == 0) {
+            return;
+        }
+    }
+
+    // if depth is non-zero, scan subdirs recursively
+    --depth;
+    for (auto i = fs::recursive_directory_iterator(
+             std::move(path),
+             fs::directory_options::skip_permission_denied);
+         i != fs::recursive_directory_iterator(); ++i) {
+        if (!i->is_directory()) continue;
+        auto p = i->path();
+        if (is_directory(p / ".hg")) {
+            m_repositories.emplace_back(repository{canonical(p), HG});
+            i.disable_recursion_pending();
+        } else if (is_directory(p / ".git")) {
+            m_repositories.emplace_back(repository{canonical(p), GIT});
+            i.disable_recursion_pending();
+        } else if (i.depth() == depth) {
+            i.disable_recursion_pending();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/repositories.h	Tue Jan 21 20:24:45 2025 +0100
@@ -0,0 +1,53 @@
+/* Copyright 2025 Mike Becker. All rights reserved.
+*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef REPOSITORIES_H
+#define REPOSITORIES_H
+
+#include <string>
+#include <vector>
+
+namespace fm {
+
+enum repository_type {
+    HG, GIT
+};
+
+struct repository final {
+    std::string path;
+    repository_type type;
+};
+
+class repositories final {
+    std::vector<repository> m_repositories;
+public:
+    void scan(std::string path, unsigned depth);
+    [[nodiscard]] const std::vector<repository>& list() const {
+        return m_repositories;
+    }
+};
+
+} // fm
+
+#endif //REPOSITORIES_H
--- a/src/settings.h	Tue Jan 21 18:25:59 2025 +0100
+++ b/src/settings.h	Tue Jan 21 20:24:45 2025 +0100
@@ -38,7 +38,7 @@
     std::string git{"/usr/bin/git"};
     std::vector<std::string> paths;
     unsigned char depth = 1;
-    bool nopull = false;
+    bool update_repos = true;
     bool separate = false;
     unsigned short year = SETTINGS_CURRENT_YEAR;
 };

mercurial