commit 553d83475bd124e7e5ba693c5ae9313d21d2139b from: Omar Polo date: Thu Mar 28 16:32:40 2024 UTC got-notify-http: handle new tags 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