Commit Diff


commit - 909ef56bac18cdc0d889412542697be574acfe6b
commit + ac0a4dfc3547f38c3fe0544f329f3c7bded24010
blob - e1dd226bd532d7adaf1e4712e8c13bf3cc29ffba
blob + 65830ea27b3c8094af7418498500f922ed75ecee
--- gotd/libexec/got-notify-http/got-notify-http.c
+++ gotd/libexec/got-notify-http/got-notify-http.c
@@ -149,6 +149,46 @@ json_field(FILE *fp, const char *key, const char *val,
 	fprintf(fp, "\"%s", comma ? "," : "");
 }
 
+static void
+json_author(FILE *fp, const char *type, char *address, int comma)
+{
+	char	*gt, *lt, *at, *email, *endname;
+
+	fprintf(fp, "\"%s\":{", type);
+
+	gt = strchr(address, '<');
+	if (gt != NULL) {
+		/* long format, e.g. "Omar Polo <op@openbsd.org>" */
+
+		json_field(fp, "full", address, 1);
+
+		endname = gt;
+		while (endname > address && endname[-1] == ' ')
+			endname--;
+
+		*endname = '\0';
+		json_field(fp, "name", address, 1);
+
+		email = gt + 1;
+		lt = strchr(email, '>');
+		if (lt)
+			*lt = '\0';
+
+		json_field(fp, "mail", email, 1);
+
+		at = strchr(email, '@');
+		if (at)
+			*at = '\0';
+
+		json_field(fp, "user", email, 0);
+	} else {
+		/* short format only shows the username */
+		json_field(fp, "user", address, 0);
+	}
+
+	fprintf(fp, "}%s", comma ? "," : "");
+}
+
 static int
 jsonify_short(FILE *fp)
 {
@@ -187,9 +227,9 @@ jsonify_short(FILE *fp)
 
 		fprintf(fp, "{\"short\":true,");
 		json_field(fp, "id", id, 1);
-		json_field(fp, "author", author, 1);
+		json_author(fp, "committer", author, 1);
 		json_field(fp, "date", date, 1);
-		json_field(fp, "message", message, 0);
+		json_field(fp, "short_message", message, 0);
 		fprintf(fp, "}");
 	}
 
