commit e46f587ca8c2affae88104d037a368b3802c7492 from: Tracey Emery date: Wed Jan 29 16:48:01 2020 UTC add gw_blob to increase the usefulness of gw_tree commit - c3bcdfd5079e63b840d5dc9ee58515a3144502a5 commit + e46f587ca8c2affae88104d037a368b3802c7492 blob - /dev/null blob + 12819268eddbfa9b3a5d68d8897c937bb20f7cd4 (mode 644) --- /dev/null +++ gotweb/files/cgi-bin/gw_tmpl/blob.tmpl @@ -0,0 +1,22 @@ + + + + @@title@@ + @@head@@ + + +
+ +
+ @@sitepath@@ + @@search@@ +
+
+ @@content@@ +
+ @@siteowner@@ +
+ + blob - 146401086ad20321034b022c7c92af5563e98331 blob + 353aeae3483606ed1b60e3deebe566a02d9259fe --- gotweb/files/htdocs/gotweb/gotweb.css +++ gotweb/files/htdocs/gotweb/gotweb.css @@ -586,6 +586,78 @@ body { overflow: hidden; } #blame_code { + float:left; + width: 50%; + overflow: visible; +} + +/* blob.tmpl */ + +#blob_title_wrapper { + clear: left; + float: left; + width: 100%; + background-color: LightSlateGray; + color: #ffffff; +} +#blob_title { + padding-left: 10px; + padding-top: 5px; + padding-bottom: 5px; +} +#blob_content { + clear: left; + float: left; + width: 100%; +} +#blob_header_wrapper { + float: left; + background-color: #f5fcfb; + width: 100%; +} +#blob_header { + float: left; + padding-left: 10px; + padding-top: 5px; + padding-bottom: 2px; + width: 80%; +} +#blob { + clear: left; + float: left; + margin-left: 20px; + margin-top: 20px; + margin-bottom: 20px; + font-family: monospace; + white-space: pre; + overflow: auto; +} +#blob_wrapper { + clear: left; + float: left; + width: 100%; +} +#blob_number { + float: left; + width: 3em; + overflow: hidden; +} +#blob_hash { + float: left; + width: 6em; + overflow: auto; +} +#blob_date { + float: left; + width: 7em; + overflow: auto; +} +#blob_author { + float: left; + width: 6em; + overflow: hidden; +} +#blob_code { float:left; width: 50%; overflow: visible; @@ -640,7 +712,19 @@ body { clear: left; float: left; width: 20em; + padding: 1px; } +#tree_line_blank { + float: left; + padding: 1px; + width: 8em; +} +#tree_line_navs { + float: left; + text-align: right; + padding: 1px; + width: 8em; +} /* tag.tmpl */ blob - 6c89bc761dfa6a56a8b3d2a63f102d06e125c8af blob + f1c85a76870b084cc23a41e2f8e21c246ffb73e2 --- gotweb/gotweb.c +++ gotweb/gotweb.c @@ -164,7 +164,7 @@ static char *gw_get_repo_owner(struct gw_trans *, static char *gw_get_time_str(time_t, int); static const struct got_error *gw_get_repo_age(char **, struct gw_trans *, char *, char *, int); -static char *gw_get_file_blame(struct gw_trans *); +static char *gw_get_file_blame_blob(struct gw_trans *); static char *gw_get_repo_tree(struct gw_trans *); static char *gw_get_diff(struct gw_trans *, struct gw_header *); @@ -209,6 +209,7 @@ static const struct got_error* gw_load_got_path(struc static const struct got_error* gw_parse_querystring(struct gw_trans *); static const struct got_error* gw_blame(struct gw_trans *); +static const struct got_error* gw_blob(struct gw_trans *); static const struct got_error* gw_diff(struct gw_trans *); static const struct got_error* gw_index(struct gw_trans *); static const struct got_error* gw_commits(struct gw_trans *); @@ -226,6 +227,7 @@ struct gw_query_action { enum gw_query_actions { GW_BLAME, + GW_BLOB, GW_BRIEFS, GW_COMMITS, GW_DIFF, @@ -238,6 +240,7 @@ enum gw_query_actions { static struct gw_query_action gw_query_funcs[] = { { GW_BLAME, "blame", gw_blame, "gw_tmpl/blame.tmpl" }, + { GW_BLOB, "blob", gw_blob, "gw_tmpl/blob.tmpl" }, { GW_BRIEFS, "briefs", gw_briefs, "gw_tmpl/briefs.tmpl" }, { GW_COMMITS, "commits", gw_commits, "gw_tmpl/commit.tmpl" }, { GW_DIFF, "diff", gw_diff, "gw_tmpl/diff.tmpl" }, @@ -324,7 +327,7 @@ gw_blame(struct gw_trans *gw_trans) if (error) goto done; - blame_html = gw_get_file_blame(gw_trans); + blame_html = gw_get_file_blame_blob(gw_trans); if (blame_html == NULL) { blame_html = strdup(""); @@ -360,6 +363,64 @@ done: } static const struct got_error * +gw_blob(struct gw_trans *gw_trans) +{ + const struct got_error *error = NULL; + struct gw_header *header = NULL; + char *blob = NULL, *blob_html = NULL, *blob_html_disp = NULL; + enum kcgi_err kerr; + + if (pledge("stdio rpath wpath cpath proc exec sendfd unveil", + NULL) == -1) + return got_error_from_errno("pledge"); + + if ((header = gw_init_header()) == NULL) + return got_error_from_errno("malloc"); + + error = gw_apply_unveil(gw_trans->gw_dir->path, NULL); + if (error) + goto done; + + error = gw_get_header(gw_trans, header, 1); + if (error) + goto done; + + blob_html = gw_get_file_blame_blob(gw_trans); + + if (blob_html == NULL) { + blob_html = strdup(""); + if (blob_html == NULL) { + error = got_error_from_errno("strdup"); + goto done; + } + } + + if (asprintf(&blob_html_disp, blob_header, + gw_gen_age_header(gw_get_time_str(header->committer_time, TM_LONG)), + gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)), + blob_html) == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + + if (asprintf(&blob, blob_wrapper, blob_html_disp) == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + + kerr = khttp_puts(gw_trans->gw_req, blob); + if (kerr != KCGI_OK) + error = gw_kcgi_error(kerr); +done: + got_ref_list_free(&header->refs); + gw_free_headers(header); + free(blob_html_disp); + free(blob_html); + free(blob); + return error; +} + +static const struct got_error * gw_diff(struct gw_trans *gw_trans) { const struct got_error *error = NULL; @@ -593,10 +654,10 @@ gw_commits(struct gw_trans *gw_trans) } if (asprintf(&commits_html, commits_line, - gw_gen_commit_header(n_header->commit_id, + gw_gen_commit_header(n_header->commit_id, n_header->refs_str), - gw_gen_author_header(n_header->author), - gw_gen_committer_header(n_header->committer), + gw_gen_author_header(n_header->author), + gw_gen_committer_header(n_header->committer), gw_gen_age_header(gw_get_time_str(n_header->committer_time, TM_LONG)), gw_html_escape(n_header->commit_msg), commits_navs_html) == -1) { @@ -1551,8 +1612,8 @@ gw_get_diff(struct gw_trans *gw_trans, struct gw_heade FILE *f = NULL; struct got_object_id *id1 = NULL, *id2 = NULL; struct buf *diffbuf = NULL; - char *label1 = NULL, *label2 = NULL, *diff_html = NULL, *buf = NULL, - *buf_color = NULL, *n_buf = NULL, *newline = NULL; + char *label1 = NULL, *label2 = NULL, *diff_html = NULL, *buf = NULL; + char *buf_color = NULL, *n_buf = NULL, *newline = NULL; int obj_type; size_t newsize; @@ -1736,9 +1797,8 @@ gw_get_repo_tags(struct gw_trans *gw_trans, struct gw_ struct got_repository *repo = NULL; struct got_reflist_head refs; struct got_reflist_entry *re; - char *tags = NULL, *tag_row = NULL, *tags_navs_disp = NULL, - *age = NULL; - char *newline; + char *tags = NULL, *tag_row = NULL, *tags_navs_disp = NULL; + char *age = NULL, *newline; struct buf *diffbuf = NULL; size_t newsize; @@ -1978,8 +2038,7 @@ gw_get_commit(struct gw_trans *gw_trans, struct gw_hea struct got_reflist_entry *re; struct got_object_id *id2 = NULL; struct got_object_qid *parent_id; - char *refs_str = NULL, - *commit_msg = NULL, *commit_msg0; + char *refs_str = NULL, *commit_msg = NULL, *commit_msg0; /*print commit*/ SIMPLEQ_FOREACH(re, &header->refs, entry) { @@ -2315,15 +2374,15 @@ done: } static char* -gw_get_file_blame(struct gw_trans *gw_trans) +gw_get_file_blame_blob(struct gw_trans *gw_trans) { const struct got_error *error = NULL; struct got_repository *repo = NULL; struct got_object_id *obj_id = NULL; struct got_object_id *commit_id = NULL; struct got_blob_object *blob = NULL; - char *blame_html = NULL, *path = NULL, *in_repo_path = NULL, - *folder = NULL; + char *blame_html = NULL, *path = NULL, *in_repo_path = NULL; + char *folder = NULL; struct gw_blame_cb_args bca; int i, obj_type; size_t filesize; @@ -2391,6 +2450,17 @@ gw_get_file_blame(struct gw_trans *gw_trans) if (error || bca.nlines == 0) goto done; + if (gw_trans->action == GW_BLOB) { + int len; + fseek(bca.f, 0, SEEK_END); + len = ftell(bca.f) + 1; + fseek(bca.f, 0, SEEK_SET); + if ((blame_html = calloc(len, sizeof(char *))) == NULL) + goto done; + fread(blame_html, 1, len, bca.f); + goto done; + } + /* Don't include \n at EOF in the blame line count. */ if (bca.line_offsets[bca.nlines - 1] == filesize) bca.nlines--; @@ -2412,24 +2482,21 @@ gw_get_file_blame(struct gw_trans *gw_trans) error = got_blame(in_repo_path, commit_id, repo, gw_blame_cb, &bca, NULL, NULL); + if (error) + goto done; if (buf_len(bca.blamebuf) > 0) { error = buf_putc(bca.blamebuf, '\0'); blame_html = strdup(buf_get(bca.blamebuf)); } done: + free(bca.line_offsets); free(bca.blamebuf); free(in_repo_path); free(commit_id); free(obj_id); free(path); - if (blob) - error = got_object_blob_close(blob); - if (repo) - error = got_repo_close(repo); - if (error) - return NULL; - if (bca.lines) { + if (gw_trans->action != GW_BLOB && bca.lines) { for (i = 0; i < bca.nlines; i++) { struct blame_line *bline = &bca.lines[i]; free(bline->id_str); @@ -2437,11 +2504,18 @@ done: } free(bca.lines); } - free(bca.line_offsets); + if (error) + return NULL; if (bca.f && fclose(bca.f) == EOF && error == NULL) - error = got_error_from_errno("fclose"); + return NULL; + if (blob) + error = got_object_blob_close(blob); if (error) return NULL; + if (repo) + error = got_repo_close(repo); + if (error) + return NULL; else return blame_html; } @@ -2566,6 +2640,12 @@ gw_get_repo_tree(struct gw_trans *gw_trans) error = got_error_from_errno("asprintf"); goto done; } + if (asprintf(&tree_row, tree_line, class, url_html, + class) == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + } else { if (gw_trans->repo_folder != NULL) { if (asprintf(&build_folder, "%s", @@ -2578,22 +2658,29 @@ gw_get_repo_tree(struct gw_trans *gw_trans) build_folder = strdup(""); if (asprintf(&url_html, file_html, gw_trans->repo_name, - "blame", gw_trans->commit, + "blob", gw_trans->commit, got_tree_entry_get_name(te), build_folder, got_tree_entry_get_name(te), modestr) == -1) { error = got_error_from_errno("asprintf"); goto done; } + + if (asprintf(&tree_row, tree_line_with_navs, class, + url_html, class, gw_trans->repo_name, "blob", + gw_trans->commit, got_tree_entry_get_name(te), + build_folder, "blob", gw_trans->repo_name, + "blame", gw_trans->commit, + got_tree_entry_get_name(te), build_folder, + "blame") == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } } free(build_folder); if (error) goto done; - if ((asprintf(&tree_row, tree_line, class, url_html)) == -1) { - error = got_error_from_errno("asprintf"); - goto done; - } error = buf_puts(&newsize, diffbuf, tree_row); if (error) goto done; blob - 683c22af5b6a77f2b21948233534ad7ab911b4d3 blob + 47c732d635c1ea51ab78f5f2dfcce303770ce0a7 --- gotweb/gotweb_ui.h +++ gotweb/gotweb_ui.h @@ -207,6 +207,30 @@ char *briefs_navs = "diff | " \ "tree"; + +/* blob.tmpl */ + +char *blob_wrapper = + "
" \ + "
Blob
" \ + "
%s
"; + +char *blob_header = + "
" \ + "
%s%s
" \ + "
" \ + "
" \ + "
%s
" \ + ""; + +char *blob_line = + "
" \ + "
%.*d
" \ + "
%.8s
" \ + "
%s
" \ + "
%-8s
" \ + "
%s
" \ + "
"; /* blame.tmpl */ @@ -250,8 +274,18 @@ char *tree_header = char *tree_line = "
" \ "
%s
" \ + "
 
" \ "
"; +char *tree_line_with_navs = + "
" \ + "
%s
" \ + "
" \ + "%s | " \ + "%s" \ + "
" \ + "
"; + /* tag.tmpl */ char *tag_wrapper =