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
{
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,
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);
if (errstr)
errx(1, "message len is %s: %s", errstr, l);
+ msglen++;
+
phase = P_MSG;
break;
* 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;
err(1, "getline");
if (!done)
errx(1, "unexpected EOF");
+ fputc('}', fp);
return 0;
}
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
"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
"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
"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
"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
+ }
+ }
}
]}
.