@@ -206,6 +246,7 @@ static int
 jsonify(FILE *fp)
 {
 	const char	*errstr;
+	char		*author = NULL;
 	char		*l;
 	char		*line = NULL;
 	size_t		 linesize = 0;
@@ -254,7 +295,13 @@ jsonify(FILE *fp)
 			if (strncmp(l, "from: ", 6) != 0)
 				errx(1, "unexpected from line");
 			l += 6;
-			json_field(fp, "author", l, 1);
+
+			author = strdup(l);
+			if (author == NULL)
+				err(1, "strdup");
+
+			json_author(fp, "author", l, 1);
+
 			phase = P_VIA;
 			break;
 
@@ -262,10 +309,17 @@ jsonify(FILE *fp)
 			/* optional */
 			if (!strncmp(l, "via: ", 5)) {
 				l += 5;
-				json_field(fp, "via", l, 1);
+				json_author(fp, "committer", l, 1);
 				phase = P_DATE;
 				break;
 			}
+
+			if (author == NULL) /* impossible */
+				err(1, "from not specified");
+			json_author(fp, "committer", author, 1);
+			free(author);
+			author = NULL;
+
 			phase = P_DATE;
 			/* fallthrough */
 
@@ -313,7 +367,6 @@ jsonify(FILE *fp)
 			if (errstr)
 				errx(1, "message len is %s: %s", errstr, l);
 
-			fprintf(fp, "\"message\":\"");
 			phase = P_MSG;
 			break;
 
@@ -329,14 +382,21 @@ jsonify(FILE *fp)
 			 * tolerate one byte less than advertised.
 			 */
 			if (*l == ' ') {
-				escape(fp, l + 1); /* skip leading space */
+				l++; /* skip leading space */
+				linelen--;
 
-				/* avoid pre-pending \n to the commit msg */
-				msgwrote += linelen - 1;
-				if (msgwrote != 0)
+				if (msgwrote == 0 && linelen != 0) {
+					json_field(fp, "short_message", l, 1);
+					fprintf(fp, "\"message\":\"");
+					escape(fp, l);
+					escape(fp, "\n");
+					msgwrote += linelen;
+				} else if (msgwrote != 0) {
+					escape(fp, l);
 					escape(fp, "\n");
+				}
 			}
-			msglen -= linelen;
+			msglen -= linelen + 1;
 			if (msglen <= 1) {
 				fprintf(fp, "\",");
 				msgwrote = 0;
blob - f52fcec4add98bdb2e991b6ef2ce5efd55a54784
blob + 51fc31fca5b661529114910cf87eed04f5611301
--- regress/gotd/http_notification.sh
+++ regress/gotd/http_notification.sh
@@ -62,8 +62,20 @@ test_file_changed() {
 	{"notifications":[{
 		"short":false,
 		"id":"$commit_id",
-		"author":"$GOT_AUTHOR",
+		"author":{
+			"full":"$GOT_AUTHOR",
+			"name":"$GIT_AUTHOR_NAME",
+			"mail":"$GIT_AUTHOR_EMAIL",
+			"user":"$GOT_AUTHOR_11"
+		},
+		"committer":{
+			"full":"$GOT_AUTHOR",
+			"name":"$GIT_AUTHOR_NAME",
+			"mail":"$GIT_AUTHOR_EMAIL",
+			"user":"$GOT_AUTHOR_11"
+		},
 		"date":"$d",
+		"short_message":"make changes",
 		"message":"make changes\n",
 		"diffstat":{},
 		"changes":{}
@@ -131,8 +143,20 @@ test_bad_utf8() {
 	{"notifications":[{
 		"short":false,
 		"id":"$commit_id",
-		"author":"$GOT_AUTHOR",
+		"author":{
+			"full":"$GOT_AUTHOR",
+			"name":"$GIT_AUTHOR_NAME",
+			"mail":"$GIT_AUTHOR_EMAIL",
+			"user":"$GOT_AUTHOR_11"
+		},
+		"committer":{
+			"full":"$GOT_AUTHOR",
+			"name":"$GIT_AUTHOR_NAME",
+			"mail":"$GIT_AUTHOR_EMAIL",
+			"user":"$GOT_AUTHOR_11"
+		},
 		"date":"$d",
+		"short_message":"make\uFFFD\uFFFDchanges",
 		"message":"make\uFFFD\uFFFDchanges\n",
 		"diffstat":{},
 		"changes":{}
@@ -208,8 +232,20 @@ test_many_commits_not_summarized() {
 		{
 			"short":false,
 			"id":"$commit_id",
-			"author":"$GOT_AUTHOR",
+			"author":{
+				"full":"$GOT_AUTHOR",
+				"name":"$GIT_AUTHOR_NAME",
+				"mail":"$GIT_AUTHOR_EMAIL",
+				"user":"$GOT_AUTHOR_11"
+			},
+			"committer":{
+				"full":"$GOT_AUTHOR",
+				"name":"$GIT_AUTHOR_NAME",
+				"mail":"$GIT_AUTHOR_EMAIL",
+				"user":"$GOT_AUTHOR_11"
+			},
 			"date":"$commit_time",
+			"short_message":"make changes",
 			"message":"make changes\n",
 			"diffstat":{},
 			"changes":{}
@@ -289,9 +325,11 @@ test_many_commits_summarized() {
 		{
 			"short":true,
 			"id":"$commit_id",
-			"author":"$GOT_AUTHOR_8",
+			"committer":{
+				"user":"$GOT_AUTHOR_8"
+			},
 			"date":"$commit_time",
-			"message":"make changes"
+			"short_message":"make changes"
 		}
 		EOF
 	done >> $testroot/stdout.expected