[PATCH 2/3] mailinfo: collect commit metadata from mail

From: Vegard Nossum
Date: Tue Oct 15 2019 - 20:04:08 EST


Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxxx>
---
commit 51bb531eb57320caf3761680ebf77c25b89b3719
tree f3a3141f7d3f706d8ca60cdc1e1cde5aa2cc927a
parent 622a0469a4970c5daac0c0323e2d6a77b3bebbdb
author Vegard Nossum <vegard.nossum@xxxxxxxxxx> 1571184248 +0200
committer Vegard Nossum <vegard.nossum@xxxxxxxxxx> 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


--------------8457B549DA2D505D3C75C377
Content-Type: text/x-patch;
name="0003-am-add-exact.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0003-am-add-exact.patch"