Abstract out the message-sending parts of ReceiveCommits

For the RPC server case, we want to send the output from
ReceiveCommits back over the wire via the RPC protocol, and the
underlying ReceivePack has no connection to the server.

Change-Id: Icbb9d55cb42be601c349c0ab2e82d2d52b3ce95a
This commit is contained in:
Dave Borowitz
2012-02-29 09:24:20 -08:00
parent 2a2d8b9fea
commit f04aa729fe

View File

@@ -114,6 +114,43 @@ public class ReceiveCommits implements PreReceiveHook {
ReceiveCommits create(ProjectControl projectControl, Repository repository);
}
public interface MessageSender {
void sendMessage(String what);
void sendError(String what);
void sendBytes(byte[] what);
void sendBytes(byte[] what, int off, int len);
}
private class ReceivePackMessageSender implements MessageSender {
@Override
public void sendMessage(String what) {
rp.sendMessage(what);
}
@Override
public void sendError(String what) {
rp.sendError(what);
}
@Override
public void sendBytes(byte[] what) {
try {
rp.getMessageOutputStream().write(what);
} catch (IOException e) {
// Ignore write failures (matching JGit behavior).
}
}
@Override
public void sendBytes(byte[] what, int off, int len) {
try {
rp.getMessageOutputStream().write(what, off, len);
} catch (IOException e) {
// Ignore write failures (matching JGit behavior).
}
}
}
private final Set<Account.Id> reviewerId = new HashSet<Account.Id>();
private final Set<Account.Id> ccId = new HashSet<Account.Id>();
@@ -157,6 +194,8 @@ public class ReceiveCommits implements PreReceiveHook {
private final SubmoduleOp.Factory subOpFactory;
private MessageSender messageSender;
@Inject
ReceiveCommits(final ReviewDb db, final ApprovalTypes approvalTypes,
final AccountResolver accountResolver,
@@ -201,6 +240,8 @@ public class ReceiveCommits implements PreReceiveHook {
this.subOpFactory = subOpFactory;
this.messageSender = new ReceivePackMessageSender();
rp.setAllowCreates(true);
rp.setAllowDeletes(true);
rp.setAllowNonFastForwards(true);
@@ -228,6 +269,11 @@ public class ReceiveCommits implements PreReceiveHook {
ccId.addAll(who);
}
/** Set a message sender for this operation. */
public void setMessageSender(final MessageSender ms) {
messageSender = ms != null ? ms : new ReceivePackMessageSender();
}
/** @return the ReceivePack instance to speak the native Git protocol. */
public ReceivePack getReceivePack() {
return rp;
@@ -373,17 +419,17 @@ public class ReceiveCommits implements PreReceiveHook {
if (!allNewChanges.isEmpty() && canonicalWebUrl != null) {
final String url = canonicalWebUrl;
rp.sendMessage("");
rp.sendMessage("New Changes:");
messageSender.sendMessage("");
messageSender.sendMessage("New Changes:");
for (final Change c : allNewChanges) {
if (c.getStatus() == Change.Status.DRAFT) {
rp.sendMessage(" " + url + c.getChangeId() + " [DRAFT]");
messageSender.sendMessage(" " + url + c.getChangeId() + " [DRAFT]");
}
else {
rp.sendMessage(" " + url + c.getChangeId());
messageSender.sendMessage(" " + url + c.getChangeId());
}
}
rp.sendMessage("");
messageSender.sendMessage("");
}
}
@@ -465,9 +511,9 @@ public class ReceiveCommits implements PreReceiveHook {
ProjectConfig cfg = new ProjectConfig(project.getNameKey());
cfg.load(repo, cmd.getNewId());
if (!cfg.getValidationErrors().isEmpty()) {
rp.sendError("Invalid project configuration:");
messageSender.sendError("Invalid project configuration:");
for (ValidationError err : cfg.getValidationErrors()) {
rp.sendError(" " + err.getMessage());
messageSender.sendError(" " + err.getMessage());
}
reject(cmd, "invalid project configuration");
log.error("User " + currentUser.getUserName()
@@ -1155,7 +1201,7 @@ public class ReceiveCommits implements PreReceiveHook {
if (!parentsEq) {
msg.append(", was rebased");
}
rp.sendMessage(msg.toString());
messageSender.sendMessage(msg.toString());
}
}
} catch (IOException e) {
@@ -1560,7 +1606,7 @@ public class ReceiveCommits implements PreReceiveHook {
if (project.isRequireChangeID()) {
String errMsg = "missing Change-Id in commit message";
reject(cmd, errMsg);
rp.sendMessage(getFixedCommitMsgWithChangeId(errMsg, c));
messageSender.sendMessage(getFixedCommitMsgWithChangeId(errMsg, c));
return false;
}
} else if (idList.size() > 1) {
@@ -1572,7 +1618,7 @@ public class ReceiveCommits implements PreReceiveHook {
final String errMsg =
"missing or invalid Change-Id line format in commit message";
reject(cmd, errMsg);
rp.sendMessage(getFixedCommitMsgWithChangeId(errMsg, c));
messageSender.sendMessage(getFixedCommitMsgWithChangeId(errMsg, c));
return false;
}
}
@@ -1590,9 +1636,9 @@ public class ReceiveCommits implements PreReceiveHook {
ProjectConfig cfg = new ProjectConfig(project.getNameKey());
cfg.load(repo, cmd.getNewId());
if (!cfg.getValidationErrors().isEmpty()) {
rp.sendError("Invalid project configuration:");
messageSender.sendError("Invalid project configuration:");
for (ValidationError err : cfg.getValidationErrors()) {
rp.sendError(" " + err.getMessage());
messageSender.sendError(" " + err.getMessage());
}
reject(cmd, "invalid project configuration");
log.error("User " + currentUser.getUserName()
@@ -1671,7 +1717,7 @@ public class ReceiveCommits implements PreReceiveHook {
sb.append("ERROR: " + canonicalWebUrl + "#" + PageLinks.SETTINGS_CONTACT + "\n");
}
sb.append("\n");
getReceivePack().sendMessage(sb.toString());
messageSender.sendMessage(sb.toString());
}
private void warnMalformedMessage(RevCommit c) {
@@ -1683,7 +1729,7 @@ public class ReceiveCommits implements PreReceiveHook {
} catch (IOException err) {
id = c.abbreviate(6);
}
rp.sendMessage("(W) " + id.name() //
messageSender.sendMessage("(W) " + id.name() //
+ ": commit subject >65 characters; use shorter first paragraph");
}
@@ -1704,7 +1750,7 @@ public class ReceiveCommits implements PreReceiveHook {
} catch (IOException err) {
id = c.abbreviate(6);
}
rp.sendMessage("(W) " + id.name() //
messageSender.sendMessage("(W) " + id.name() //
+ ": commit message lines >70 characters; manually wrap lines");
}
}