Support for reading and writing Hashtags from/to NoteDB
Change-Id: If8539f21bb29685d2fba8ab4d8612c3f588cb28b
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user