#include #include #include #include #include #include #include #include #include #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; free(repo); } } 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); } void cleanup_git(git_repository **repos) { cleanup_git_repos(repos); git_libgit2_shutdown(); } pull_request *get_pull_request(int id, const char *root) { } int create_pull_request_dir(pull_request *pr, const char *root) { int id = 0; int is_num = 0; DIR *dir = opendir(root); struct dirent entry, *result; while (readdir_r(dir, &entry, &result) == 0 && result != NULL) { if (entry.d_type == DT_DIR) { char *tmp = entry.d_name; /* Is this a blank directory name? */ if (*tmp == '\0') { continue; } for (is_num = 1; *tmp && is_num; is_num = isdigit(*tmp++)); /* Is this a numbered directory? */ if (is_num) { int val = strtol(entry.d_name, NULL, 0); /* Set the current ID to the numbered directory, if it's larger than it. */ id = (id < val) ? val : id; } } } /* Did we find any numbered directories? */ if (id > 0) { struct stat st; file **commits = (pr->pr_type) ? get_branch_commits(pr->branch) : pr->patches; /* Get the length of the stringified ID path. */ int len = snprintf(NULL, 0, "%s/%i", root, id); /* Convert the ID to a string. */ char *pr_dir = calloc(len+1, sizeof(char)); sprintf(pr_dir, "%s/%i", root, id); /* Is there no existing directory? */ if (stat(pr_dir, &st) < -1) { /* Create a directory with a name of the stringified ID. */ mkdir(pr_dir, 0755); } /* TODO: Implement rest of code. */ } return id; } git_repository **init_git(config *cfg) { 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) + 2, 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; }