package uk.ac.ic.wlgitbridge.git.handler.hook; import com.google.api.client.auth.oauth2.Credential; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PreReceiveHook; import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.transport.ReceiveCommand.Result; import org.eclipse.jgit.transport.ReceivePack; import uk.ac.ic.wlgitbridge.bridge.BridgeAPI; import uk.ac.ic.wlgitbridge.data.filestore.RawDirectory; import uk.ac.ic.wlgitbridge.git.handler.hook.exception.ForcedPushException; import uk.ac.ic.wlgitbridge.git.handler.hook.exception.WrongBranchException; import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.push.exception.InternalErrorException; import uk.ac.ic.wlgitbridge.snapshot.push.exception.OutOfDateException; import uk.ac.ic.wlgitbridge.snapshot.push.exception.SnapshotPostException; import uk.ac.ic.wlgitbridge.util.Log; import java.io.IOException; import java.util.Collection; /** * Created by Winston on 03/11/14. */ public class WriteLatexPutHook implements PreReceiveHook { private final BridgeAPI bridgeAPI; private final String hostname; private final Credential oauth2; public WriteLatexPutHook(BridgeAPI bridgeAPI, String hostname, Credential oauth2) { this.bridgeAPI = bridgeAPI; this.hostname = hostname; this.oauth2 = oauth2; } @Override public void onPreReceive(ReceivePack receivePack, Collection<ReceiveCommand> receiveCommands) { for (ReceiveCommand receiveCommand : receiveCommands) { try { handleReceiveCommand(oauth2, receivePack.getRepository(), receiveCommand); } catch (IOException e) { receivePack.sendError(e.getMessage()); receiveCommand.setResult(Result.REJECTED_OTHER_REASON, e.getMessage()); } catch (OutOfDateException e) { receiveCommand.setResult(Result.REJECTED_NONFASTFORWARD); } catch (SnapshotPostException e) { handleSnapshotPostException(receivePack, receiveCommand, e); } catch (Throwable t) { Log.warn("Throwable on pre receive: ", t); handleSnapshotPostException(receivePack, receiveCommand, new InternalErrorException()); } } } private void handleSnapshotPostException(ReceivePack receivePack, ReceiveCommand receiveCommand, SnapshotPostException e) { String message = e.getMessage(); receivePack.sendError(message); for (String line : e.getDescriptionLines()) { receivePack.sendMessage("hint: " + line); } receiveCommand.setResult(Result.REJECTED_OTHER_REASON, message); } private void handleReceiveCommand(Credential oauth2, Repository repository, ReceiveCommand receiveCommand) throws IOException, SnapshotPostException, ForbiddenException { checkBranch(receiveCommand); checkForcedPush(receiveCommand); bridgeAPI.putDirectoryContentsToProjectWithName( oauth2, repository.getWorkTree().getName(), getPushedDirectoryContents(repository, receiveCommand), getOldDirectoryContents(repository), hostname ); } private void checkBranch(ReceiveCommand receiveCommand) throws WrongBranchException { if (!receiveCommand.getRefName().equals("refs/heads/master")) { throw new WrongBranchException(); } } private void checkForcedPush(ReceiveCommand receiveCommand) throws ForcedPushException { if (receiveCommand.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD) { throw new ForcedPushException(); } } private RawDirectory getPushedDirectoryContents(Repository repository, ReceiveCommand receiveCommand) throws IOException, SnapshotPostException { return new RepositoryObjectTreeWalker(repository, receiveCommand.getNewId()) .getDirectoryContents(); } private RawDirectory getOldDirectoryContents(Repository repository) throws IOException, SnapshotPostException { return new RepositoryObjectTreeWalker(repository).getDirectoryContents(); } }