aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorNitzan Gur-Furman <nitzan@google.com>2023-07-19 10:37:39 +0200
committerNitzan Gur-Furman <nitzan@google.com>2023-08-01 10:37:24 +0200
commitc353645a09b677644c55daa9dcff7df54529dc04 (patch)
treed0302970bcafa12fdf9167b0575514d895dad6e9 /org.eclipse.jgit
parentec11129b1d2ff5f7a909c05deb84e422fcd83084 (diff)
downloadjgit-c353645a09b677644c55daa9dcff7df54529dc04.tar.gz
jgit-c353645a09b677644c55daa9dcff7df54529dc04.zip
Move footer-line parsing methods from RevCommit to FooterLine
This allows extracting footers from a messages not associated with a commit. The public API of RevCommit is kept intact. Change-Id: I5809c23df7b7d49641a4be3a26d6f987d3d57c9b Bug: Google b/287891316
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java105
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java76
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java19
3 files changed, 136 insertions, 64 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
index 676573c2f2..eeaccc6d33 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
@@ -11,6 +11,9 @@
package org.eclipse.jgit.revwalk;
import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.eclipse.jgit.util.RawParseUtils;
@@ -47,6 +50,108 @@ public final class FooterLine {
}
/**
+ * Extract the footer lines from the given message.
+ *
+ * @param str
+ * the message to extract footers from.
+ * @return ordered list of footer lines; empty list if no footers found.
+ * @see RevCommit#getFooterLines()
+ */
+ public static List<FooterLine> fromMessage(
+ String str) {
+ return fromMessage(str.getBytes());
+ }
+
+ /**
+ * Extract the footer lines from the given message.
+ *
+ * @param raw
+ * the raw message to extract footers from.
+ * @return ordered list of footer lines; empty list if no footers found.
+ * @see RevCommit#getFooterLines()
+ */
+ public static List<FooterLine> fromMessage(
+ byte[] raw) {
+ int ptr = raw.length - 1;
+ while (raw[ptr] == '\n') // trim any trailing LFs, not interesting
+ ptr--;
+
+ int msgB = RawParseUtils.commitMessage(raw, 0);
+ ArrayList<FooterLine> r = new ArrayList<>(4);
+ Charset enc = RawParseUtils.guessEncoding(raw);
+ for (;;) {
+ ptr = RawParseUtils.prevLF(raw, ptr);
+ if (ptr <= msgB)
+ break; // Don't parse commit headers as footer lines.
+
+ int keyStart = ptr + 2;
+ if (raw[keyStart] == '\n')
+ break; // Stop at first paragraph break, no footers above it.
+
+ int keyEnd = RawParseUtils.endOfFooterLineKey(raw, keyStart);
+ if (keyEnd < 0)
+ continue; // Not a well formed footer line, skip it.
+
+ // Skip over the ': *' at the end of the key before the value.
+ //
+ int valStart = keyEnd + 1;
+ while (valStart < raw.length && raw[valStart] == ' ')
+ valStart++;
+
+ // Value ends at the LF, and does not include it.
+ //
+ int valEnd = RawParseUtils.nextLF(raw, valStart);
+ if (raw[valEnd - 1] == '\n')
+ valEnd--;
+
+ r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd));
+ }
+ Collections.reverse(r);
+ return r;
+ }
+
+ /**
+ * Get the values of all footer lines with the given key.
+ *
+ * @param footers
+ * list of footers to find the values in.
+ * @param keyName
+ * footer key to find values of, case-insensitive.
+ * @return values of footers with key of {@code keyName}, ordered by their
+ * order of appearance. Duplicates may be returned if the same
+ * footer appeared more than once. Empty list if no footers appear
+ * with the specified key, or there are no footers at all.
+ * @see #fromMessage
+ */
+ public static List<String> getValues(List<FooterLine> footers, String keyName) {
+ return getValues(footers, new FooterKey(keyName));
+ }
+
+ /**
+ * Get the values of all footer lines with the given key.
+ *
+ * @param footers
+ * list of footers to find the values in.
+ * @param key
+ * footer key to find values of, case-insensitive.
+ * @return values of footers with key of {@code keyName}, ordered by their
+ * order of appearance. Duplicates may be returned if the same
+ * footer appeared more than once. Empty list if no footers appear
+ * with the specified key, or there are no footers at all.
+ * @see #fromMessage
+ */
+ public static List<String> getValues(List<FooterLine> footers, FooterKey key) {
+ if (footers.isEmpty())
+ return Collections.emptyList();
+ ArrayList<String> r = new ArrayList<>(footers.size());
+ for (FooterLine f : footers) {
+ if (f.matches(key))
+ r.add(f.getValue());
+ }
+ return r;
+ }
+
+ /**
* Whether keys match
*
* @param key
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
index 4619938147..0392ea428c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
@@ -11,15 +11,13 @@
package org.eclipse.jgit.revwalk;
-import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.util.RawParseUtils.guessEncoding;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.annotations.Nullable;
@@ -484,7 +482,8 @@ public class RevCommit extends RevObject {
if (msgB < 0) {
return ""; //$NON-NLS-1$
}
- return RawParseUtils.decode(guessEncoding(), raw, msgB, raw.length);
+ return RawParseUtils.decode(guessEncoding(buffer), raw, msgB,
+ raw.length);
}
/**
@@ -510,7 +509,8 @@ public class RevCommit extends RevObject {
}
int msgE = RawParseUtils.endOfParagraph(raw, msgB);
- String str = RawParseUtils.decode(guessEncoding(), raw, msgB, msgE);
+ String str = RawParseUtils.decode(guessEncoding(buffer), raw, msgB,
+ msgE);
if (hasLF(raw, msgB, msgE)) {
str = StringUtils.replaceLineBreaksWithSpace(str);
}
@@ -562,14 +562,6 @@ public class RevCommit extends RevObject {
return RawParseUtils.parseEncoding(buffer);
}
- private Charset guessEncoding() {
- try {
- return getEncoding();
- } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
- return UTF_8;
- }
- }
-
/**
* Parse the footer lines (e.g. "Signed-off-by") for machine processing.
* <p>
@@ -592,50 +584,14 @@ public class RevCommit extends RevObject {
* @return ordered list of footer lines; empty list if no footers found.
*/
public final List<FooterLine> getFooterLines() {
- final byte[] raw = buffer;
- int ptr = raw.length - 1;
- while (raw[ptr] == '\n') // trim any trailing LFs, not interesting
- ptr--;
-
- final int msgB = RawParseUtils.commitMessage(raw, 0);
- final ArrayList<FooterLine> r = new ArrayList<>(4);
- final Charset enc = guessEncoding();
- for (;;) {
- ptr = RawParseUtils.prevLF(raw, ptr);
- if (ptr <= msgB)
- break; // Don't parse commit headers as footer lines.
-
- final int keyStart = ptr + 2;
- if (raw[keyStart] == '\n')
- break; // Stop at first paragraph break, no footers above it.
-
- final int keyEnd = RawParseUtils.endOfFooterLineKey(raw, keyStart);
- if (keyEnd < 0)
- continue; // Not a well formed footer line, skip it.
-
- // Skip over the ': *' at the end of the key before the value.
- //
- int valStart = keyEnd + 1;
- while (valStart < raw.length && raw[valStart] == ' ')
- valStart++;
-
- // Value ends at the LF, and does not include it.
- //
- int valEnd = RawParseUtils.nextLF(raw, valStart);
- if (raw[valEnd - 1] == '\n')
- valEnd--;
-
- r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd));
- }
- Collections.reverse(r);
- return r;
+ return FooterLine.fromMessage(buffer);
}
/**
* Get the values of all footer lines with the given key.
*
* @param keyName
- * footer key to find values of, case insensitive.
+ * footer key to find values of, case-insensitive.
* @return values of footers with key of {@code keyName}, ordered by their
* order of appearance. Duplicates may be returned if the same
* footer appeared more than once. Empty list if no footers appear
@@ -643,30 +599,22 @@ public class RevCommit extends RevObject {
* @see #getFooterLines()
*/
public final List<String> getFooterLines(String keyName) {
- return getFooterLines(new FooterKey(keyName));
+ return FooterLine.getValues(getFooterLines(), keyName);
}
/**
* Get the values of all footer lines with the given key.
*
- * @param keyName
- * footer key to find values of, case insensitive.
+ * @param key
+ * footer key to find values of, case-insensitive.
* @return values of footers with key of {@code keyName}, ordered by their
* order of appearance. Duplicates may be returned if the same
* footer appeared more than once. Empty list if no footers appear
* with the specified key, or there are no footers at all.
* @see #getFooterLines()
*/
- public final List<String> getFooterLines(FooterKey keyName) {
- final List<FooterLine> src = getFooterLines();
- if (src.isEmpty())
- return Collections.emptyList();
- final ArrayList<String> r = new ArrayList<>(src.size());
- for (FooterLine f : src) {
- if (f.matches(keyName))
- r.add(f.getValue());
- }
- return r;
+ public final List<String> getFooterLines(FooterKey key) {
+ return FooterLine.getValues(getFooterLines(), key);
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
index 0e8e9b3d84..1c98336b99 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
@@ -868,6 +868,25 @@ public final class RawParseUtils {
}
/**
+ * Parse the "encoding " header into a character set reference.
+ * <p>
+ * If unsuccessful, return UTF-8.
+ *
+ * @param buffer
+ * buffer to scan.
+ * @return the Java character set representation. Never null. Default to
+ * UTF-8.
+ * @see #parseEncoding(byte[])
+ */
+ public static Charset guessEncoding(byte[] buffer) {
+ try {
+ return parseEncoding(buffer);
+ } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+ return UTF_8;
+ }
+ }
+
+ /**
* Parse a name string (e.g. author, committer, tagger) into a PersonIdent.
* <p>
* Leading spaces won't be trimmed from the string, i.e. will show up in the