mobley

C Git HTTP server
Log | Files | Refs | Submodules | README | git clone https://git.ne02ptzero.me/git/mobley

commit fcd57317dbebcbaecec4df51c8821f3a8a02e580
parent a7511ff06dda99d98594a2ecf9ef19281fe1d7af
Author: Louis Solofrizzo <lsolofrizzo@online.net>
Date:   Mon, 17 Dec 2018 18:04:46 +0100

Add last commit date on index repository list

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>

Diffstat:
MCMakeLists.txt | 3++-
Mconfig.c | 14+++++++++++++-
Mconfig.yaml | 12++++++------
Mhtml.h | 6++++++
Mindex.c | 16+++++++++++++++-
Mmain.c | 3+++
Arepository.c | 35+++++++++++++++++++++++++++++++++++
Mrepository.h | 30+++++++++++++++++++-----------
Mstyle/main.css | 2+-
9 files changed, 100 insertions(+), 21 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -36,7 +36,7 @@ add_definitions(-DMOBLEY_MINOR="${MOBLEY_MINOR}") include_directories(".") -link_libraries(pthread event event_openssl crypto ssl evhtp yaml) +link_libraries(pthread event event_openssl crypto ssl evhtp yaml git2) add_executable(${MOBLEY_NAME} main.c args.c @@ -47,6 +47,7 @@ add_executable(${MOBLEY_NAME} main.c index.c template.c config.c + repository.c ) install(TARGETS ${MOBLEY_NAME} DESTINATION bin) diff --git a/config.c b/config.c @@ -98,15 +98,24 @@ static bool config_read_repositories(yaml_parser_t *parser, yaml_event_t *event, quit--; break; case YAML_MAPPING_END_EVENT: - list_add_tail(&repo->node, &ctx->repos.repos); quit++; if (quit != 2) { + if (!repository_git_init(repo)) + { + printf("Can't open %s (%s)\n", repo->name, repo->path); + goto end; + } + + list_add_tail(&repo->node, &ctx->repos.repos); + repo = calloc(1, sizeof(*repo)); if (repo == NULL) goto end; } + else + free(repo); break ; @@ -131,6 +140,8 @@ static bool config_read_repositories(yaml_parser_t *parser, yaml_event_t *event, COPY_OR_FAIL(repo->owner, val); else if (strcmp(token, "dir") == 0) repository_set_path(repo, val, ctx->repos.repo_dir); + else if (strcmp(token, "default_branch") == 0) + COPY_OR_FAIL(repo->default_branch, val); else { printf("Unknown token = %s\n", token); @@ -152,6 +163,7 @@ static bool config_read_repositories(yaml_parser_t *parser, yaml_event_t *event, } while (quit != 2); free(token); + if (ctx->conf.sort_repo) list_sort(NULL, &ctx->repos.repos, &repository_name_cmp); diff --git a/config.yaml b/config.yaml @@ -4,7 +4,7 @@ static_dir : /usr/local/share/mobley logo : logo.png desc : Software Stuff title : git:// -repo_dir : /tmp/git +repo_dir : /home/louis/Work/perso/git_local/repositories sort_repo : true styles: @@ -22,7 +22,7 @@ repositories: description : HTTP git distributed viewer C server owner : louis - - dir : krakern.git + - dir : KraKern.git name : krakern description : C++ POSIX kernel owner : louis @@ -39,12 +39,12 @@ repositories: - dir : 42_Scale.git name : 42_scale - description : A small software to create and edit 42 (.yaml) scale files easily + description : a small software to create and edit 42 (.yaml) scale files easily owner : louis - dir : Y-asc.git name : y-asc - description : Yet Another Stupid compiler + description : yet another stupid compiler owner : louis - dir : KFS.git @@ -57,7 +57,7 @@ repositories: description : low level network subjects owner : louis - - dir : C_Advanced_Tips_n_Tricks.git + - dir : c_advanced_tips_n_tricks.git name : C_advanced_tips_and_tricks description : 42 conference about some C tricks owner : louis @@ -99,7 +99,7 @@ repositories: - dir : Grog-Knight.git name : grog-knight - description : Some game in C++ + description : some game in C++ owner : louis - dir : IRC-Bot.git diff --git a/html.h b/html.h @@ -45,5 +45,11 @@ void _html(server_req_t *r, const mobley_t *ctx, # define html_open(s, ...) _html(r, ctx, s, NULL, &(html_args_t){__VA_ARGS__}); # define html_close(s) evbuffer_add_printf((r)->req->buffer_out, "</" s ">") # define html_simple(s) html_open(s) +# define html_git_date(s) do { \ + struct tm *__timeinfo; \ + \ + __timeinfo = localtime(s); \ + html_raw("%s", asctime(__timeinfo)); \ +} while (0) #endif /* HTML_H */ diff --git a/index.c b/index.c @@ -20,6 +20,8 @@ bool index_route_handler(const mobley_t *ctx, server_req_t *r) { repository_t *repo; + git_commit *commit; + git_time_t time; html_open("table") { @@ -41,7 +43,19 @@ bool index_route_handler(const mobley_t *ctx, server_req_t *r) } html_close("td"); html("td", repo->desc); html("td", repo->owner, .align = "right"); - html("td", repo->path, .align = "right"); + + html_open("td", .align = "right") { + commit = repository_get_last_commit(repo); + if (commit != NULL) + { + time = git_commit_time(commit); + html_git_date(&time); + git_commit_free(commit); + } + else + html_raw("None"); + } html_close("td"); + } html_close("tr"); } } html_close("tbody"); diff --git a/main.c b/main.c @@ -115,6 +115,8 @@ int main(int ac, const char **av) if (!parse_args(ac, av, options, COUNT_OF(options), &help)) return 1; + git_libgit2_init(); + if (!mobley_options(&ctx)) goto end; @@ -137,6 +139,7 @@ end: event_free(ev_sighup); mobley_dtr(&ctx); + git_libgit2_shutdown(); free_args(options, COUNT_OF(options)); return ret; } diff --git a/repository.c b/repository.c @@ -0,0 +1,35 @@ +/** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <repository.h> + +git_commit *repository_get_last_commit(repository_t *repo) +{ + git_commit *ret = NULL; + git_oid oid_parent_commit = { 0 }; + char branch[1024] = { 0 }; + + if (repo->repo == NULL) + return NULL; + + snprintf(branch, sizeof(branch), "refs/heads/%s", + repo->default_branch != NULL ? repo->default_branch : "master"); + + if (git_reference_name_to_id(&oid_parent_commit, repo->repo, branch) == 0) + if (git_commit_lookup(&ret, repo->repo, &oid_parent_commit) == 0) + return ret; + + return NULL; +} diff --git a/repository.h b/repository.h @@ -16,16 +16,20 @@ #ifndef REPOSITORY_H # define REPOSITORY_H -# include <list.h> # include <stdlib.h> # include <stdio.h> +# include <git2.h> + +# include <list.h> typedef struct { - char path[PATH_MAX]; - char *name; - char *desc; - char *owner; - list_head_t node; + char path[PATH_MAX]; + char *name; + char *desc; + char *owner; + char *default_branch; + git_repository *repo; + list_head_t node; } repository_t; static inline void repository_dtr(repository_t *ptr) @@ -36,6 +40,13 @@ static inline void repository_dtr(repository_t *ptr) free(ptr->name); free(ptr->desc); free(ptr->owner); + free(ptr->default_branch); + git_repository_free(ptr->repo); +} + +static inline bool repository_git_init(repository_t *ptr) +{ + return git_repository_open_bare(&ptr->repo, ptr->path) == 0; } static inline void repository_set_path(repository_t *out, const char *dir, const char *path) @@ -59,12 +70,9 @@ static inline int repository_name_cmp(void *u, list_head_t *a, list_head_t *b) repository_t *one = list_entry(a, repository_t, node); repository_t *two = list_entry(b, repository_t, node); - if (one->name == NULL) - return 1; - if (two->name == NULL) - return -1; - return strcmp(one->name, two->name); } +git_commit *repository_get_last_commit(repository_t *repo); + #endif /* REPOSITORY_H */ diff --git a/style/main.css b/style/main.css @@ -100,7 +100,7 @@ table td { white-space: nowrap; } -tr:hover td { +tbody tr:hover td { background-color: #333; }