From c3e350c6e5abe887808260e3f807664946eacc4c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 24 Jun 2009 10:30:29 -0700 Subject: [PATCH] Support extracting emails from Signed-off-by lines A typical Signed-off-by footer line can be seen below in this message, and it clearly contains an email address (or at least a user@domain sort of reference to the identity). This identity may need to be parsed out of a footer line by application code, to match the Signed-off-by line back to the author or the committer of the commit, or to some external datastore. Signed-off-by: Shawn O. Pearce Signed-off-by: Robin Rosenberg --- .../org/spearce/jgit/revwalk/FooterLineTest.java | 40 ++++++++++++++++++++++ .../src/org/spearce/jgit/revwalk/FooterLine.java | 24 +++++++++++++ 2 files changed, 64 insertions(+) diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/FooterLineTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/FooterLineTest.java index 342346fd..431c1705 100644 --- a/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/FooterLineTest.java +++ b/org.spearce.jgit.test/tst/org/spearce/jgit/revwalk/FooterLineTest.java @@ -105,6 +105,7 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("Signed-off-by", f.getKey()); assertEquals("A. U. Thor ", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); } public void testSignedOffBy_OneUserWithLF() { @@ -119,6 +120,7 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("Signed-off-by", f.getKey()); assertEquals("A. U. Thor ", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); } public void testSignedOffBy_IgnoreWhitespace() { @@ -136,6 +138,7 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("Signed-off-by", f.getKey()); assertEquals("A. U. Thor ", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); } public void testEmptyValueNoLF() { @@ -150,6 +153,7 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("Signed-off-by", f.getKey()); assertEquals("", f.getValue()); + assertNull(f.getEmailAddress()); } public void testEmptyValueWithLF() { @@ -164,6 +168,7 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("Signed-off-by", f.getKey()); assertEquals("", f.getValue()); + assertNull(f.getEmailAddress()); } public void testShortKey() { @@ -178,6 +183,37 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("K", f.getKey()); assertEquals("V", f.getValue()); + assertNull(f.getEmailAddress()); + } + + public void testNonDelimtedEmail() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Acked-by: re@example.com\n"); + final List footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Acked-by", f.getKey()); + assertEquals("re@example.com", f.getValue()); + assertEquals("re@example.com", f.getEmailAddress()); + } + + public void testNotEmail() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Acked-by: Main Tain Er\n"); + final List footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Acked-by", f.getKey()); + assertEquals("Main Tain Er", f.getValue()); + assertNull(f.getEmailAddress()); } public void testSignedOffBy_ManyUsers() { @@ -197,18 +233,22 @@ public class FooterLineTest extends RepositoryTestCase { f = footers.get(0); assertEquals("Signed-off-by", f.getKey()); assertEquals("A. U. Thor ", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); f = footers.get(1); assertEquals("CC", f.getKey()); assertEquals("", f.getValue()); + assertEquals("some.mailing.list@example.com", f.getEmailAddress()); f = footers.get(2); assertEquals("Acked-by", f.getKey()); assertEquals("Some Reviewer ", f.getValue()); + assertEquals("sr@example.com", f.getEmailAddress()); f = footers.get(3); assertEquals("Signed-off-by", f.getKey()); assertEquals("Main Tain Er ", f.getValue()); + assertEquals("mte@example.com", f.getEmailAddress()); } public void testSignedOffBy_SkipNonFooter() { diff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/FooterLine.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/FooterLine.java index 1fef47dc..b28f52db 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/FooterLine.java +++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/FooterLine.java @@ -114,6 +114,30 @@ public final class FooterLine { return RawParseUtils.decode(enc, buffer, valStart, valEnd); } + /** + * Extract the email address (if present) from the footer. + *

+ * If there is an email address looking string inside of angle brackets + * (e.g. ""), the return value is the part extracted from inside the + * brackets. If no brackets are found, then {@link #getValue()} is returned + * if the value contains an '@' sign. Otherwise, null. + * + * @return email address appearing in the value of this footer, or null. + */ + public String getEmailAddress() { + final int lt = RawParseUtils.nextLF(buffer, valStart, '<'); + if (valEnd <= lt) { + final int at = RawParseUtils.nextLF(buffer, valStart, '@'); + if (valStart < at && at < valEnd) + return getValue(); + return null; + } + final int gt = RawParseUtils.nextLF(buffer, lt, '>'); + if (valEnd < gt) + return null; + return RawParseUtils.decode(enc, buffer, lt, gt - 1); + } + @Override public String toString() { return getKey() + ": " + getValue(); -- 2.11.4.GIT