From 51bb531eb57320caf3761680ebf77c25b89b3719 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Wed, 16 Oct 2019 02:04:08 +0200 Subject: [PATCH 2/3] mailinfo: collect commit metadata from mail Signed-off-by: Vegard Nossum --- commit 51bb531eb57320caf3761680ebf77c25b89b3719 tree f3a3141f7d3f706d8ca60cdc1e1cde5aa2cc927a parent 622a0469a4970c5daac0c0323e2d6a77b3bebbdb author Vegard Nossum 1571184248 +0200 committer Vegard Nossum 1571219301 +0200 --- builtin/am.c | 2 +- builtin/mailinfo.c | 11 +++++++--- mailinfo.c | 55 +++++++++++++++++++++++++++++++++++++++++++++- mailinfo.h | 4 +++- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 8181c2aef3..4190383bba 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1159,7 +1159,7 @@ static int parse_mail(struct am_state *state, const char *mail) mi.input = xfopen(mail, "r"); mi.output = xfopen(am_path(state, "info"), "w"); - if (mailinfo(&mi, am_path(state, "msg"), am_path(state, "patch"))) + if (mailinfo(&mi, am_path(state, "msg"), am_path(state, "patch"), am_path(state, "meta"))) die("could not parse patch"); fclose(mi.input); diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index cfb667a594..f3f9aabd97 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -16,7 +16,7 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix) const char *def_charset; struct mailinfo mi; int status; - char *msgfile, *patchfile; + char *msgfile, *patchfile, *metafile; setup_mailinfo(&mi); @@ -47,7 +47,7 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix) argc--; argv++; } - if (argc != 3) + if (argc < 3 || argc > 4) usage(mailinfo_usage); mi.input = stdin; @@ -56,10 +56,15 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix) msgfile = prefix_filename(prefix, argv[1]); patchfile = prefix_filename(prefix, argv[2]); - status = !!mailinfo(&mi, msgfile, patchfile); + metafile = NULL; + if (argc == 4) + metafile = prefix_filename(prefix, argv[3]); + + status = !!mailinfo(&mi, msgfile, patchfile, metafile); clear_mailinfo(&mi); free(msgfile); free(patchfile); + free(metafile); return status; } diff --git a/mailinfo.c b/mailinfo.c index b395adbdf2..50e2c685df 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -825,6 +825,40 @@ static int handle_commit_msg(struct mailinfo *mi, struct strbuf *line) return 0; } +/* + * returns non-0 when we're done handling metadata + */ +static int handle_meta(struct mailinfo *mi, const struct strbuf *line) +{ + if (mi->meta_stage == 0) { + /* + * Swallow the first patch break and continue handling meta + */ + if (patchbreak(line)) { + ++mi->meta_stage; + return 0; + } + + return 1; + } + + if (mi->meta_stage == 1) { + /* + * Check that the first line is "commit ", punt if not + */ + if (!starts_with(line->buf, "commit ")) + return 1; + + ++mi->meta_stage; + } + + if (patchbreak(line)) + return 1; + + strbuf_addbuf(&mi->meta_text, line); + return 0; +} + static void handle_patch(struct mailinfo *mi, const struct strbuf *line) { fwrite(line->buf, 1, line->len, mi->patchfile); @@ -840,6 +874,11 @@ static void handle_filter(struct mailinfo *mi, struct strbuf *line) mi->filter_stage++; /* fallthrough */ case 1: + if (!handle_meta(mi, line)) + break; + mi->filter_stage++; + /* fallthrough */ + case 2: handle_patch(mi, line); break; } @@ -1145,9 +1184,10 @@ static void handle_info(struct mailinfo *mi) fprintf(mi->output, "\n"); } -int mailinfo(struct mailinfo *mi, const char *msg, const char *patch) +int mailinfo(struct mailinfo *mi, const char *msg, const char *patch, const char *meta) { FILE *cmitmsg; + FILE *metafile; int peek; struct strbuf line = STRBUF_INIT; @@ -1163,6 +1203,14 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch) return -1; } + metafile = fopen(meta, "w"); + if (!metafile) { + perror(meta); + fclose(mi->patchfile); + fclose(cmitmsg); + return -1; + } + mi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data))); mi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data))); @@ -1184,6 +1232,9 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch) fclose(cmitmsg); fclose(mi->patchfile); + fwrite(mi->meta_text.buf, 1, mi->meta_text.len, metafile); + fclose(metafile); + handle_info(mi); strbuf_release(&line); return mi->input_error; @@ -1210,8 +1261,10 @@ void setup_mailinfo(struct mailinfo *mi) strbuf_init(&mi->email, 0); strbuf_init(&mi->charset, 0); strbuf_init(&mi->log_message, 0); + strbuf_init(&mi->meta_text, 0); strbuf_init(&mi->inbody_header_accum, 0); mi->header_stage = 1; + mi->meta_stage = 0; mi->use_inbody_headers = 1; mi->content_top = mi->content; git_config(git_mailinfo_config, mi); diff --git a/mailinfo.h b/mailinfo.h index 79b1d6774e..89386103bd 100644 --- a/mailinfo.h +++ b/mailinfo.h @@ -31,16 +31,18 @@ struct mailinfo { int patch_lines; int filter_stage; /* still reading log or are we copying patch? */ int header_stage; /* still checking in-body headers? */ + int meta_stage; struct strbuf inbody_header_accum; struct strbuf **p_hdr_data; struct strbuf **s_hdr_data; struct strbuf log_message; + struct strbuf meta_text; int input_error; }; void setup_mailinfo(struct mailinfo *); -int mailinfo(struct mailinfo *, const char *msg, const char *patch); +int mailinfo(struct mailinfo *, const char *msg, const char *patch, const char *meta); void clear_mailinfo(struct mailinfo *); #endif /* MAILINFO_H */ -- 2.23.0.718.g3120370db8