@matheusbsbs / matheus-bagliano / commits / b82445dc27
Fork 0

ref-filter: support different email formats

Currently, ref-filter only supports printing email with angle brackets. Let's add support for two more email options. - trim : for email without angle brackets. - localpart : for the part before the @ sign out of trimmed email Mentored-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Heba Waly <heba.waly@gmail.com> Signed-off-by: Hariom Verma <hariom18599@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Hariom Verma committed Aug 21, 2020 at 21:41 UTC b82445dc2789f2046831621e6be7b2af464af6e9
3 files changed +65 -10
Documentation/git-for-each-ref.txt
+4 -1
@@ -230,7 +230,10 @@ These are intended for working on a mix of annotated and lightweight tags.
230
231 Fields that have name-email-date tuple as its value (`author`,
232 `committer`, and `tagger`) can be suffixed with `name`, `email`,
233 -and `date` to extract the named component.
233 +and `date` to extract the named component. For email fields (`authoremail`,
234 +`committeremail` and `taggeremail`), `:trim` can be appended to get the email
235 +without angle brackets, and `:localpart` to get the part before the `@` symbol
236 +out of the trimmed email.
237
238 The message in a commit or a tag object is `contents`, from which
239 `contents:<part>` can be used to extract various parts out of:
ref-filter.c
+45 -9
@@ -140,6 +140,9 @@ static struct used_atom {
140 enum { O_FULL, O_LENGTH, O_SHORT } option;
141 unsigned int length;
142 } objectname;
143 + struct email_option {
144 + enum { EO_RAW, EO_TRIM, EO_LOCALPART } option;
145 + } email_option;
146 struct refname_atom refname;
147 char *head;
148 } u;
@@ -377,6 +380,20 @@ static int objectname_atom_parser(const struct ref_format *format, struct used_a
380 return 0;
381 }
382
383 +static int person_email_atom_parser(const struct ref_format *format, struct used_atom *atom,
384 + const char *arg, struct strbuf *err)
385 +{
386 + if (!arg)
387 + atom->u.email_option.option = EO_RAW;
388 + else if (!strcmp(arg, "trim"))
389 + atom->u.email_option.option = EO_TRIM;
390 + else if (!strcmp(arg, "localpart"))
391 + atom->u.email_option.option = EO_LOCALPART;
392 + else
393 + return strbuf_addf_ret(err, -1, _("unrecognized email option: %s"), arg);
394 + return 0;
395 +}
396 +
397 static int refname_atom_parser(const struct ref_format *format, struct used_atom *atom,
398 const char *arg, struct strbuf *err)
399 {
@@ -488,15 +505,15 @@ static struct {
505 { "tag", SOURCE_OBJ },
506 { "author", SOURCE_OBJ },
507 { "authorname", SOURCE_OBJ },
491 - { "authoremail", SOURCE_OBJ },
508 + { "authoremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
509 { "authordate", SOURCE_OBJ, FIELD_TIME },
510 { "committer", SOURCE_OBJ },
511 { "committername", SOURCE_OBJ },
495 - { "committeremail", SOURCE_OBJ },
512 + { "committeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
513 { "committerdate", SOURCE_OBJ, FIELD_TIME },
514 { "tagger", SOURCE_OBJ },
515 { "taggername", SOURCE_OBJ },
499 - { "taggeremail", SOURCE_OBJ },
516 + { "taggeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
517 { "taggerdate", SOURCE_OBJ, FIELD_TIME },
518 { "creator", SOURCE_OBJ },
519 { "creatordate", SOURCE_OBJ, FIELD_TIME },
@@ -1037,16 +1054,35 @@ static const char *copy_name(const char *buf)
1054 return xstrdup("");
1055 }
1056
1040 -static const char *copy_email(const char *buf)
1057 +static const char *copy_email(const char *buf, struct used_atom *atom)
1058 {
1059 const char *email = strchr(buf, '<');
1060 const char *eoemail;
1061 if (!email)
1062 return xstrdup("");
1046 - eoemail = strchr(email, '>');
1063 + switch (atom->u.email_option.option) {
1064 + case EO_RAW:
1065 + eoemail = strchr(email, '>');
1066 + if (eoemail)
1067 + eoemail++;
1068 + break;
1069 + case EO_TRIM:
1070 + email++;
1071 + eoemail = strchr(email, '>');
1072 + break;
1073 + case EO_LOCALPART:
1074 + email++;
1075 + eoemail = strchr(email, '@');
1076 + if (!eoemail)
1077 + eoemail = strchr(email, '>');
1078 + break;
1079 + default:
1080 + BUG("unknown email option");
1081 + }
1082 +
1083 if (!eoemail)
1084 return xstrdup("");
1049 - return xmemdupz(email, eoemail + 1 - email);
1085 + return xmemdupz(email, eoemail - email);
1086 }
1087
1088 static char *copy_subject(const char *buf, unsigned long len)
@@ -1116,7 +1152,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
1152 continue;
1153 if (name[wholen] != 0 &&
1154 strcmp(name + wholen, "name") &&
1119 - strcmp(name + wholen, "email") &&
1155 + !starts_with(name + wholen, "email") &&
1156 !starts_with(name + wholen, "date"))
1157 continue;
1158 if (!wholine)
@@ -1127,8 +1163,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
1163 v->s = copy_line(wholine);
1164 else if (!strcmp(name + wholen, "name"))
1165 v->s = copy_name(wholine);
1130 - else if (!strcmp(name + wholen, "email"))
1131 - v->s = copy_email(wholine);
1166 + else if (starts_with(name + wholen, "email"))
1167 + v->s = copy_email(wholine, &used_atom[i]);
1168 else if (starts_with(name + wholen, "date"))
1169 grab_date(wholine, v, name);
1170 }
t/t6300-for-each-ref.sh
+16
@@ -125,15 +125,21 @@ test_atom head '*objecttype' ''
125 test_atom head author 'A U Thor <author@example.com> 1151968724 +0200'
126 test_atom head authorname 'A U Thor'
127 test_atom head authoremail '<author@example.com>'
128 +test_atom head authoremail:trim 'author@example.com'
129 +test_atom head authoremail:localpart 'author'
130 test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200'
131 test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200'
132 test_atom head committername 'C O Mitter'
133 test_atom head committeremail '<committer@example.com>'
134 +test_atom head committeremail:trim 'committer@example.com'
135 +test_atom head committeremail:localpart 'committer'
136 test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200'
137 test_atom head tag ''
138 test_atom head tagger ''
139 test_atom head taggername ''
140 test_atom head taggeremail ''
141 +test_atom head taggeremail:trim ''
142 +test_atom head taggeremail:localpart ''
143 test_atom head taggerdate ''
144 test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200'
145 test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200'
@@ -170,15 +176,21 @@ test_atom tag '*objecttype' 'commit'
176 test_atom tag author ''
177 test_atom tag authorname ''
178 test_atom tag authoremail ''
179 +test_atom tag authoremail:trim ''
180 +test_atom tag authoremail:localpart ''
181 test_atom tag authordate ''
182 test_atom tag committer ''
183 test_atom tag committername ''
184 test_atom tag committeremail ''
185 +test_atom tag committeremail:trim ''
186 +test_atom tag committeremail:localpart ''
187 test_atom tag committerdate ''
188 test_atom tag tag 'testtag'
189 test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200'
190 test_atom tag taggername 'C O Mitter'
191 test_atom tag taggeremail '<committer@example.com>'
192 +test_atom tag taggeremail:trim 'committer@example.com'
193 +test_atom tag taggeremail:localpart 'committer'
194 test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200'
195 test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200'
196 test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200'
@@ -564,10 +576,14 @@ test_atom refs/tags/taggerless tag 'taggerless'
576 test_atom refs/tags/taggerless tagger ''
577 test_atom refs/tags/taggerless taggername ''
578 test_atom refs/tags/taggerless taggeremail ''
579 +test_atom refs/tags/taggerless taggeremail:trim ''
580 +test_atom refs/tags/taggerless taggeremail:localpart ''
581 test_atom refs/tags/taggerless taggerdate ''
582 test_atom refs/tags/taggerless committer ''
583 test_atom refs/tags/taggerless committername ''
584 test_atom refs/tags/taggerless committeremail ''
585 +test_atom refs/tags/taggerless committeremail:trim ''
586 +test_atom refs/tags/taggerless committeremail:localpart ''
587 test_atom refs/tags/taggerless committerdate ''
588 test_atom refs/tags/taggerless subject 'Broken tag'
589