From d7905a15bf41df0574bd8613bf16f2d7ef0cb805 Mon Sep 17 00:00:00 2001 From: James Moger Date: Tue, 27 Dec 2011 17:50:39 -0500 Subject: Implemented Team hook scripts --- src/com/gitblit/ConfigUserService.java | 33 +++++- src/com/gitblit/FileUserService.java | 23 +++- src/com/gitblit/GitBlit.java | 130 +++++++++++++++------ src/com/gitblit/GitServlet.java | 14 +-- src/com/gitblit/models/TeamModel.java | 3 + .../gitblit/wicket/pages/EditRepositoryPage.java | 14 ++- src/com/gitblit/wicket/pages/EditTeamPage.html | 3 + src/com/gitblit/wicket/pages/EditTeamPage.java | 60 +++++++++- 8 files changed, 222 insertions(+), 58 deletions(-) (limited to 'src/com/gitblit') diff --git a/src/com/gitblit/ConfigUserService.java b/src/com/gitblit/ConfigUserService.java index b899d924..7e4600cf 100644 --- a/src/com/gitblit/ConfigUserService.java +++ b/src/com/gitblit/ConfigUserService.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -62,9 +63,13 @@ public class ConfigUserService implements IUserService { private static final String REPOSITORY = "repository"; private static final String ROLE = "role"; - + private static final String MAILINGLIST = "mailingList"; + private static final String PRERECEIVE = "preReceiveScript"; + + private static final String POSTRECEIVE = "postReceiveScript"; + private final File realmFile; private final Logger logger = LoggerFactory.getLogger(ConfigUserService.class); @@ -303,6 +308,7 @@ public class ConfigUserService implements IUserService { public List getAllTeamNames() { read(); List list = new ArrayList(teams.keySet()); + Collections.sort(list); return list; } @@ -328,6 +334,7 @@ public class ConfigUserService implements IUserService { } catch (Throwable t) { logger.error(MessageFormat.format("Failed to get teamnames for role {0}!", role), t); } + Collections.sort(list); return list; } @@ -468,6 +475,7 @@ public class ConfigUserService implements IUserService { public List getAllUsernames() { read(); List list = new ArrayList(users.keySet()); + Collections.sort(list); return list; } @@ -493,6 +501,7 @@ public class ConfigUserService implements IUserService { } catch (Throwable t) { logger.error(MessageFormat.format("Failed to get usernames for role {0}!", role), t); } + Collections.sort(list); return list; } @@ -652,12 +661,23 @@ public class ConfigUserService implements IUserService { } // null check on "final" mailing lists because JSON-sourced - // TeamModel - // can have a null users object + // TeamModel can have a null users object if (model.mailingLists != null) { config.setStringList(TEAM, model.name, MAILINGLIST, new ArrayList( model.mailingLists)); } + + // null check on "final" preReceiveScripts because JSON-sourced + // TeamModel can have a null preReceiveScripts object + if (model.preReceiveScripts != null) { + config.setStringList(TEAM, model.name, PRERECEIVE, model.preReceiveScripts); + } + + // null check on "final" postReceiveScripts because JSON-sourced + // TeamModel can have a null postReceiveScripts object + if (model.postReceiveScripts != null) { + config.setStringList(TEAM, model.name, POSTRECEIVE, model.postReceiveScripts); + } } config.save(); @@ -724,7 +744,12 @@ public class ConfigUserService implements IUserService { team.addRepositories(Arrays.asList(config.getStringList(TEAM, teamname, REPOSITORY))); team.addUsers(Arrays.asList(config.getStringList(TEAM, teamname, USER))); - team.addMailingLists(Arrays.asList(config.getStringList(TEAM, teamname, MAILINGLIST))); + team.addMailingLists(Arrays.asList(config.getStringList(TEAM, teamname, + MAILINGLIST))); + team.preReceiveScripts.addAll(Arrays.asList(config.getStringList(TEAM, + teamname, PRERECEIVE))); + team.postReceiveScripts.addAll(Arrays.asList(config.getStringList(TEAM, + teamname, POSTRECEIVE))); teams.put(team.name.toLowerCase(), team); diff --git a/src/com/gitblit/FileUserService.java b/src/com/gitblit/FileUserService.java index 27892f71..88c7d790 100644 --- a/src/com/gitblit/FileUserService.java +++ b/src/com/gitblit/FileUserService.java @@ -20,6 +20,7 @@ import java.io.FileWriter; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -334,6 +335,7 @@ public class FileUserService extends FileSettings implements IUserService { } list.add(user); } + Collections.sort(list); return list; } @@ -368,6 +370,7 @@ public class FileUserService extends FileSettings implements IUserService { } catch (Throwable t) { logger.error(MessageFormat.format("Failed to get usernames for role {0}!", role), t); } + Collections.sort(list); return list; } @@ -619,11 +622,17 @@ public class FileUserService extends FileSettings implements IUserService { List repositories = new ArrayList(); List users = new ArrayList(); List mailingLists = new ArrayList(); + List preReceive = new ArrayList(); + List postReceive = new ArrayList(); for (String role : roles) { if (role.charAt(0) == '!') { users.add(role.substring(1)); } else if (role.charAt(0) == '&') { - mailingLists.add(role.substring(1)); + mailingLists.add(role.substring(1)); + } else if (role.charAt(0) == '^') { + preReceive.add(role.substring(1)); + } else if (role.charAt(0) == '%') { + postReceive.add(role.substring(1)); } else { repositories.add(role); } @@ -656,6 +665,7 @@ public class FileUserService extends FileSettings implements IUserService { @Override public List getAllTeamNames() { List list = new ArrayList(teams.keySet()); + Collections.sort(list); return list; } @@ -691,6 +701,7 @@ public class FileUserService extends FileSettings implements IUserService { } catch (Throwable t) { logger.error(MessageFormat.format("Failed to get teamnames for role {0}!", role), t); } + Collections.sort(list); return list; } @@ -841,6 +852,16 @@ public class FileUserService extends FileSettings implements IUserService { sb.append(address); sb.append(','); } + for (String script : model.preReceiveScripts) { + sb.append('^'); + sb.append(script); + sb.append(','); + } + for (String script : model.postReceiveScripts) { + sb.append('%'); + sb.append(script); + sb.append(','); + } // trim trailing comma sb.setLength(sb.length() - 1); allUsers.remove("@" + teamname); diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index a4680606..d82e3c2f 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -28,11 +28,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -1444,13 +1445,12 @@ public class GitBlit implements ServletContextListener { } /** - * Returns the list of all available Groovy push hook scripts that are not - * already specified globally for all repositories. Script files must have + * Returns the list of all Groovy push hook scripts. Script files must have * .groovy extension * * @return list of available hook scripts */ - public List getAvailableScripts() { + public List getAllScripts() { File groovyFolder = getGroovyScriptsFolder(); File[] files = groovyFolder.listFiles(new FileFilter() { @Override @@ -1458,55 +1458,115 @@ public class GitBlit implements ServletContextListener { return pathname.isFile() && pathname.getName().endsWith(".groovy"); } }); - - Set globals = new HashSet(); - String[] keys = { Keys.groovy.preReceiveScripts, Keys.groovy.postReceiveScripts }; - for (String key : keys) { - for (String script : getStrings(key)) { - if (script.endsWith(".groovy")) { - globals.add(script.substring(0, script.lastIndexOf('.'))); - } else { - globals.add(script); - } - } - } - - // create list of available scripts by excluding scripts that are - // globally specified List scripts = new ArrayList(); if (files != null) { for (File file : files) { String script = file.getName().substring(0, file.getName().lastIndexOf('.')); - if (!globals.contains(script)) { - scripts.add(script); - } + scripts.add(script); } } return scripts; } - - public List getInheritedPreReceiveScripts(RepositoryModel repository) { - Set globals = new HashSet(); + + /** + * Returns the list of pre-receive scripts the repository inherited from the + * global settings and team affiliations. + * + * @param repository + * if null only the globally specified scripts are returned + * @return a list of scripts + */ + public List getPreReceiveScriptsInherited(RepositoryModel repository) { + Set scripts = new LinkedHashSet(); + // Globals for (String script : getStrings(Keys.groovy.preReceiveScripts)) { if (script.endsWith(".groovy")) { - globals.add(script.substring(0, script.lastIndexOf('.'))); + scripts.add(script.substring(0, script.lastIndexOf('.'))); } else { - globals.add(script); + scripts.add(script); + } + } + + // Team Scripts + if (repository != null) { + for (String teamname : userService.getTeamnamesForRepositoryRole(repository.name)) { + TeamModel team = userService.getTeamModel(teamname); + scripts.addAll(team.preReceiveScripts); + } + } + return new ArrayList(scripts); + } + + /** + * Returns the list of all available Groovy pre-receive push hook scripts + * that are not already inherited by the repository. Script files must have + * .groovy extension + * + * @param repository + * optional parameter + * @return list of available hook scripts + */ + public List getPreReceiveScriptsUnused(RepositoryModel repository) { + Set inherited = new TreeSet(getPreReceiveScriptsInherited(repository)); + + // create list of available scripts by excluding inherited scripts + List scripts = new ArrayList(); + for (String script : getAllScripts()) { + if (!inherited.contains(script)) { + scripts.add(script); } } - return new ArrayList(globals); + return scripts; } - - public List getInheritedPostReceiveScripts(RepositoryModel repository) { - Set globals = new HashSet(); + + /** + * Returns the list of post-receive scripts the repository inherited from + * the global settings and team affiliations. + * + * @param repository + * if null only the globally specified scripts are returned + * @return a list of scripts + */ + public List getPostReceiveScriptsInherited(RepositoryModel repository) { + Set scripts = new LinkedHashSet(); + // Global Scripts for (String script : getStrings(Keys.groovy.postReceiveScripts)) { if (script.endsWith(".groovy")) { - globals.add(script.substring(0, script.lastIndexOf('.'))); + scripts.add(script.substring(0, script.lastIndexOf('.'))); } else { - globals.add(script); + scripts.add(script); + } + } + // Team Scripts + if (repository != null) { + for (String teamname : userService.getTeamnamesForRepositoryRole(repository.name)) { + TeamModel team = userService.getTeamModel(teamname); + scripts.addAll(team.postReceiveScripts); } } - return new ArrayList(globals); + return new ArrayList(scripts); + } + + /** + * Returns the list of unused Groovy post-receive push hook scripts that are + * not already inherited by the repository. Script files must have .groovy + * extension + * + * @param repository + * optional parameter + * @return list of available hook scripts + */ + public List getPostReceiveScriptsUnused(RepositoryModel repository) { + Set inherited = new TreeSet(getPostReceiveScriptsInherited(repository)); + + // create list of available scripts by excluding inherited scripts + List scripts = new ArrayList(); + for (String script : getAllScripts()) { + if (!inherited.contains(script)) { + scripts.add(script); + } + } + return scripts; } /** @@ -1572,7 +1632,7 @@ public class GitBlit implements ServletContextListener { setting.currentValue = settings.getString(key, ""); } } - settingsModel.pushScripts = getAvailableScripts(); + settingsModel.pushScripts = getAllScripts(); return settingsModel; } diff --git a/src/com/gitblit/GitServlet.java b/src/com/gitblit/GitServlet.java index 36e1c3ed..967efac6 100644 --- a/src/com/gitblit/GitServlet.java +++ b/src/com/gitblit/GitServlet.java @@ -99,9 +99,9 @@ public class GitServlet extends org.eclipse.jgit.http.server.GitServlet { } /** - * Transitional wrapper class to configure the JGit 1.2 GitFilter. - * This GitServlet will probably be replaced by a GitFilter so that Gitblit - * can serve Git repositories on the root URL and not a /git sub-url. + * Transitional wrapper class to configure the JGit 1.2 GitFilter. This + * GitServlet will probably be replaced by a GitFilter so that Gitblit can + * serve Git repositories on the root URL and not a /git sub-url. * * @author James Moger * @@ -160,9 +160,9 @@ public class GitServlet extends org.eclipse.jgit.http.server.GitServlet { */ @Override public void onPreReceive(ReceivePack rp, Collection commands) { - Set scripts = new LinkedHashSet(); - scripts.addAll(GitBlit.getStrings(Keys.groovy.preReceiveScripts)); RepositoryModel repository = getRepositoryModel(rp); + Set scripts = new LinkedHashSet(); + scripts.addAll(GitBlit.self().getPreReceiveScriptsInherited(repository)); scripts.addAll(repository.preReceiveScripts); UserModel user = getUserModel(rp); runGroovy(repository, user, commands, scripts); @@ -188,9 +188,9 @@ public class GitServlet extends org.eclipse.jgit.http.server.GitServlet { logger.info("skipping post-receive hooks, no refs created, updated, or removed"); return; } - Set scripts = new LinkedHashSet(); - scripts.addAll(GitBlit.getStrings(Keys.groovy.postReceiveScripts)); RepositoryModel repository = getRepositoryModel(rp); + Set scripts = new LinkedHashSet(); + scripts.addAll(GitBlit.self().getPostReceiveScriptsInherited(repository)); scripts.addAll(repository.postReceiveScripts); UserModel user = getUserModel(rp); runGroovy(repository, user, commands, scripts); diff --git a/src/com/gitblit/models/TeamModel.java b/src/com/gitblit/models/TeamModel.java index 3258ef6c..3d176e59 100644 --- a/src/com/gitblit/models/TeamModel.java +++ b/src/com/gitblit/models/TeamModel.java @@ -16,6 +16,7 @@ package com.gitblit.models; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -37,6 +38,8 @@ public class TeamModel implements Serializable, Comparable { public final Set users = new HashSet(); public final Set repositories = new HashSet(); public final Set mailingLists = new HashSet(); + public final List preReceiveScripts = new ArrayList(); + public final List postReceiveScripts = new ArrayList(); public TeamModel(String name) { this.name = name; diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java index 69d21191..0f3a0bbe 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java @@ -121,8 +121,8 @@ public class EditRepositoryPage extends RootSubPage { } final Palette preReceivePalette = new Palette("preReceiveScripts", new ListModel(preReceiveScripts), new CollectionModel(GitBlit - .self().getAvailableScripts()), new ChoiceRenderer("", ""), 12, - true); + .self().getPreReceiveScriptsUnused(repositoryModel)), + new ChoiceRenderer("", ""), 12, true); // post-receive palette if (repositoryModel.postReceiveScripts != null) { @@ -130,8 +130,8 @@ public class EditRepositoryPage extends RootSubPage { } final Palette postReceivePalette = new Palette("postReceiveScripts", new ListModel(postReceiveScripts), new CollectionModel(GitBlit - .self().getAvailableScripts()), new ChoiceRenderer("", ""), 12, - true); + .self().getPostReceiveScriptsUnused(repositoryModel)), + new ChoiceRenderer("", ""), 12, true); CompoundPropertyModel model = new CompoundPropertyModel( repositoryModel); @@ -293,9 +293,11 @@ public class EditRepositoryPage extends RootSubPage { form.add(teamsPalette); form.add(federationSetsPalette); form.add(preReceivePalette); - form.add(new BulletListPanel("inheritedPreReceive", "inherited", GitBlit.self().getInheritedPreReceiveScripts(repositoryModel))); + form.add(new BulletListPanel("inheritedPreReceive", "inherited", GitBlit.self() + .getPreReceiveScriptsInherited(repositoryModel))); form.add(postReceivePalette); - form.add(new BulletListPanel("inheritedPostReceive", "inherited", GitBlit.self().getInheritedPostReceiveScripts(repositoryModel))); + form.add(new BulletListPanel("inheritedPostReceive", "inherited", GitBlit.self() + .getPostReceiveScriptsInherited(repositoryModel))); form.add(new Button("save")); Button cancel = new Button("cancel") { diff --git a/src/com/gitblit/wicket/pages/EditTeamPage.html b/src/com/gitblit/wicket/pages/EditTeamPage.html index 36dd26a7..b680bc97 100644 --- a/src/com/gitblit/wicket/pages/EditTeamPage.html +++ b/src/com/gitblit/wicket/pages/EditTeamPage.html @@ -17,6 +17,9 @@
+

 

+

+

 
diff --git a/src/com/gitblit/wicket/pages/EditTeamPage.java b/src/com/gitblit/wicket/pages/EditTeamPage.java index c5c240fd..8a0540f1 100644 --- a/src/com/gitblit/wicket/pages/EditTeamPage.java +++ b/src/com/gitblit/wicket/pages/EditTeamPage.java @@ -43,6 +43,7 @@ import com.gitblit.models.TeamModel; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.RequiresAdminRole; import com.gitblit.wicket.WicketUtils; +import com.gitblit.wicket.panels.BulletListPanel; @RequiresAdminRole public class EditTeamPage extends RootSubPage { @@ -73,7 +74,7 @@ public class EditTeamPage extends RootSubPage { } else { super.setupPage(getString("gb.edit"), teamModel.name); } - + CompoundPropertyModel model = new CompoundPropertyModel(teamModel); List repos = new ArrayList(); @@ -84,17 +85,42 @@ public class EditTeamPage extends RootSubPage { } } StringUtils.sortRepositorynames(repos); - + List teamUsers = new ArrayList(teamModel.users); Collections.sort(teamUsers); - + List preReceiveScripts = new ArrayList(); + List postReceiveScripts = new ArrayList(); + final String oldName = teamModel.name; + + // repositories palette final Palette repositories = new Palette("repositories", new ListModel(new ArrayList(teamModel.repositories)), new CollectionModel(repos), new ChoiceRenderer("", ""), 10, false); + + // users palette final Palette users = new Palette("users", new ListModel( new ArrayList(teamUsers)), new CollectionModel(GitBlit.self() .getAllUsernames()), new ChoiceRenderer("", ""), 10, false); + + // pre-receive palette + if (teamModel.preReceiveScripts != null) { + preReceiveScripts.addAll(teamModel.preReceiveScripts); + } + final Palette preReceivePalette = new Palette("preReceiveScripts", + new ListModel(preReceiveScripts), new CollectionModel(GitBlit + .self().getPreReceiveScriptsUnused(null)), new ChoiceRenderer("", + ""), 12, true); + + // post-receive palette + if (teamModel.postReceiveScripts != null) { + postReceiveScripts.addAll(teamModel.postReceiveScripts); + } + final Palette postReceivePalette = new Palette("postReceiveScripts", + new ListModel(postReceiveScripts), new CollectionModel(GitBlit + .self().getPostReceiveScriptsUnused(null)), new ChoiceRenderer("", + ""), 12, true); + Form form = new Form("editForm", model) { private static final long serialVersionUID = 1L; @@ -147,7 +173,25 @@ public class EditTeamPage extends RootSubPage { teamModel.mailingLists.clear(); teamModel.mailingLists.addAll(list); } - + + // pre-receive scripts + List preReceiveScripts = new ArrayList(); + Iterator pres = preReceivePalette.getSelectedChoices(); + while (pres.hasNext()) { + preReceiveScripts.add(pres.next()); + } + teamModel.preReceiveScripts.clear(); + teamModel.preReceiveScripts.addAll(preReceiveScripts); + + // post-receive scripts + List postReceiveScripts = new ArrayList(); + Iterator post = postReceivePalette.getSelectedChoices(); + while (post.hasNext()) { + postReceiveScripts.add(post.next()); + } + teamModel.postReceiveScripts.clear(); + teamModel.postReceiveScripts.addAll(postReceiveScripts); + try { GitBlit.self().updateTeamModel(oldName, teamModel, isCreate); } catch (GitBlitException e) { @@ -173,8 +217,14 @@ public class EditTeamPage extends RootSubPage { mailingLists = new Model(teamModel.mailingLists == null ? "" : StringUtils.flattenStrings(teamModel.mailingLists, " ")); form.add(new TextField("mailingLists", mailingLists)); - + form.add(repositories); + form.add(preReceivePalette); + form.add(new BulletListPanel("inheritedPreReceive", "inherited", GitBlit.self() + .getPreReceiveScriptsInherited(null))); + form.add(postReceivePalette); + form.add(new BulletListPanel("inheritedPostReceive", "inherited", GitBlit.self() + .getPostReceiveScriptsInherited(null))); form.add(new Button("save")); Button cancel = new Button("cancel") { -- cgit v1.2.3