Commit Diff


commit - 7a0952773e482459a286e0128d0a192fcaaeb8c9
commit + 553d83475bd124e7e5ba693c5ae9313d21d2139b
blob - ce42aab3943c0acfce6889c037c435bac0241964
blob + 0df13f74c2b58b6d516bbd7282d589e589b61513
--- gotd/libexec/got-notify-http/got-notify-http.c
+++ gotd/libexec/got-notify-http/got-notify-http.c
@@ -428,6 +428,135 @@ jsonify_commit(FILE *fp, char **line, ssize_t *linesiz
 }
 
 static int
+jsonify_tag(FILE *fp, char **line, ssize_t *linesize)
+{
+	const char	*errstr;
+	char		*l;
+	ssize_t		 linelen;
+	int		 msglen = 0, msgwrote = 0;
+	int		 done = 0;
+	enum {
+		P_FROM,
+		P_DATE,
+		P_OBJECT,
+		P_MSGLEN,
+		P_MSG,
+	} phase = P_FROM;
+
+	l = *line;
+	if (strncmp(l, "tag ", 4) != 0)
+		errx(1, "%s: unexpected line: %s", __func__, l);
+	l += 4;
+
+	fputc('{', fp);
+	json_field(fp, "type", "tag", 1);
+	json_field(fp, "tag", l, 1);
+
+	while (!done) {
+		if ((linelen = getline(line, linesize, stdin)) == -1)
+			break;
+
+		if ((*line)[linelen - 1] == '\n')
+			(*line)[--linelen] = '\0';
+
+		l = *line;
+		switch (phase) {
+		case P_FROM:
+			if (strncmp(l, "from: ", 6) != 0)
+				errx(1, "unexpected from line");
+			l += 6;
+
+			json_author(fp, "tagger", l, 1);
+
+			phase = P_DATE;
+			break;
+
+		case P_DATE:
+			/* optional */
+			if (!strncmp(l, "date: ", 6)) {
+				l += 6;
+				json_field(fp, "date", l, 1);
+				phase = P_OBJECT;
+				break;
+			}
+			phase = P_OBJECT;
+			/* fallthough */
+
+		case P_OBJECT:
+			/* optional */
+			if (!strncmp(l, "object: ", 8)) {
+				char *type, *id;
+
+				l += 8;
+				type = l;
+				id = strchr(l, ' ');
+				if (id == NULL)
+					errx(1, "malformed tag object line");
+				*id++ = '\0';
+
+				fputs("\"object\":{", fp);
+				json_field(fp, "type", type, 1);
+				json_field(fp, "id", id, 0);
+				fputs("},", fp);
+
+				phase = P_MSGLEN;
+				break;
+			}
+			phase = P_MSGLEN;
+			/* fallthrough */
+
+		case P_MSGLEN:
+			if (strncmp(l, "messagelen: ", 12) != 0)
+				errx(1, "unexpected messagelen line");
+			l += 12;
+			msglen = strtonum(l, 1, INT_MAX, &errstr);
+			if (errstr)
+				errx(1, "message len is %s: %s", errstr, l);
+
+			msglen++;
+
+			phase = P_MSG;
+			break;
+
+		case P_MSG:
+			if (*l == ' ') {
+				l++; /* skip leading space */
+				linelen--;
+
+				if (msgwrote == 0 && linelen != 0) {
+					fprintf(fp, "\"message\":\"");
+					escape(fp, l);
+					escape(fp, "\n");
+					msgwrote += linelen;
+				} else if (msgwrote != 0) {
+					escape(fp, l);
+					escape(fp, "\n");
+				}
+			}
+			msglen -= linelen + 1;
+			if (msglen <= 0) {
+				fprintf(fp, "\"");
+				msgwrote = 0;
+				done = 1;
+				break;
+			}
+			break;
+
+		default:
+			/* unreachable */
+			errx(1, "unexpected line: %s", *line);
+		}
+	}
+	if (ferror(stdin))
+		err(1, "getline");
+	if (!done)
+		errx(1, "unexpected EOF");
+	fputc('}', fp);
+
+	return 0;
+}
+
+static int
 jsonify(FILE *fp)
 {
 	char		*line = NULL;
@@ -465,6 +594,12 @@ jsonify(FILE *fp)
 			continue;
 		}
 
+		if (strncmp(line, "tag ", 4) == 0) {
+			if (jsonify_tag(fp, &line, &linesize) == -1)
+				err(1, "jsonify_tag");
+			continue;
+		}
+
 		errx(1, "unexpected line: %s", line);
 	}
 	if (ferror(stdin))
blob - 8bf420b1b2ad5811471bcfd0160cda044cdb7cbf
blob + cea0c1eae414b659ded62ae15edaa4f32d24ab37
--- regress/gotd/http_notification.sh
+++ regress/gotd/http_notification.sh
@@ -478,6 +478,71 @@ test_branch_removed() {
 		"type":"branch-deleted",
 		"ref":"refs/heads/newbranch",
 		"id":"$commit_id"
+	}]}
+	.
+	,j
+	w
+	EOF
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	test_done "$testroot" "$ret"
+}
+
+test_tag_created() {
+	local testroot=`test_init tag_created 1`
+
+	got clone -a -q ${GOTD_TEST_REPO_URL} $testroot/repo-clone
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got clone failed unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	got tag -r $testroot/repo-clone -m "new tag" 1.0 > /dev/null
+	local commit_id=`git_show_head $testroot/repo-clone`
+	local tagger_time=`git_show_tagger_time $testroot/repo-clone 1.0`
+
+	timeout 5 ./http-server -p "$GOTD_TEST_HTTP_PORT" \
+	    >$testroot/stdout &
+
+	got send -t 1.0 -q -r $testroot/repo-clone
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got send failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	wait %1 # wait for the http "server"
+
+	d=`date -u -r $tagger_time +"%a %b %e %X %Y UTC"`
+
+	touch "$testroot/stdout.expected"
+	ed -s "$testroot/stdout.expected" <<-EOF
+	a
+	{"notifications":[{
+		"type":"tag",
+		"tag":"refs/tags/1.0",
+		"tagger":{
+			"full":"$GOT_AUTHOR",
+			"name":"$GIT_AUTHOR_NAME",
+			"mail":"$GIT_AUTHOR_EMAIL",
+			"user":"$GOT_AUTHOR_11"
+		},
+		"date":"$d",
+		"object":{
+			"type":"commit",
+			"id":"$commit_id"
+		},
+		"message":"new tag\n\n"
 	}]}
 	.
 	,j
@@ -502,3 +567,4 @@ run_test test_many_commits_not_summarized
 run_test test_many_commits_summarized
 run_test test_branch_created
 run_test test_branch_removed
+run_test test_tag_created