commit 763b7f49146da1df5142d9f88651f4516b1d1a88 from: Omar Polo date: Thu Mar 28 18:14:08 2024 UTC got-notify-http: parse diffstat; adjust tag/commit commit - cd18253299922842254cc506eb7fa85be402962d commit + 763b7f49146da1df5142d9f88651f4516b1d1a88 blob - 0df13f74c2b58b6d516bbd7282d589e589b61513 blob + 4877c0752c043c855ee2cdcfefe71db2894b1bb7 --- gotd/libexec/got-notify-http/got-notify-http.c +++ gotd/libexec/got-notify-http/got-notify-http.c @@ -254,10 +254,12 @@ jsonify_commit(FILE *fp, char **line, ssize_t *linesiz { const char *errstr; char *author = NULL; + char *filename, *t; char *l; ssize_t linelen; int parent = 0; int msglen = 0, msgwrote = 0; + int n, files = 0; int done = 0; enum { P_FROM, @@ -274,6 +276,7 @@ jsonify_commit(FILE *fp, char **line, ssize_t *linesiz if (strncmp(l, "commit ", 7) != 0) errx(1, "%s: unexpected line: %s", __func__, l); l += 7; + fprintf(fp, "{\"type\":\"commit\",\"short\":false,"); json_field(fp, "id", l, 1); @@ -362,6 +365,8 @@ jsonify_commit(FILE *fp, char **line, ssize_t *linesiz if (errstr) errx(1, "message len is %s: %s", errstr, l); + msglen++; + phase = P_MSG; break; @@ -376,41 +381,151 @@ jsonify_commit(FILE *fp, char **line, ssize_t *linesiz * a \n added at the end of the message, * tolerate one byte less than advertised. */ - if (*l == ' ') { - l++; /* skip leading space */ - linelen--; + if (*l != ' ') + errx(1, "unexpected line in commit message"); - 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"); - } + l++; /* skip leading space */ + linelen--; + + 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 + 1; if (msglen <= 1) { fprintf(fp, "\","); - msgwrote = 0; phase = P_DST; + break; } break; case P_DST: - /* XXX: ignore the diffstat for now */ + if (files == 0 && !strcmp(l, " ")) + break; + + if (files == 0) + fputs("\"diffstat\":{\"files\":[", fp); + if (*l == '\0') { - fprintf(fp, "\"diffstat\":{},"); + fputs("],", fp); phase = P_SUM; break; } + + if (*l != ' ') + errx(1, "bad diffstat line"); + l++; + + if (files != 0) + fputc(',', fp); + fputc('{', fp); + + switch (*l) { + case 'A': + json_field(fp, "action", "added", 1); + break; + case 'D': + json_field(fp, "action", "deleted", 1); + break; + case 'M': + json_field(fp, "action", "modified", 1); + break; + case 'm': + json_field(fp, "action", "mode changed", 1); + break; + default: + json_field(fp, "action", "unknown", 1); + break; + } + + l++; + while (*l == ' ') + *l++ = '\0'; + if (*l == '\0') + errx(1, "invalid diffstat: no filename"); + + filename = l; + l = strrchr(l, '|'); + if (l == NULL) + errx(1, "invalid diffstat: no separator"); + t = l - 1; + while (t > filename && *t == ' ') + *t-- = '\0'; + json_field(fp, "file", filename, 1); + + l++; + while (*l == ' ') + l++; + + t = strchr(l, '+'); + if (t == NULL) + errx(1, "invalid diffstat: no added counter"); + *t++ = '\0'; + + n = strtonum(l, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "added counter is %s: %s", errstr, l); + fprintf(fp, "\"added\":%d,", n); + + l = ++t; + while (*l == ' ') + l++; + + t = strchr(l, '-'); + if (t == NULL) + errx(1, "invalid diffstat: no del counter"); + *t = '\0'; + + n = strtonum(l, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "del counter is %s: %s", errstr, l); + fprintf(fp, "\"removed\":%d", n); + + fputc('}', fp); + + files++; + break; case P_SUM: - /* XXX: ignore the sum of changes for now */ - fprintf(fp, "\"changes\":{}}"); + fputs("\"total\":{", fp); + + t = l; + l = strchr(l, ' '); + if (l == NULL) + errx(1, "missing number of additions"); + *l++ = '\0'; + + n = strtonum(t, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "add counter is %s: %s", errstr, t); + fprintf(fp, "\"added\":%d,", n); + + l = strchr(l, ','); + if (l == NULL) + errx(1, "missing number of deletions"); + l++; + while (*l == ' ') + l++; + + t = strchr(l, ' '); + if (t == NULL) + errx(1, "malformed diffstat sum line"); + *t = '\0'; + + n = strtonum(l, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "del counter is %s: %s", errstr, l); + fprintf(fp, "\"removed\":%d", n); + + fputs("}}", fp); done = 1; break; @@ -423,6 +538,7 @@ jsonify_commit(FILE *fp, char **line, ssize_t *linesiz err(1, "getline"); if (!done) errx(1, "unexpected EOF"); + fputc('}', fp); return 0; } @@ -519,24 +635,25 @@ jsonify_tag(FILE *fp, char **line, ssize_t *linesize) break; case P_MSG: - if (*l == ' ') { - l++; /* skip leading space */ - linelen--; + if (*l != ' ') + errx(1, "unexpected line in tag message"); - 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"); - } + 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) { + if (msglen <= 1) { fprintf(fp, "\""); - msgwrote = 0; done = 1; break; } blob - 45034b29f011c8d27974a7b67e86892d53a30661 blob + 2b284098386d43112d889524776e02f46e7e1331 --- regress/gotd/http_notification.sh +++ regress/gotd/http_notification.sh @@ -78,8 +78,18 @@ test_file_changed() { "date":"$d", "short_message":"make changes", "message":"make changes\n", - "diffstat":{}, - "changes":{} + "diffstat":{ + "files":[{ + "action":"modified", + "file":"alpha", + "added":1, + "removed":1 + }], + "total":{ + "added":1, + "removed":1 + } + } }]} . ,j @@ -160,8 +170,18 @@ test_bad_utf8() { "date":"$d", "short_message":"make\uFFFD\uFFFDchanges", "message":"make\uFFFD\uFFFDchanges\n", - "diffstat":{}, - "changes":{} + "diffstat":{ + "files":[{ + "action":"modified", + "file":"alpha", + "added":1, + "removed":1 + }], + "total":{ + "added":1, + "removed":1 + } + } }]} . ,j @@ -250,8 +270,18 @@ test_many_commits_not_summarized() { "date":"$commit_time", "short_message":"make changes", "message":"make changes\n", - "diffstat":{}, - "changes":{} + "diffstat":{ + "files":[{ + "action":"modified", + "file":"alpha", + "added":1, + "removed":1 + }], + "total":{ + "added":1, + "removed":1 + } + } } EOF done >> $testroot/stdout.expected @@ -425,8 +455,18 @@ test_branch_created() { "date":"$d", "short_message":"newbranch", "message":"newbranch\n", - "diffstat":{}, - "changes":{} + "diffstat":{ + "files":[{ + "action":"modified", + "file":"alpha", + "added":1, + "removed":1 + }], + "total":{ + "added":1, + "removed":1 + } + } } ]} .