Tue, 21 Jan 2025 20:24:45 +0100
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; };