"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Tracey Emery <tracey@traceyemery.net>
Subject:
Re: gotwebd: add patch action
To:
Omar Polo <op@omarpolo.com>
Cc:
gameoftrees@openbsd.org
Date:
Fri, 1 Dec 2023 12:31:03 -0700

Download raw body.

Thread
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;
>