Download raw body.
gotwebd: add patch action
On Fri, Dec 01, 2023 at 07:47:58PM +0100, Omar Polo wrote:
> This adds a "patch" action to serve diffs as plain text over http(s).
> There's an example here:
>
> https://got.omarpolo.com/?action=patch&commit=446026cb9332485a4c570afd42fb493d451f7251&headref=HEAD&path=got.git
>
> I personally find it useful to have diffs served via http, especially
> when dealing with ports.
>
> concerns/comments/ok?
Yes please. Ok! This is very handy.
>
> diff /home/op/w/got
> commit - 4ba8b606a0a1ebe0d9a9daf6909948315c313d36
> path + /home/op/w/got
> blob - 45a8a36ea39f6f705bfc81c145d550389dd82872
> file + gotwebd/got_operations.c
> --- gotwebd/got_operations.c
> +++ gotwebd/got_operations.c
> @@ -259,7 +259,7 @@ got_get_repo_commit(struct request *c, struct repo_com
> if (error)
> return error;
>
> - if (qs->action == DIFF) {
> + if (qs->action == DIFF || qs->action == PATCH) {
> parent_id = STAILQ_FIRST(
> got_object_commit_get_parent_ids(commit));
> if (parent_id != NULL) {
> blob - e5f7034e08396bd55ab20a409d6dbd8d8acf4c88
> file + gotwebd/gotweb.c
> --- gotwebd/gotweb.c
> +++ gotwebd/gotweb.c
> @@ -72,6 +72,7 @@ static const struct action_keys action_keys[] = {
> { "diff", DIFF },
> { "error", ERR },
> { "index", INDEX },
> + { "patch", PATCH },
> { "summary", SUMMARY },
> { "tag", TAG },
> { "tags", TAGS },
> @@ -187,7 +188,8 @@ gotweb_process_request(struct request *c)
> */
>
> if (qs->action == BLAME || qs->action == BLOB ||
> - qs->action == BLOBRAW || qs->action == DIFF) {
> + qs->action == BLOBRAW || qs->action == DIFF ||
> + qs->action == PATCH) {
> if (qs->commit == NULL) {
> error = got_error(GOT_ERR_BAD_QUERYSTRING);
> goto err;
> @@ -314,6 +316,21 @@ gotweb_process_request(struct request *c)
> return;
> gotweb_render_page(c->tp, gotweb_render_index);
> return;
> + case PATCH:
> + error = got_get_repo_commits(c, 1);
> + if (error) {
> + log_warnx("%s: %s", __func__, error->msg);
> + goto err;
> + }
> + error = got_open_diff_for_output(&c->t->fp, c);
> + if (error) {
> + log_warnx("%s: %s", __func__, error->msg);
> + goto err;
> + }
> + if (gotweb_reply(c, 200, "text/plain", NULL) == -1)
> + return;
> + gotweb_render_patch(c->tp);
> + return;
> case RSS:
> error = got_get_repo_tags(c, D_MAXSLCOMMDISP);
> if (error)
> @@ -987,6 +1004,8 @@ gotweb_action_name(int action)
> return "err";
> case INDEX:
> return "index";
> + case PATCH:
> + return "patch";
> case SUMMARY:
> return "summary";
> case TAG:
> blob - 8005d4db4e8e1da67b226c26b8e1640b5c42645d
> file + gotwebd/gotwebd.h
> --- gotwebd/gotwebd.h
> +++ gotwebd/gotwebd.h
> @@ -436,6 +436,7 @@ enum query_actions {
> DIFF,
> ERR,
> INDEX,
> + PATCH,
> SUMMARY,
> TAG,
> TAGS,
> @@ -493,6 +494,7 @@ int gotweb_render_diff(struct template *);
> int gotweb_render_branches(struct template *, struct got_reflist_head *);
> int gotweb_render_summary(struct template *);
> int gotweb_render_blame(struct template *);
> +int gotweb_render_patch(struct template *);
> int gotweb_render_rss(struct template *);
>
> /* parse.y */
> blob - bac391d8a08e90c6c0b28bba4f935029591ab0c8
> file + gotwebd/pages.tmpl
> --- gotwebd/pages.tmpl
> +++ gotwebd/pages.tmpl
> @@ -346,7 +346,7 @@ nextsep(char *s, char **t)
> struct querystring *qs = c->t->qs;
> struct repo_commit *rc;
> struct repo_dir *repo_dir = t->repo_dir;
> - struct gotweb_url diff_url, tree_url;
> + struct gotweb_url diff_url, patch_url, tree_url;
> char *tmp;
>
> diff_url = (struct gotweb_url){
> @@ -356,6 +356,13 @@ nextsep(char *s, char **t)
> .path = repo_dir->name,
> .headref = qs->headref,
> };
> + patch_url = (struct gotweb_url){
> + .action = PATCH,
> + .index_page = -1,
> + .page = -1,
> + .path = repo_dir->name,
> + .headref = qs->headref,
> + };
> tree_url = (struct gotweb_url){
> .action = TREE,
> .index_page = -1,
> @@ -371,6 +378,7 @@ nextsep(char *s, char **t)
> {{ tailq-foreach rc &t->repo_commits entry }}
> {!
> diff_url.commit = rc->commit_id;
> + patch_url.commit = rc->commit_id;
> tree_url.commit = rc->commit_id;
>
> tmp = strchr(rc->committer, '<');
> @@ -405,6 +413,8 @@ nextsep(char *s, char **t)
> <div class="navs">
> <a href="{{ render gotweb_render_url(tp->tp_arg, &diff_url) }}">diff</a>
> {{ " | " }}
> + <a href="{{ render gotweb_render_url(tp->tp_arg, &patch_url) }}">patch</a>
> + {{ " | " }}
> <a href="{{ render gotweb_render_url(tp->tp_arg, &tree_url) }}">tree</a>
> </div>
> </div>
> @@ -479,7 +489,7 @@ nextsep(char *s, char **t)
> struct transport *t = c->t;
> struct repo_dir *repo_dir = t->repo_dir;
> struct repo_commit *rc;
> - struct gotweb_url diff, tree;
> + struct gotweb_url diff, patch, tree;
>
> diff = (struct gotweb_url){
> .action = DIFF,
> @@ -487,6 +497,12 @@ nextsep(char *s, char **t)
> .page = -1,
> .path = repo_dir->name,
> };
> + patch = (struct gotweb_url){
> + .action = PATCH,
> + .index_page = -1,
> + .page = -1,
> + .path = repo_dir->name,
> + };
> tree = (struct gotweb_url){
> .action = TREE,
> .index_page = -1,
> @@ -501,6 +517,7 @@ nextsep(char *s, char **t)
> {{ tailq-foreach rc &t->repo_commits entry }}
> {!
> diff.commit = rc->commit_id;
> + patch.commit = rc->commit_id;
> tree.commit = rc->commit_id;
> !}
> <div class="page_header_wrapper">
> @@ -528,6 +545,8 @@ nextsep(char *s, char **t)
> <div class="navs">
> <a href="{{ render gotweb_render_url(c, &diff) }}">diff</a>
> {{ " | " }}
> + <a href="{{ render gotweb_render_url(c, &patch) }}">patch</a>
> + {{ " | " }}
> <a href="{{ render gotweb_render_url(c, &tree) }}">tree</a>
> </div>
> </div>
> @@ -989,7 +1008,7 @@ nextsep(char *s, char **t)
> struct transport *t = c->t;
> struct got_reflist_head *refs = &t->refs;
> !}
> -<dl id="summary_wrapper">
> +<dl id="summary_wrapper" class="page_header_wrapper">
> {{ if srv->show_repo_description }}
> <dt>Description:</dt>
> <dd>{{ t->repo_dir->description }}</dd>
> @@ -1118,6 +1137,39 @@ nextsep(char *s, char **t)
> </div>
> {{ end }}
>
> +{{ define gotweb_render_patch(struct template *tp) }}
> +{!
> + struct request *c = tp->tp_arg;
> + struct transport *t = c->t;
> + struct repo_commit *rc = TAILQ_FIRST(&t->repo_commits);
> + struct tm tm;
> + char buf[BUFSIZ], datebuf[64];
> + size_t r;
> +
> + if (gmtime_r(&rc->committer_time, &tm) == NULL ||
> + strftime(datebuf, sizeof(datebuf), "%a %b %d %T %Y UTC", &tm) == 0)
> + return (-1);
> +!}
> +commit {{ rc->commit_id }} {{ "\n" }}
> +from: {{ rc->author | unsafe }} {{ "\n" }}
> +{{ if strcmp(rc->committer, rc->author) != 0 }}
> +via: {{ rc->committer | unsafe }} {{ "\n" }}
> +{{ end }}
> +date: {{ datebuf }} {{ "\n" }}
> +{{ "\n" }}
> +{{ rc->commit_msg | unsafe }} {{ "\n" }}
> +{!
> + if (template_flush(tp) == -1)
> + return (-1);
> + for (;;) {
> + r = fread(buf, 1, sizeof(buf), t->fp);
> + if (fcgi_write(c, buf, r) == -1 ||
> + r != sizeof(buf))
> + break;
> + }
> +!}
> +{{ end }}
> +
> {{ define gotweb_render_rss(struct template *tp) }}
> {!
> struct request *c = tp->tp_arg;
>
gotwebd: add patch action