Support for reading and writing Hashtags from/to NoteDB

Change-Id: If8539f21bb29685d2fba8ab4d8612c3f588cb28b
This commit is contained in:
Gustaf Lundh
2014-09-09 10:26:57 +02:00
parent bcf97bd354
commit 8c9d00e005
5 changed files with 80 additions and 1 deletions

View File

@@ -27,6 +27,7 @@ import java.util.Date;
public class ChangeNoteUtil {
static final String GERRIT_PLACEHOLDER_HOST = "gerrit";
static final FooterKey FOOTER_HASHTAGS = new FooterKey("Hashtags");
static final FooterKey FOOTER_LABEL = new FooterKey("Label");
static final FooterKey FOOTER_PATCH_SET = new FooterKey("Patch-set");
static final FooterKey FOOTER_STATUS = new FooterKey("Status");

View File

@@ -22,6 +22,7 @@ import com.google.common.base.Function;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Ordering;
import com.google.common.collect.Table;
@@ -138,6 +139,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
private ImmutableListMultimap<PatchSet.Id, ChangeMessage> changeMessages;
private ImmutableListMultimap<PatchSet.Id, PatchLineComment> commentsForBase;
private ImmutableListMultimap<PatchSet.Id, PatchLineComment> commentsForPS;
private ImmutableSet<String> hashtags;
NoteMap noteMap;
private final AllUsersName allUsers;
@@ -163,6 +165,10 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
return reviewers;
}
public ImmutableSet<String> getHashtags() {
return hashtags;
}
/**
* @return a list of all users who have ever been a reviewer on this change.
*/
@@ -275,6 +281,11 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
commentsForPS = ImmutableListMultimap.copyOf(parser.commentsForPs);
noteMap = parser.commentNoteMap;
if (parser.hashtags != null) {
hashtags = ImmutableSet.copyOf(parser.hashtags);
} else {
hashtags = ImmutableSet.of();
}
ImmutableSetMultimap.Builder<ReviewerState, Account.Id> reviewers =
ImmutableSetMultimap.builder();
for (Map.Entry<Account.Id, ReviewerState> e

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.notedb;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_HASHTAGS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_LABEL;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_STATUS;
@@ -22,6 +23,7 @@ import static com.google.gerrit.server.notedb.ChangeNoteUtil.GERRIT_PLACEHOLDER_
import com.google.common.base.Enums;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
@@ -29,6 +31,7 @@ import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import com.google.common.primitives.Ints;
@@ -63,6 +66,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
class ChangeNotesParser implements AutoCloseable {
final Map<Account.Id, ReviewerState> reviewers;
@@ -72,6 +76,7 @@ class ChangeNotesParser implements AutoCloseable {
final Multimap<PatchSet.Id, PatchLineComment> commentsForBase;
NoteMap commentNoteMap;
Change.Status status;
Set<String> hashtags;
private final Change.Id changeId;
private final ObjectId tip;
@@ -143,6 +148,7 @@ class ChangeNotesParser implements AutoCloseable {
PatchSet.Id psId = parsePatchSetId(commit);
Account.Id accountId = parseIdent(commit);
parseChangeMessage(psId, accountId, commit);
parseHashtags(commit);
if (submitRecords.isEmpty()) {
@@ -162,6 +168,20 @@ class ChangeNotesParser implements AutoCloseable {
}
}
private void parseHashtags(RevCommit commit) throws ConfigInvalidException {
// Commits are parsed in reverse order and only the last set of hashtags should be used.
if (hashtags != null) {
return;
}
List<String> hashtagsLines = commit.getFooterLines(FOOTER_HASHTAGS);
if (hashtagsLines.isEmpty()) {
return;
} else if (hashtagsLines.size() > 1) {
throw expectedOneFooter(FOOTER_HASHTAGS, hashtagsLines);
}
hashtags = Sets.newHashSet(Splitter.on(',').split(hashtagsLines.get(0)));
}
private Change.Status parseStatus(RevCommit commit)
throws ConfigInvalidException {
List<String> statusLines = commit.getFooterLines(FOOTER_STATUS);

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.notedb;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_HASHTAGS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_LABEL;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_STATUS;
@@ -22,6 +23,7 @@ import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBMITTED_WI
import static com.google.gerrit.server.notedb.CommentsInNotesUtil.getCommentPsId;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -62,6 +64,7 @@ import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A delta to apply to a change.
@@ -93,6 +96,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
private final CommentsInNotesUtil commentsUtil;
private List<PatchLineComment> commentsForBase;
private List<PatchLineComment> commentsForPs;
private Set<String> hashtags;
private String changeMessage;
private ChangeNotes notes;
@@ -342,6 +346,10 @@ public class ChangeUpdate extends AbstractChangeUpdate {
}
public void setHashtags(Set<String> hashtags) {
this.hashtags = hashtags;
}
public void putReviewer(Account.Id reviewer, ReviewerState type) {
checkArgument(type != ReviewerState.REMOVED, "invalid ReviewerType");
reviewers.put(reviewer, type);
@@ -448,6 +456,10 @@ public class ChangeUpdate extends AbstractChangeUpdate {
addFooter(msg, FOOTER_STATUS, status.name().toLowerCase());
}
if (hashtags != null) {
addFooter(msg, FOOTER_HASHTAGS, Joiner.on(",").join(hashtags));
}
for (Map.Entry<Account.Id, ReviewerState> e : reviewers.entrySet()) {
Account account = accountCache.get(e.getKey()).getAccount();
PersonIdent ident = newIdent(account, when);
@@ -507,7 +519,8 @@ public class ChangeUpdate extends AbstractChangeUpdate {
&& reviewers.isEmpty()
&& status == null
&& subject == null
&& submitRecords == null;
&& submitRecords == null
&& hashtags == null;
}
private static StringBuilder addFooter(StringBuilder sb, FooterKey footer) {

View File

@@ -58,6 +58,7 @@ import org.junit.Test;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class ChangeNotesTest extends AbstractChangeNotesTest {
@@ -338,6 +339,39 @@ public class ChangeNotesTest extends AbstractChangeNotesTest {
assertNull(update.getRevision());
}
@Test
public void hashtagCommit() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
LinkedHashSet<String> hashtags = new LinkedHashSet<String>();
hashtags.add("tag1");
hashtags.add("tag2");
update.setHashtags(hashtags);
update.commit();
RevWalk walk = new RevWalk(repo);
try {
RevCommit commit = walk.parseCommit(update.getRevision());
walk.parseBody(commit);
assertTrue(commit.getFullMessage().endsWith("Hashtags: tag1,tag2\n"));
} finally {
walk.release();
}
}
@Test
public void hashtagChangeNotes() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
LinkedHashSet<String> hashtags = new LinkedHashSet<String>();
hashtags.add("tag1");
hashtags.add("tag2");
update.setHashtags(hashtags);
update.commit();
ChangeNotes notes = newNotes(c);
assertEquals(hashtags, notes.getHashtags());
}
@Test
public void emptyExceptSubject() throws Exception {
ChangeUpdate update = newUpdate(newChange(), changeOwner);