Move new change display to PostReceiveHook

Future versions of Git (and JGit) will support sending messages from
the server side down a muxed side-band channel, so we can put custom
messages onto the client's terminal even over protocols like http://.

Instead of writing these new change links only in the SSH code,
write them in our onPostReceive hook so they can become part of
that side-band channel once we upgrade to a JGit that supports it.
Until then, these will still appear on ssh:// connections, but
won't show on http://.

Change-Id: Ibcc94cf93191f8b2fb9c5c446dee05d5e168b28e
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index c117813..14e0481 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -109,16 +109,6 @@
     ReceiveCommits create(ProjectControl projectControl, Repository repository);
   }
 
-  public interface MessageListener {
-    public static final MessageListener DISABLED = new MessageListener() {
-      @Override
-      public void warn(String msg) {
-      }
-    };
-
-    void warn(String msg) throws IOException;
-  }
-
   public static class Capable {
     public static final Capable OK = new Capable("OK");
 
@@ -133,7 +123,6 @@
     }
   }
 
-  private MessageListener messages = MessageListener.DISABLED;
   private final Set<Account.Id> reviewerId = new HashSet<Account.Id>();
   private final Set<Account.Id> ccId = new HashSet<Account.Id>();
 
@@ -207,11 +196,6 @@
     rp.setPostReceiveHook(this);
   }
 
-  /** Set the logger where warning messages are sent to the user. */
-  public void setMessageListener(MessageListener logger) {
-    this.messages = logger;
-  }
-
   /** Add reviewers for new (or updated) changes. */
   public void addReviewers(Collection<Account.Id> who) {
     reviewerId.addAll(who);
@@ -246,11 +230,6 @@
     }
   }
 
-  /** @return the set of new changes, if any were created during receive. */
-  public List<Change.Id> getNewChanges() {
-    return allNewChanges;
-  }
-
   public void onPreReceive(final ReceivePack arg0,
       final Collection<ReceiveCommand> commands) {
     parseCommands(commands);
@@ -287,6 +266,16 @@
         }
       }
     }
+
+    if (!allNewChanges.isEmpty() && canonicalWebUrl != null) {
+      final String url = canonicalWebUrl;
+      rp.sendMessage("");
+      rp.sendMessage("New Changes:");
+      for (final Change.Id c : allNewChanges) {
+        rp.sendMessage("  " + url + c.get());
+      }
+      rp.sendMessage("");
+    }
   }
 
   private Capable verifyActiveContributorAgreement() throws OrmException {
@@ -1003,7 +992,7 @@
             reject(request.cmd, "no changes made");
             return null;
           } else {
-            messages.warn(change.getKey().abbreviate() + ": " //
+            rp.sendMessage("warning: " + change.getKey().abbreviate() + ": " //
                 + " no files changed, but" //
                 + (!messageEq ? " message updated" : "") //
                 + (!messageEq && !parentsEq ? " and" : "") //
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java
index d849eaf..a468e19 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java
@@ -15,11 +15,8 @@
 package com.google.gerrit.sshd.commands;
 
 import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.Change;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.config.CanonicalWebUrl;
 import com.google.gerrit.server.git.ReceiveCommits;
-import com.google.gerrit.server.git.ReceiveCommits.MessageListener;
 import com.google.gerrit.sshd.AbstractGitCommand;
 import com.google.inject.Inject;
 
@@ -31,8 +28,6 @@
 import java.util.HashSet;
 import java.util.Set;
 
-import javax.annotation.Nullable;
-
 /** Receives change upload over SSH using the Git receive-pack protocol. */
 final class Receive extends AbstractGitCommand {
   @Inject
@@ -44,11 +39,6 @@
   @Inject
   private IdentifiedUser.GenericFactory identifiedUserFactory;
 
-  @Inject
-  @CanonicalWebUrl
-  @Nullable
-  private String canonicalWebUrl;
-
   private final Set<Account.Id> reviewerId = new HashSet<Account.Id>();
   private final Set<Account.Id> ccId = new HashSet<Account.Id>();
 
@@ -75,35 +65,12 @@
     verifyProjectVisible("reviewer", reviewerId);
     verifyProjectVisible("CC", ccId);
 
-    receive.setMessageListener(new MessageListener() {
-      @Override
-      public void warn(String warning) {
-        msg.print("warning: " + warning + "\n");
-        msg.flush();
-      }
-    });
     receive.addReviewers(reviewerId);
     receive.addExtraCC(ccId);
 
     final ReceivePack rp = receive.getReceivePack();
     rp.setRefLogIdent(currentUser.newRefLogIdent());
     rp.receive(in, out, err);
-
-    if (!receive.getNewChanges().isEmpty() && canonicalWebUrl != null) {
-      // Make sure there isn't anything buffered; we want to give the
-      // push client a chance to display its status report before we
-      // show our own messages on standard error.
-      //
-      out.flush();
-
-      final String url = canonicalWebUrl;
-      msg.write("\nNew Changes:\n");
-      for (final Change.Id c : receive.getNewChanges()) {
-        msg.write("  " + url + c.get() + "\n");
-      }
-      msg.write('\n');
-      msg.flush();
-    }
   }
 
   private void verifyProjectVisible(final String type, final Set<Account.Id> who)