Merge "ChangeNotesParser: move out logic for parsing commit message range"

This commit is contained in:
xchangcheng
2018-07-20 14:26:50 +00:00
committed by Gerrit Code Review
2 changed files with 105 additions and 44 deletions

View File

@@ -14,13 +14,17 @@
package com.google.gerrit.server.notedb;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.config.GerritServerId;
import com.google.inject.Inject;
import java.util.Date;
import java.util.Optional;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.FooterKey;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.RawParseUtils;
public class ChangeNoteUtil {
public static final FooterKey FOOTER_ASSIGNEE = new FooterKey("Assignee");
@@ -98,4 +102,87 @@ public class ChangeNoteUtil {
when,
serverIdent.getTimeZone());
}
public static Optional<CommitMessageRange> parseCommitMessageRange(RevCommit commit) {
byte[] raw = commit.getRawBuffer();
int size = raw.length;
int subjectStart = RawParseUtils.commitMessage(raw, 0);
if (subjectStart < 0 || subjectStart >= size) {
return Optional.empty();
}
int subjectEnd = RawParseUtils.endOfParagraph(raw, subjectStart);
if (subjectEnd == size) {
return Optional.empty();
}
int changeMessageStart;
if (raw[subjectEnd] == '\n') {
changeMessageStart = subjectEnd + 2; // \n\n ends paragraph
} else if (raw[subjectEnd] == '\r') {
changeMessageStart = subjectEnd + 4; // \r\n\r\n ends paragraph
} else {
return Optional.empty();
}
int ptr = size - 1;
int changeMessageEnd = -1;
while (ptr > changeMessageStart) {
ptr = RawParseUtils.prevLF(raw, ptr, '\r');
if (ptr == -1) {
break;
}
if (raw[ptr] == '\n') {
changeMessageEnd = ptr - 1;
break;
} else if (raw[ptr] == '\r') {
changeMessageEnd = ptr - 3;
break;
}
}
if (ptr <= changeMessageStart) {
return Optional.empty();
}
CommitMessageRange range =
CommitMessageRange.builder()
.subjectStart(subjectStart)
.subjectEnd(subjectEnd)
.changeMessageStart(changeMessageStart)
.changeMessageEnd(changeMessageEnd)
.build();
return Optional.of(range);
}
@AutoValue
public abstract static class CommitMessageRange {
public abstract int subjectStart();
public abstract int subjectEnd();
public abstract int changeMessageStart();
public abstract int changeMessageEnd();
public static Builder builder() {
return new AutoValue_ChangeNoteUtil_CommitMessageRange.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
abstract Builder subjectStart(int subjectStart);
abstract Builder subjectEnd(int subjectEnd);
abstract Builder changeMessageStart(int changeMessageStart);
abstract Builder changeMessageEnd(int changeMessageEnd);
abstract CommitMessageRange build();
}
}
}

View File

@@ -36,6 +36,7 @@ import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBMITTED_WI
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_TAG;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_TOPIC;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_WORK_IN_PROGRESS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.parseCommitMessageRange;
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
import static java.util.stream.Collectors.joining;
@@ -692,61 +693,34 @@ class ChangeNotesParser {
Account.Id realAccountId,
ChangeNotesCommit commit,
Timestamp ts) {
byte[] raw = commit.getRawBuffer();
int size = raw.length;
Charset enc = RawParseUtils.parseEncoding(raw);
int subjectStart = RawParseUtils.commitMessage(raw, 0);
if (subjectStart < 0 || subjectStart >= size) {
Optional<String> changeMsgString = getChangeMessageString(commit);
if (!changeMsgString.isPresent()) {
return;
}
int subjectEnd = RawParseUtils.endOfParagraph(raw, subjectStart);
if (subjectEnd == size) {
return;
}
int changeMessageStart;
if (raw[subjectEnd] == '\n') {
changeMessageStart = subjectEnd + 2; // \n\n ends paragraph
} else if (raw[subjectEnd] == '\r') {
changeMessageStart = subjectEnd + 4; // \r\n\r\n ends paragraph
} else {
return;
}
int ptr = size - 1;
int changeMessageEnd = -1;
while (ptr > changeMessageStart) {
ptr = RawParseUtils.prevLF(raw, ptr, '\r');
if (ptr == -1) {
break;
}
if (raw[ptr] == '\n') {
changeMessageEnd = ptr - 1;
break;
} else if (raw[ptr] == '\r') {
changeMessageEnd = ptr - 3;
break;
}
}
if (ptr <= changeMessageStart) {
return;
}
String changeMsgString =
RawParseUtils.decode(enc, raw, changeMessageStart, changeMessageEnd + 1);
ChangeMessage changeMessage =
new ChangeMessage(
new ChangeMessage.Key(psId.getParentKey(), commit.name()), accountId, ts, psId);
changeMessage.setMessage(changeMsgString);
changeMessage.setMessage(changeMsgString.get());
changeMessage.setTag(tag);
changeMessage.setRealAuthor(realAccountId);
allChangeMessages.add(changeMessage);
}
public static Optional<String> getChangeMessageString(ChangeNotesCommit commit) {
byte[] raw = commit.getRawBuffer();
Charset enc = RawParseUtils.parseEncoding(raw);
Optional<ChangeNoteUtil.CommitMessageRange> range = parseCommitMessageRange(commit);
return range.map(
commitMessageRange ->
RawParseUtils.decode(
enc,
raw,
commitMessageRange.changeMessageStart(),
commitMessageRange.changeMessageEnd() + 1));
}
private void parseNotes() throws IOException, ConfigInvalidException {
ObjectReader reader = walk.getObjectReader();
ChangeNotesCommit tipCommit = walk.parseCommit(tip);