diff options
| -rw-r--r-- | cmd.c | 16 | ||||
| -rw-r--r-- | ui-shared.c | 3 | ||||
| -rw-r--r-- | ui-summary.c | 137 | ||||
| -rw-r--r-- | ui-summary.h | 3 |
4 files changed, 74 insertions, 85 deletions
@@ -41,6 +41,8 @@ static void about_fn(void) { if (ctx.repo) { size_t path_info_len = ctx.env.path_info ? strlen(ctx.env.path_info) : 0; + struct object_id oid; + if (!ctx.qry.path && ctx.qry.url[strlen(ctx.qry.url) - 1] != '/' && (!path_info_len || ctx.env.path_info[path_info_len - 1] != '/')) { @@ -49,10 +51,12 @@ static void about_fn(void) cgit_redirect(redirect, true); free(currenturl); free(redirect); - } else if (ctx.repo->readme.nr) - cgit_print_repo_readme(ctx.qry.path); - else if (ctx.repo->homepage) + } else if (!get_oid(ctx.qry.head, &oid)) { + cgit_print_repo_readme(ctx.qry.path, &oid); + } + else if (ctx.repo->homepage) { cgit_redirect(ctx.repo->homepage, false); + } else { char *currenturl = cgit_currenturl(); char *redirect = fmtalloc("%s../", currenturl); @@ -205,7 +209,11 @@ struct cgit_cmd *cgit_get_cmd(void) if (!strcmp(ctx.qry.page, cmds[i].name)) return &cmds[i]; - char *redirect = fmtalloc("/git/%s/tree/%s%s%s", ctx.qry.repo, ctx.qry.page, ctx.qry.path ? "/" : "", ctx.qry.path ? ctx.qry.path : ""); + char *redirect; + if (ctx.qry.path) + redirect = fmtalloc("/git/%s/tree/%s/%s", ctx.qry.repo, ctx.qry.page, ctx.qry.path); + else + redirect = fmtalloc("/git/%s/tree/%s", ctx.qry.repo, ctx.qry.page); cgit_redirect(redirect, false); free(redirect); diff --git a/ui-shared.c b/ui-shared.c index e352c33..9d8dfef 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -8,6 +8,7 @@ #include "cgit.h" #include "ui-shared.h" +#include "ui-summary.h" #include "cmd.h" #include "html.h" #include "version.h" @@ -1037,7 +1038,7 @@ void cgit_print_pageheader(void) html("<table class='tabs'><tr><td>\n"); if (ctx.env.authenticated && ctx.repo) { - if (ctx.repo->readme.nr) + if (cgit_has_readme()) reporevlink("about", "about", NULL, hc("about"), ctx.qry.head, NULL, NULL); diff --git a/ui-summary.c b/ui-summary.c index 57182e3..e2003b1 100644 --- a/ui-summary.c +++ b/ui-summary.c @@ -31,14 +31,13 @@ static void print_url(const char *url) htmlf("<tr class='nohover'><th class='left' colspan='%d'>Clone</th></tr>\n", columns); } - htmlf("<tr><td colspan='%d'><input type='text' readonly value='", columns); - html_url_path(url); - html("' />"); - html("<button onclick=\"navigator.clipboard.writeText('"); - html_txt(url); - html("');\">"); - html("<svg aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\" display=\"inline-block\" overflow=\"visible\" style=\"vertical-align: text-bottom;\"><path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path></svg>"); - html("</button></td></tr>\n"); + 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) @@ -101,55 +100,6 @@ static char* append_readme_path(const char *filename, const char *ref, const cha return full_path; } -void cgit_print_repo_readme(const char *path) -{ - char *filename, *ref, *mimetype; - int free_filename = 0; - - mimetype = get_mimetype_for_filename(path); - if (mimetype && (!strncmp(mimetype, "image/", 6) || !strncmp(mimetype, "video/", 6))) { - ctx.page.mimetype = mimetype; - ctx.page.charset = NULL; - cgit_print_plain(); - free(mimetype); - return; - } - free(mimetype); - - cgit_print_layout_start(); - if (ctx.repo->readme.nr == 0) - goto done; - - filename = ctx.repo->readme.items[0].string; - ref = ctx.repo->readme.items[0].util; - - if (path) { - free_filename = 1; - filename = append_readme_path(filename, ref, path); - if (!filename) - goto done; - } - - /* Print the calculated readme, either from the git repo or from the - * filesystem, while applying the about-filter. - */ - html("<div id='summary'>"); - cgit_open_filter(ctx.repo->about_filter, filename); - if (ref) - cgit_print_file(filename, ref, 1); - else - html_include(filename); - cgit_close_filter(ctx.repo->about_filter); - - html("</div>"); - if (free_filename) - free(filename); - - -done: - cgit_print_layout_end(); -} - struct get_readme_oid_ctx { struct object_id *oid; char **filename; @@ -161,43 +111,40 @@ static int get_readme_oid_cb(const struct object_id *oid, struct strbuf *base, struct get_readme_oid_ctx *ctx = (struct get_readme_oid_ctx*)cbdata; - // TODO: make readme.md configurable - const size_t readme_names_count = 2; + // 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); - - bool match_base = false; - if (ctx->path == NULL) - match_base = base->len == 0; - else if (strncmp(buffer.buf, ctx->path, buffer.len > 0 ? buffer.len - 1 : 0) == 0) - match_base = true; - strbuf_addstr(&buffer, pathname); - - bool match_path = false; - if (ctx->path == NULL) - match_path = false; - else if (strcmp(buffer.buf, ctx->path) == 0) - match_path = true; + + 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_base && strcasecmp(pathname, readme_names[i]) == 0) { - *(ctx->oid) = *oid; - *(ctx->filename) = xstrdup(pathname); + 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; } - else if (match_path) { - return READ_TREE_RECURSIVE; - } } - return 0; + 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){ @@ -210,6 +157,22 @@ bool get_readme_oid(struct tree *tree, struct pathspec *paths, struct object_id 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; @@ -225,6 +188,22 @@ void cgit_print_repo_readme_no_layout(struct tree *tree, struct pathspec *paths) 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_no_layout(const struct tree *tree, struct pathspec *paths) // { // if (ctx.repo->readme.nr) { diff --git a/ui-summary.h b/ui-summary.h index c27358d..4ccac56 100644 --- a/ui-summary.h +++ b/ui-summary.h @@ -2,7 +2,8 @@ #define UI_SUMMARY_H extern void cgit_print_summary(void); -extern void cgit_print_repo_readme(const char *path); extern void cgit_print_repo_readme_no_layout(struct tree *tree, struct pathspec *paths); +extern void cgit_print_repo_readme(const char *path, struct object_id *oid); +extern bool cgit_has_readme(void); #endif /* UI_SUMMARY_H */ |
