diff options
| -rw-r--r-- | ui-summary.c | 341 |
1 files changed, 175 insertions, 166 deletions
diff --git a/ui-summary.c b/ui-summary.c index e2003b1..2c22e43 100644 --- a/ui-summary.c +++ b/ui-summary.c @@ -7,202 +7,211 @@ */ #include "cgit.h" -#include "ui-summary.h" #include "html.h" #include "ui-blob.h" #include "ui-log.h" #include "ui-plain.h" #include "ui-refs.h" #include "ui-shared.h" +#include "ui-summary.h" static int urls; static void print_url(const char *url) { - int columns = 3; - - if (ctx.repo->enable_log_filecount) - columns++; - if (ctx.repo->enable_log_linecount) - columns++; - - if (urls++ == 0) { - htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); - htmlf("<tr class='nohover'><th class='left' colspan='%d'>Clone</th></tr>\n", columns); - } - - htmlf("<tr><td colspan='%d'><a rel='vcs-git' href=\"javascript:navigator.clipboard.writeText('", columns); - html_url_path(url); - html("');\" title='"); - html_attr(ctx.repo->name); - html(" Git repository'>"); - html_txt(url); - html("</a></td></tr>\n"); + int columns = 3; + + if (ctx.repo->enable_log_filecount) + columns++; + if (ctx.repo->enable_log_linecount) + columns++; + + if (urls++ == 0) + { + htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); + htmlf("<tr class='nohover'><th class='left' colspan='%d'>Clone</th></tr>\n", columns); + } + + htmlf("<tr><td colspan='%d'><a rel='vcs-git' href=\"javascript:navigator.clipboard.writeText('", columns); + html_url_path(url); + html("');\" title='"); + html_attr(ctx.repo->name); + html(" Git repository'>"); + html_txt(url); + html("</a></td></tr>\n"); } void cgit_print_summary(void) { - int columns = 3; - - if (ctx.repo->enable_log_filecount) - columns++; - if (ctx.repo->enable_log_linecount) - columns++; - - cgit_print_layout_start(); - - html("<table summary='repository info' class='list nowrap'>"); - cgit_print_branches(ctx.cfg.summary_branches); - htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); - cgit_print_tags(ctx.cfg.summary_tags); - if (ctx.cfg.summary_log > 0) { - htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); - cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, - NULL, NULL, 0, 0, 0); - } - urls = 0; - cgit_add_clone_urls(print_url); - html("</table>"); - cgit_print_layout_end(); + int columns = 3; + + if (ctx.repo->enable_log_filecount) + columns++; + if (ctx.repo->enable_log_linecount) + columns++; + + cgit_print_layout_start(); + + html("<table summary='repository info' class='list nowrap'>"); + cgit_print_branches(ctx.cfg.summary_branches); + htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); + cgit_print_tags(ctx.cfg.summary_tags); + if (ctx.cfg.summary_log > 0) + { + htmlf("<tr class='nohover'><td colspan='%d'> </td></tr>", columns); + cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, NULL, NULL, 0, 0, 0); + } + urls = 0; + cgit_add_clone_urls(print_url); + html("</table>"); + cgit_print_layout_end(); } /* The caller must free the return value. */ -static char* append_readme_path(const char *filename, const char *ref, const char *path) +static char *append_readme_path(const char *filename, const char *ref, const char *path) { - char *file, *base_dir, *full_path, *resolved_base = NULL, *resolved_full = NULL; - /* If a subpath is specified for the about page, make it relative - * to the directory containing the configured readme. */ - - file = xstrdup(filename); - base_dir = dirname(file); - if (!strcmp(base_dir, ".") || !strcmp(base_dir, "..")) { - if (!ref) { - free(file); - return NULL; - } - full_path = xstrdup(path); - } else - full_path = fmtalloc("%s/%s", base_dir, path); - - if (!ref) { - resolved_base = realpath(base_dir, NULL); - resolved_full = realpath(full_path, NULL); - if (!resolved_base || !resolved_full || !starts_with(resolved_full, resolved_base)) { - free(full_path); - full_path = NULL; - } - } - - free(file); - free(resolved_base); - free(resolved_full); - - return full_path; + char *file, *base_dir, *full_path, *resolved_base = NULL, *resolved_full = NULL; + /* If a subpath is specified for the about page, make it relative + * to the directory containing the configured readme. */ + + file = xstrdup(filename); + base_dir = dirname(file); + if (!strcmp(base_dir, ".") || !strcmp(base_dir, "..")) + { + if (!ref) + { + free(file); + return NULL; + } + full_path = xstrdup(path); + } + else + full_path = fmtalloc("%s/%s", base_dir, path); + + if (!ref) + { + resolved_base = realpath(base_dir, NULL); + resolved_full = realpath(full_path, NULL); + if (!resolved_base || !resolved_full || !starts_with(resolved_full, resolved_base)) + { + free(full_path); + full_path = NULL; + } + } + + free(file); + free(resolved_base); + free(resolved_full); + + return full_path; } -struct get_readme_oid_ctx { - struct object_id *oid; - char **filename; - const char *path; - bool found; +struct get_readme_oid_ctx +{ + struct object_id *oid; + char **filename; + const char *path; + bool found; }; -static int get_readme_oid_cb(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, int stage, void *cbdata) { - - struct get_readme_oid_ctx *ctx = (struct get_readme_oid_ctx*)cbdata; - - // TODO: make readme.md configurable, ctx.readme (stringlist) - const int readme_names_count = 2; - const char **readme_names = (const char*[]){"readme.md", "readme"}; - - struct strbuf buffer = STRBUF_INIT; - - if (base->len > 0) - strbuf_addbuf(&buffer, base); - strbuf_addstr(&buffer, pathname); - - size_t path_len = (ctx->path == NULL) ? 0 : strlen(ctx->path); - size_t cmp_count = (buffer.len > 0 && buffer.buf[buffer.len-1] == '/') ? buffer.len-1 : buffer.len; - if (path_len < cmp_count) cmp_count = path_len; - bool match_base = strncmp(buffer.buf, ctx->path, cmp_count) == 0; - bool match_path = match_base && buffer.len == path_len; - - strbuf_release(&buffer); - - bool match_pathname = match_base && match_path && (oid_object_info(the_repository, oid, NULL) == OBJ_BLOB); - - // htmlf("[%s %s %s %b %b]", base->buf, pathname, ctx->path, match_base, match_path); - - for (int i = 0; i < readme_names_count; i++) { - if ( match_pathname || (match_base && strcasecmp(pathname, readme_names[i]) == 0) ) { - if (ctx->oid) - *(ctx->oid) = *oid; - if (ctx->filename) - *(ctx->filename) = xstrdup(pathname); - ctx->found = true; - break; - } - } - - return READ_TREE_RECURSIVE; -} -bool get_readme_oid(struct tree *tree, struct pathspec *paths, struct object_id *oid, char **filename) { - struct get_readme_oid_ctx gro_ctx = (struct get_readme_oid_ctx){ - .oid = oid, - .filename = filename, - .path = (paths->nr == 1 ? paths->items[0].match : NULL), - .found = false }; - read_tree_recursive(the_repository, tree, "", 0, 0, - paths, get_readme_oid_cb, &gro_ctx); - return gro_ctx.found; -} +static int get_readme_oid_cb(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, + int stage, void *cbdata) +{ + + struct get_readme_oid_ctx *ctx = (struct get_readme_oid_ctx *)cbdata; + + // TODO: make readme.md configurable, ctx.readme (stringlist) + const int readme_names_count = 2; + const char **readme_names = (const char *[]){"readme.md", "readme"}; + + struct strbuf buffer = STRBUF_INIT; + + if (base->len > 0) + strbuf_addbuf(&buffer, base); + strbuf_addstr(&buffer, pathname); -bool cgit_has_readme(void) { - struct object_id oid; - if (get_oid(ctx.qry.head, &oid)) { - return false; - } + size_t path_len = (ctx->path == NULL) ? 0 : strlen(ctx->path); + size_t cmp_count = (buffer.len > 0 && buffer.buf[buffer.len - 1] == '/') ? buffer.len - 1 : buffer.len; + if (path_len < cmp_count) + cmp_count = path_len; + bool match_base = strncmp(buffer.buf, ctx->path, cmp_count) == 0; + bool match_path = match_base && buffer.len == path_len; - struct commit *commit = lookup_commit_reference(the_repository, &oid); - struct object_id *commit_tree_oid = get_commit_tree_oid(commit); + strbuf_release(&buffer); - struct tree *tree = parse_tree_indirect(commit_tree_oid); - struct pathspec paths = { - .nr = 0, - }; - return get_readme_oid(tree, &paths, NULL, NULL); + bool match_pathname = match_base && match_path && (oid_object_info(the_repository, oid, NULL) == OBJ_BLOB); + + // htmlf("[%s %s %s %b %b]", base->buf, pathname, ctx->path, match_base, match_path); + + for (int i = 0; i < readme_names_count; i++) + { + if (match_pathname || (match_base && strcasecmp(pathname, readme_names[i]) == 0)) + { + if (ctx->oid) + *(ctx->oid) = *oid; + if (ctx->filename) + *(ctx->filename) = xstrdup(pathname); + ctx->found = true; + break; + } + } + + if (match_base && cmp_count > 0) + return READ_TREE_RECURSIVE; + else + return 0; +} +bool get_readme_oid(struct tree *tree, struct pathspec *paths, struct object_id *oid, char **filename) +{ + struct get_readme_oid_ctx gro_ctx = (struct get_readme_oid_ctx){ + .oid = oid, .filename = filename, .path = (paths->nr == 1 ? paths->items[0].match : NULL), .found = false}; + read_tree_recursive(the_repository, tree, "", 0, 0, paths, get_readme_oid_cb, &gro_ctx); + return gro_ctx.found; +} + +bool cgit_has_readme(void) +{ + struct object_id oid; + if (get_oid(ctx.qry.head, &oid)) + { + return false; + } + + struct commit *commit = lookup_commit_reference(the_repository, &oid); + struct object_id *commit_tree_oid = get_commit_tree_oid(commit); + + struct tree *tree = parse_tree_indirect(commit_tree_oid); + struct pathspec paths = { + .nr = 0, + }; + return get_readme_oid(tree, &paths, NULL, NULL); } void cgit_print_repo_readme_no_layout(struct tree *tree, struct pathspec *paths) { - char *filename = NULL; - struct object_id readme_oid; - if (get_readme_oid(tree, paths, &readme_oid, &filename)) { - html("<div id='summary'>"); - cgit_open_filter(ctx.repo->about_filter, filename); - cgit_print_oid(&readme_oid); - cgit_close_filter(ctx.repo->about_filter); - - html("</div>"); - - free(filename); - } + char *filename = NULL; + struct object_id readme_oid; + if (get_readme_oid(tree, paths, &readme_oid, &filename)) + { + html("<div id='summary'>"); + cgit_open_filter(ctx.repo->about_filter, filename); + cgit_print_oid(&readme_oid); + cgit_close_filter(ctx.repo->about_filter); + + html("</div>"); + + free(filename); + } } -void cgit_print_repo_readme(const char *path, struct object_id *oid) { - struct commit *commit = lookup_commit_reference(the_repository, oid); - struct object_id *commit_tree_oid = get_commit_tree_oid(commit); - - struct tree *tree = parse_tree_indirect(commit_tree_oid); - struct pathspec_item path_items = { - .match = path, - .len = path ? strlen(path) : 0 - }; - struct pathspec paths = { - .nr = path ? 1 : 0, - .items = &path_items - }; - cgit_print_layout_start(); - cgit_print_repo_readme_no_layout(tree, &paths); +void cgit_print_repo_readme(const char *path, struct object_id *oid) +{ + struct commit *commit = lookup_commit_reference(the_repository, oid); + struct object_id *commit_tree_oid = get_commit_tree_oid(commit); + + struct tree *tree = parse_tree_indirect(commit_tree_oid); + struct pathspec_item path_items = {.match = path, .len = path ? strlen(path) : 0}; + struct pathspec paths = {.nr = path ? 1 : 0, .items = &path_items}; + cgit_print_layout_start(); + cgit_print_repo_readme_no_layout(tree, &paths); } // void cgit_print_repo_readme_no_layout(const struct tree *tree, struct pathspec *paths) // { |
