From 6c244ade251499eea92be4dff8bd3793bcc27817 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sun, 13 Jun 2021 15:45:12 -0400 Subject: Finished the git initialization code. --- git.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 3 deletions(-) (limited to 'git.c') diff --git a/git.c b/git.c index 61ab0c0..fbeb0e9 100644 --- a/git.c +++ b/git.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include #include #include @@ -10,13 +10,113 @@ #include #include #include "config.h" +#include "git.h" #include "macros.h" +git_repo *add_repo(git_repository *repo, git_repo **first, git_repo **last) { + git_repo *new_repo = calloc(1, sizeof(git_repo)); + (*last != NULL) ? ((*last)->next = new_repo) : (*first = new_repo); + + new_repo->repo = repo; + + *last = new_repo; + + return new_repo; +} + +int find_ignore_file(const char *path) { + DIR *root = opendir(path); + struct dirent entry, *result; + + while (readdir_r(root, &entry, &result) == 0 && result != NULL) { + /* Is this entry a regular file, and is it the ignore file? */ + if (entry.d_type == DT_REG && strcasecmp(entry.d_name, "pullreqd-ignore") == 0) { + return 1; + } + } + + return 0; +} + +void cleanup_linked_list(git_repo *root) { + if (root != NULL) { + git_repo *repo = root; + cleanup_linked_list(root->next); + repo->repo = NULL; + repo->next = NULL; + } +} + +void cleanup_git_repos(git_repository **repos) { + for (int i = 0; repos[i] != NULL; i++) { + git_repository_free(repos[i]); + repos[i] = NULL; + } + free(repos); +} + git_repository **init_git(config *cfg) { - git_repository **repos; - git_repository *repo; + git_repository **repos = NULL; + git_repository *repo = NULL; + git_repo *first = NULL, *last = NULL, *current = NULL; + DIR *root = opendir(cfg->git_root); + struct dirent entry, *result; + int repo_count = 0; + + log(LOG_INFO, "Initializing libgit2."); + int ret = git_libgit2_init(); + + log(LOG_INFO, "Searching \"%s\" for repositories.", cfg->git_root); + /* Find all git repos in the git root. */ + while (readdir_r(root, &entry, &result) == 0 && result != NULL) { + log(LOG_DEBUG, "entry.d_name %s, result->d_name: %s", entry.d_name, result->d_name); + /* Is this entry a directory? */ + if (entry.d_type == DT_DIR) { + /* Is the entry neither ".", nor ".."? */ + if (strcmp(entry.d_name, ".") && strcmp(entry.d_name, "..")) { + char *repo_dir = calloc(strlen(cfg->git_root) + strlen(entry.d_name) + 1, sizeof(char)); + + /* Append the directory name to the git root. */ + /* Could also do this: + * memcpy(repo_dir, cfg->git_root, strlen(cfg->git_repo)); + * strcat(repo_dir, entry.d_name); + */ + sprintf(repo_dir, "%s%s", cfg->git_root, entry.d_name); + /* Was no ignore file found? */ + if (!find_ignore_file(repo_dir)) { + /* Did we fail to open the git repo? */ + if (git_repository_open(&repo, repo_dir)) { + log(LOG_ERR, "Failed to open git repository %s, ignoring.", entry.d_name); + } else { + log(LOG_INFO, "Successfully opened git repository %s", entry.d_name); + current = add_repo(repo, &first, &last); + repo_count++; + } + } + free(repo_dir); + } + } + } + /* Did we find any repos? */ + if (repo_count) { + log(LOG_INFO, "Found, and opened %i repositories.", repo_count); + /* Allocate repo_count + 1 git repos, since we need a NULL entry to denote the end. */ + repos = calloc(repo_count+1, sizeof(git_repository *)); + /* Add the repos to the array. */ + int i = 0; + for (git_repo *r = first; r != NULL; /*repos[i] = r->repo,*/ r = r->next, i++) { + repos[i] = r->repo; + } + cleanup_linked_list(first); + first = NULL; + last = NULL; + current = NULL; + } else { + log(LOG_ERR, "Couldn't find, and/or open any repositories."); + } + return repos; } -- cgit v1.2.3-13-gbd6f