From 819efdc8c5ea633e9be1e744ade8b197d21a1962 Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 11 Apr 2014 17:55:53 -0400 Subject: [PATCH] Allow ReceiveHook extensions --- .../com/gitblit/extensions/ReceiveHook.java | 53 +++++++++++++++++++ .../com/gitblit/git/GitblitReceivePack.java | 51 +++++++++++++++--- src/site/setup_plugins.mkd | 36 ++++++++++++- 3 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/gitblit/extensions/ReceiveHook.java diff --git a/src/main/java/com/gitblit/extensions/ReceiveHook.java b/src/main/java/com/gitblit/extensions/ReceiveHook.java new file mode 100644 index 00000000..00dcb3e3 --- /dev/null +++ b/src/main/java/com/gitblit/extensions/ReceiveHook.java @@ -0,0 +1,53 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.extensions; + +import java.util.Collection; + +import org.eclipse.jgit.transport.ReceiveCommand; + +import ro.fortsoft.pf4j.ExtensionPoint; + +import com.gitblit.git.GitblitReceivePack; + +/** + * Extension point for plugins to process commits on Pre- and Post- Receive. + * + * @author James Moger + * + */ +public abstract class ReceiveHook implements ExtensionPoint { + + /** + * Called BEFORE received ref update commands have been written to the + * repository. This allows extensions to process or reject incoming pushes + * using whatever logic may be appropriate. + * + * @param receivePack + * @param commands + */ + public abstract void onPreReceive(GitblitReceivePack receivePack, Collection commands); + + /** + * Called AFTER received ref update commands have been written to the + * repository. This allows extensions to send notifications or trigger + * continuous integration systems. + * + * @param receivePack + * @param commands + */ + public abstract void onPostReceive(GitblitReceivePack receivePack, Collection commands); +} diff --git a/src/main/java/com/gitblit/git/GitblitReceivePack.java b/src/main/java/com/gitblit/git/GitblitReceivePack.java index 73da3d3e..0cc41987 100644 --- a/src/main/java/com/gitblit/git/GitblitReceivePack.java +++ b/src/main/java/com/gitblit/git/GitblitReceivePack.java @@ -47,6 +47,7 @@ import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.client.Translation; +import com.gitblit.extensions.ReceiveHook; import com.gitblit.manager.IGitblit; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; @@ -157,6 +158,14 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P @Override public void onPreReceive(ReceivePack rp, Collection commands) { + if (commands.size() == 0) { + // no receive commands to process + // this can happen if receive pack subclasses intercept and filter + // the commands + LOGGER.debug("skipping pre-receive processing, no refs created, updated, or removed"); + return; + } + if (repository.isMirror) { // repository is a mirror for (ReceiveCommand cmd : commands) { @@ -276,6 +285,15 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P } } + // call pre-receive plugins + for (ReceiveHook hook : gitblit.getExtensions(ReceiveHook.class)) { + try { + hook.onPreReceive(this, commands); + } catch (Exception e) { + LOGGER.error("Failed to execute extension", e); + } + } + Set scripts = new LinkedHashSet(); scripts.addAll(gitblit.getPreReceiveScriptsInherited(repository)); if (!ArrayUtils.isEmpty(repository.preReceiveScripts)) { @@ -298,7 +316,7 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P @Override public void onPostReceive(ReceivePack rp, Collection commands) { if (commands.size() == 0) { - LOGGER.debug("skipping post-receive hooks, no refs created, updated, or removed"); + LOGGER.debug("skipping post-receive processing, no refs created, updated, or removed"); return; } @@ -379,6 +397,15 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P } } + // call post-receive plugins + for (ReceiveHook hook : gitblit.getExtensions(ReceiveHook.class)) { + try { + hook.onPostReceive(this, commands); + } catch (Exception e) { + LOGGER.error("Failed to execute extension", e); + } + } + // run Groovy hook scripts Set scripts = new LinkedHashSet(); scripts.addAll(gitblit.getPostReceiveScriptsInherited(repository)); @@ -434,7 +461,7 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P this.gitblitUrl = url; } - protected void sendRejection(final ReceiveCommand cmd, final String why, Object... objects) { + public void sendRejection(final ReceiveCommand cmd, final String why, Object... objects) { String text; if (ArrayUtils.isEmpty(objects)) { text = why; @@ -445,15 +472,15 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P LOGGER.error(text + " (" + user.username + ")"); } - protected void sendHeader(String msg, Object... objects) { + public void sendHeader(String msg, Object... objects) { sendInfo("--> ", msg, objects); } - protected void sendInfo(String msg, Object... objects) { + public void sendInfo(String msg, Object... objects) { sendInfo(" ", msg, objects); } - protected void sendInfo(String prefix, String msg, Object... objects) { + private void sendInfo(String prefix, String msg, Object... objects) { String text; if (ArrayUtils.isEmpty(objects)) { text = msg; @@ -467,7 +494,7 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P } } - protected void sendError(String msg, Object... objects) { + public void sendError(String msg, Object... objects) { String text; if (ArrayUtils.isEmpty(objects)) { text = msg; @@ -532,4 +559,16 @@ public class GitblitReceivePack extends ReceivePack implements PreReceiveHook, P } } } + + public IGitblit getGitblit() { + return gitblit; + } + + public RepositoryModel getRepositoryModel() { + return repository; + } + + public UserModel getUserModel() { + return user; + } } diff --git a/src/site/setup_plugins.mkd b/src/site/setup_plugins.mkd index b609a683..b956cc15 100644 --- a/src/site/setup_plugins.mkd +++ b/src/site/setup_plugins.mkd @@ -54,13 +54,47 @@ Gitblit also supports loading multiple plugin registries. Just place another ** ### Extension Point: SSH DispatchCommand -You can provide your own custom SSH commands by extending the DispatchCommand. +You can provide your own custom SSH commands by extending the *DispatchCommand* class. For some examples of how to do this, please see: [gitblit-cookbook-plugin (Maven project)](https://dev.gitblit.com/summary/gitblit-cookbook-plugin.git) [gitblit-powertools-plugin (Ant/Moxie project)](https://dev.gitblit.com/summary/gitblit-powertools-plugin.git) +### Extension Point: Pre- and Post- Receive Hook + +You can provide your own custom pre and/or post receive hooks by extending the *ReceiveHook* class. + +```java +import com.gitblit.extensions.ReceiveHook; +import ro.fortsoft.pf4j.Extension; + +@Extension +public class MyHook extends ReceiveHook { + + @Override + public void onPreReceive(GitblitReceivePack receivePack, Collection commands) { + RepositoryModel repository = receivePack.getRepositoryModel(); + UserModel user = receivePack.getUserModel(); + receivePack.sendInfo("Hi {0}, I see {1} commands for {2} onPreReceive", + user.getDisplayName(), + commands.size(), + repository.name); + } + + @Override + public void onPostReceive(GitblitReceivePack receivePack, Collection commands) { + RepositoryModel repository = receivePack.getRepositoryModel(); + UserModel user = receivePack.getUserModel(); + receivePack.sendInfo("Hi {0}, I see {1} commands for {2} onPostReceive", + user.getDisplayName(), + commands.size(), + repository.name); + } +} + +``` + ### Mac OSX Fonts Gitblit's core SSH commands and those in the *powertools* plugin rely on use of ANSI border characters to provide a pretty presentation of data. Unfortunately, the fonts provided by Apple - while very nice - don't work well with ANSI border characters. The following public domain fixed-width, fixed-point, bitmapped fonts work very nicely. I find the 6x12 font with a line spacing of ~0.8 to be quite acceptable. -- 2.39.5