From f76fee63ed9cb3a30d3c0c092d860b1cb93a481b Mon Sep 17 00:00:00 2001
From: Gerard Smyth <gerard.smyth@gmail.com>
Date: Thu, 08 May 2014 13:09:30 -0400
Subject: [PATCH] Updated the SyndicationServlet to provide an additional option to return details of the tags in the repository instead of the commits. This uses a new 'ot' request parameter to indicate the object type of the content to return, which can be ither TAG or COMMIT. If this is not provided, then COMMIT is assumed to maintain backwards compatability. If tags are returned, then the paging parameters, 'l' and 'pg' are still supported, but searching options are currently ignored.

---
 src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java |  187 +++++++++++++++++++++++++++++++++-------------
 1 files changed, 134 insertions(+), 53 deletions(-)

diff --git a/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
index e33a2c9..ce0958c 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
@@ -15,6 +15,7 @@
  */
 package com.gitblit.transport.ssh.commands;
 
+import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
 
@@ -26,14 +27,15 @@
 import ro.fortsoft.pf4j.PluginDescriptor;
 import ro.fortsoft.pf4j.PluginState;
 import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.Version;
 
 import com.gitblit.manager.IGitblit;
 import com.gitblit.models.PluginRegistry.InstallState;
 import com.gitblit.models.PluginRegistry.PluginRegistration;
 import com.gitblit.models.PluginRegistry.PluginRelease;
-import com.gitblit.models.UserModel;
 import com.gitblit.utils.FlipTable;
 import com.gitblit.utils.FlipTable.Borders;
+import com.gitblit.utils.StringUtils;
 import com.google.common.base.Joiner;
 
 /**
@@ -46,17 +48,18 @@
 public class PluginDispatcher extends DispatchCommand {
 
 	@Override
-	protected void setup(UserModel user) {
-		register(user, ListPlugins.class);
-		register(user, StartPlugin.class);
-		register(user, StopPlugin.class);
-		register(user, EnablePlugin.class);
-		register(user, DisablePlugin.class);
-		register(user, ShowPlugin.class);
-		register(user, RefreshPlugins.class);
-		register(user, AvailablePlugins.class);
-		register(user, InstallPlugin.class);
-		register(user, UninstallPlugin.class);
+	protected void setup() {
+		register(ListPlugins.class);
+		register(StartPlugin.class);
+		register(StopPlugin.class);
+		register(EnablePlugin.class);
+		register(DisablePlugin.class);
+		register(ShowPlugin.class);
+		register(RefreshPlugins.class);
+		register(AvailablePlugins.class);
+		register(InstallPlugin.class);
+		register(UpgradePlugin.class);
+		register(UninstallPlugin.class);
 	}
 
 	@CommandMetaData(name = "list", aliases = { "ls" }, description = "List plugins")
@@ -73,7 +76,7 @@
 		protected void asTable(List<PluginWrapper> list) {
 			String[] headers;
 			if (verbose) {
-				String [] h = { "#", "Id", "Description", "Version", "Requires", "State", "Path", "Provider"};
+				String [] h = { "#", "Id", "Description", "Version", "Requires", "State", "Path" };
 				headers = h;
 			} else {
 				String [] h = { "#", "Id", "Version", "State", "Path"};
@@ -84,7 +87,7 @@
 				PluginWrapper p = list.get(i);
 				PluginDescriptor d = p.getDescriptor();
 				if (verbose) {
-					data[i] = new Object[] { "" + (i + 1), d.getPluginId(), null/*d.getDescription()*/, d.getVersion(), null/*d.getRequires()*/, p.getPluginState(), p.getPluginPath(), d.getProvider() };
+					data[i] = new Object[] { "" + (i + 1), d.getPluginId(), d.getPluginDescription(), d.getVersion(), d.getRequires(), p.getPluginState(), p.getPluginPath() };
 				} else {
 					data[i] = new Object[] { "" + (i + 1), d.getPluginId(), d.getVersion(), p.getPluginState(), p.getPluginPath() };
 				}
@@ -98,7 +101,7 @@
 			for (PluginWrapper pw : list) {
 				PluginDescriptor d = pw.getDescriptor();
 				if (verbose) {
-					outTabbed(d.getPluginId(), null/*d.getDescription()*/, d.getVersion(), null/*d.getRequires()*/, pw.getPluginState(), pw.getPluginPath(), d.getProvider());
+					outTabbed(d.getPluginId(), d.getPluginDescription(), d.getVersion(), d.getRequires(), pw.getPluginState(), pw.getPluginPath());
 				} else {
 					outTabbed(d.getPluginId(), d.getVersion(), pw.getPluginState(), pw.getPluginPath());
 				}
@@ -136,7 +139,7 @@
 	@CommandMetaData(name = "start", description = "Start a plugin")
 	public static class StartPlugin extends PluginCommand {
 
-		@Argument(index = 0, required = true, metaVar = "ALL|<id>", usage = "the plugin to start")
+		@Argument(index = 0, required = true, metaVar = "ALL|<ID>|<INDEX>", usage = "the plugin to start")
 		protected String id;
 
 		@Override
@@ -155,7 +158,7 @@
 				if (PluginState.STARTED.equals(state)) {
 					stdout.println(String.format("Started %s", pluginWrapper.getPluginId()));
 				} else {
-					throw new Failure(1, String.format("Failed to start %s", pluginWrapper.getPluginId()));
+					throw new UnloggedFailure(1, String.format("Failed to start %s", pluginWrapper.getPluginId()));
 				}
 			}
 		}
@@ -164,7 +167,7 @@
 	@CommandMetaData(name = "stop", description = "Stop a plugin")
 	public static class StopPlugin extends PluginCommand {
 
-		@Argument(index = 0, required = true, metaVar = "ALL|<id>", usage = "the plugin to stop")
+		@Argument(index = 0, required = true, metaVar = "ALL|<ID>|<INDEX>", usage = "the plugin to stop")
 		protected String id;
 
 		@Override
@@ -183,7 +186,7 @@
 				if (PluginState.STOPPED.equals(state)) {
 					stdout.println(String.format("Stopped %s", pluginWrapper.getPluginId()));
 				} else {
-					throw new Failure(1, String.format("Failed to stop %s", pluginWrapper.getPluginId()));
+					throw new UnloggedFailure(1, String.format("Failed to stop %s", pluginWrapper.getPluginId()));
 				}
 			}
 		}
@@ -192,7 +195,7 @@
 	@CommandMetaData(name = "enable", description = "Enable a plugin")
 	public static class EnablePlugin extends PluginCommand {
 
-		@Argument(index = 0, required = true, metaVar = "<id>", usage = "the plugin id to enable")
+		@Argument(index = 0, required = true, metaVar = "<ID>|<INDEX>", usage = "the plugin to enable")
 		protected String id;
 
 		@Override
@@ -206,7 +209,7 @@
 			if (gitblit.enablePlugin(pluginWrapper.getPluginId())) {
 				stdout.println(String.format("Enabled %s", pluginWrapper.getPluginId()));
 			} else {
-				throw new Failure(1, String.format("Failed to enable %s", pluginWrapper.getPluginId()));
+				throw new UnloggedFailure(1, String.format("Failed to enable %s", pluginWrapper.getPluginId()));
 			}
 		}
 	}
@@ -214,7 +217,7 @@
 	@CommandMetaData(name = "disable", description = "Disable a plugin")
 	public static class DisablePlugin extends PluginCommand {
 
-		@Argument(index = 0, required = true, metaVar = "<id>", usage = "the plugin to disable")
+		@Argument(index = 0, required = true, metaVar = "<ID>|<INDEX>", usage = "the plugin to disable")
 		protected String id;
 
 		@Override
@@ -228,7 +231,7 @@
 			if (gitblit.disablePlugin(pluginWrapper.getPluginId())) {
 				stdout.println(String.format("Disabled %s", pluginWrapper.getPluginId()));
 			} else {
-				throw new Failure(1, String.format("Failed to disable %s", pluginWrapper.getPluginId()));
+				throw new UnloggedFailure(1, String.format("Failed to disable %s", pluginWrapper.getPluginId()));
 			}
 		}
 	}
@@ -236,7 +239,7 @@
 	@CommandMetaData(name = "show", description = "Show the details of a plugin")
 	public static class ShowPlugin extends PluginCommand {
 
-		@Argument(index = 0, required = true, metaVar = "<id>", usage = "the plugin to show")
+		@Argument(index = 0, required = true, metaVar = "<ID>|<INDEX>", usage = "the plugin to show")
 		protected String id;
 
 		@Override
@@ -255,10 +258,18 @@
 		}
 
 		protected String buildFieldTable(PluginWrapper pw, PluginRegistration reg) {
+			Version system = getContext().getGitblit().getSystemVersion();
+			PluginRelease current = reg == null ? null : reg.getCurrentRelease(system);
+			if (current == null) {
+				current = new PluginRelease();
+				current.version = "";
+				current.requires = "";
+			}
+
 			final String id = pw == null ? reg.id : pw.getPluginId();
-			final String description = reg == null ? ""/*pw.getDescriptor().getDescription()*/ : reg.description;
-			final String version = pw == null ? reg.getCurrentRelease().version : pw.getDescriptor().getVersion().toString();
-			final String requires = pw == null ? reg.getCurrentRelease().requires : ""/*pw.getDescriptor().getRequires().toString()*/;
+			final String description = reg == null ? pw.getDescriptor().getPluginDescription() : reg.description;
+			final String version = pw == null ? current.version : pw.getDescriptor().getVersion().toString();
+			final String requires = pw == null ? current.requires : pw.getDescriptor().getRequires().toString();
 			final String provider = pw == null ? reg.provider : pw.getDescriptor().getProvider();
 			final String registry = reg == null ? "" : reg.registry;
 			final String path = pw == null ? "" : pw.getPluginPath();
@@ -272,7 +283,7 @@
 				state = Joiner.on(", ").join(InstallState.INSTALLED, pw.getPluginState());
 			} else {
 				// registered, installed plugin
-				state = Joiner.on(", ").join(reg.getInstallState(), pw.getPluginState());
+				state = Joiner.on(", ").join(reg.getInstallState(system), pw.getPluginState());
 			}
 
 			StringBuilder sb = new StringBuilder();
@@ -444,7 +455,7 @@
 
 			List<PluginRegistration> list;
 			if (updates) {
-				list = gitblit.getRegisteredPlugins(InstallState.CAN_UPDATE);
+				list = gitblit.getRegisteredPlugins(InstallState.UPDATE_AVAILABLE);
 			} else {
 				list = gitblit.getRegisteredPlugins();
 			}
@@ -466,14 +477,18 @@
 				String [] h = { "Id", "Installed", "Current", "Requires", "State" };
 				headers = h;
 			}
+			Version system = getContext().getGitblit().getSystemVersion();
 			Object[][] data = new Object[list.size()][];
 			for (int i = 0; i < list.size(); i++) {
 				PluginRegistration p = list.get(i);
-				PluginRelease curr = p.getCurrentRelease();
+				PluginRelease curr = p.getCurrentRelease(system);
+				if (curr == null) {
+					curr = new PluginRelease();
+				}
 				if (verbose) {
-					data[i] = new Object[] {p.id, p.description, p.installedRelease, curr.version, curr.requires, p.getInstallState(), p.registry};
+					data[i] = new Object[] {p.id, p.description, p.installedRelease, curr.version, curr.requires, p.getInstallState(system), p.registry};
 				} else {
-					data[i] = new Object[] {p.id, p.installedRelease, curr.version, curr.requires, p.getInstallState()};
+					data[i] = new Object[] {p.id, p.installedRelease, curr.version, curr.requires, p.getInstallState(system)};
 				}
 			}
 
@@ -482,12 +497,16 @@
 
 		@Override
 		protected void asTabbed(List<PluginRegistration> list) {
+			Version system = getContext().getGitblit().getSystemVersion();
 			for (PluginRegistration p : list) {
-				PluginRelease curr = p.getCurrentRelease();
+				PluginRelease curr = p.getCurrentRelease(system);
+				if (curr == null) {
+					curr = new PluginRelease();
+				}
 				if (verbose) {
-					outTabbed(p.id, p.description, p.installedRelease, curr.version, curr.requires, p.getInstallState(), p.provider, p.registry);
+					outTabbed(p.id, p.description, p.installedRelease, curr.version, curr.requires, p.getInstallState(system), p.provider, p.registry);
 				} else {
-					outTabbed(p.id, p.installedRelease, curr.version, curr.requires, p.getInstallState());
+					outTabbed(p.id, p.installedRelease, curr.version, curr.requires, p.getInstallState(system));
 				}
 			}
 		}
@@ -496,8 +515,8 @@
 	@CommandMetaData(name = "install", description = "Download and installs a plugin")
 	public static class InstallPlugin extends SshCommand {
 
-		@Argument(index = 0, required = true, metaVar = "<URL>|<ID>|<NAME>", usage = "the id, name, or the url of the plugin to download and install")
-		protected String urlOrIdOrName;
+		@Argument(index = 0, required = true, metaVar = "<URL>|<ID>", usage = "the id or the url of the plugin to download and install")
+		protected String urlOrId;
 
 		@Option(name = "--version", usage = "The specific version to install")
 		private String version;
@@ -509,27 +528,89 @@
 		public void run() throws Failure {
 			IGitblit gitblit = getContext().getGitblit();
 			try {
-				String ulc = urlOrIdOrName.toLowerCase();
+				String ulc = urlOrId.toLowerCase();
 				if (ulc.startsWith("http://") || ulc.startsWith("https://")) {
-					if (gitblit.installPlugin(urlOrIdOrName, !disableChecksum)) {
-						stdout.println(String.format("Installed %s", urlOrIdOrName));
+					if (gitblit.installPlugin(urlOrId, !disableChecksum)) {
+						stdout.println(String.format("Installed %s", urlOrId));
 					} else {
-						new Failure(1, String.format("Failed to install %s", urlOrIdOrName));
+						throw new UnloggedFailure(1, String.format("Failed to install %s", urlOrId));
 					}
 				} else {
-					PluginRelease pv = gitblit.lookupRelease(urlOrIdOrName, version);
-					if (pv == null) {
-						throw new Failure(1,  String.format("Plugin \"%s\" is not in the registry!", urlOrIdOrName));
+					PluginRelease pr = gitblit.lookupRelease(urlOrId, version);
+					if (pr == null) {
+						throw new UnloggedFailure(1,  String.format("Plugin \"%s\" is not in the registry!", urlOrId));
 					}
-					if (gitblit.installPlugin(pv.url, !disableChecksum)) {
-						stdout.println(String.format("Installed %s", urlOrIdOrName));
+
+					// enforce minimum system requirement
+					if (!StringUtils.isEmpty(pr.requires)) {
+						Version requires = Version.createVersion(pr.requires);
+						Version system = gitblit.getSystemVersion();
+						boolean isValid = system.isZero() || system.atLeast(requires);
+						if (!isValid) {
+							String msg = String.format("Plugin \"%s:%s\" requires Gitblit %s",
+									urlOrId, pr.version, pr.requires);
+							throw new UnloggedFailure(1, msg);
+						}
+					}
+
+					if (gitblit.installPlugin(pr.url, !disableChecksum)) {
+						stdout.println(String.format("Installed %s", urlOrId));
 					} else {
-						throw new Failure(1, String.format("Failed to install %s", urlOrIdOrName));
+						throw new UnloggedFailure(1, String.format("Failed to install %s", urlOrId));
 					}
 				}
-			} catch (Exception e) {
-				log.error("Failed to install " + urlOrIdOrName, e);
-				throw new Failure(1, String.format("Failed to install %s", urlOrIdOrName), e);
+			} catch (IOException e) {
+				log.error("Failed to install " + urlOrId, e);
+				throw new UnloggedFailure(1, String.format("Failed to install %s", urlOrId), e);
+			}
+		}
+	}
+
+	@CommandMetaData(name = "upgrade", description = "Upgrade a plugin")
+	public static class UpgradePlugin extends PluginCommand {
+
+		@Argument(index = 0, required = true, metaVar = "<ID>|<INDEX>", usage = "the plugin to upgrade")
+		protected String id;
+
+		@Option(name = "--version", usage = "The specific version to install")
+		private String version;
+
+		@Option(name = "--noverify", usage = "Disable checksum verification")
+		private boolean disableChecksum;
+
+		@Override
+		public void run() throws Failure {
+			IGitblit gitblit = getContext().getGitblit();
+			PluginWrapper pluginWrapper = getPlugin(id);
+			if (pluginWrapper == null) {
+				throw new UnloggedFailure("Invalid plugin specified!");
+			}
+
+			PluginRelease pr = gitblit.lookupRelease(pluginWrapper.getPluginId(), version);
+			if (pr == null) {
+				throw new UnloggedFailure(1,  String.format("Plugin \"%s\" is not in the registry!", pluginWrapper.getPluginId()));
+			}
+
+			// enforce minimum system requirement
+			if (!StringUtils.isEmpty(pr.requires)) {
+				Version requires = Version.createVersion(pr.requires);
+				Version system = gitblit.getSystemVersion();
+				boolean isValid = system.isZero() || system.atLeast(requires);
+				if (!isValid) {
+					throw new Failure(1, String.format("Plugin \"%s:%s\" requires Gitblit %s",
+							pluginWrapper.getPluginId(), pr.version, pr.requires));
+				}
+			}
+
+			try {
+				if (gitblit.upgradePlugin(pluginWrapper.getPluginId(), pr.url, !disableChecksum)) {
+					stdout.println(String.format("Upgraded %s", pluginWrapper.getPluginId()));
+				} else {
+					throw new UnloggedFailure(1, String.format("Failed to upgrade %s", pluginWrapper.getPluginId()));
+				}
+			} catch (IOException e) {
+				log.error("Failed to upgrade " + pluginWrapper.getPluginId(), e);
+				throw new UnloggedFailure(1, String.format("Failed to upgrade %s", pluginWrapper.getPluginId()), e);
 			}
 		}
 	}
@@ -537,7 +618,7 @@
 	@CommandMetaData(name = "uninstall", aliases = { "rm", "del" }, description = "Uninstall a plugin")
 	public static class UninstallPlugin extends PluginCommand {
 
-		@Argument(index = 0, required = true, metaVar = "<id>", usage = "the plugin to uninstall")
+		@Argument(index = 0, required = true, metaVar = "<ID>|<INDEX>", usage = "the plugin to uninstall")
 		protected String id;
 
 		@Override
@@ -548,10 +629,10 @@
 				throw new UnloggedFailure(String.format("Plugin %s is not installed!", id));
 			}
 
-			if (gitblit.deletePlugin(pluginWrapper.getPluginId())) {
+			if (gitblit.uninstallPlugin(pluginWrapper.getPluginId())) {
 				stdout.println(String.format("Uninstalled %s", pluginWrapper.getPluginId()));
 			} else {
-				throw new Failure(1, String.format("Failed to uninstall %s", pluginWrapper.getPluginId()));
+				throw new UnloggedFailure(1, String.format("Failed to uninstall %s", pluginWrapper.getPluginId()));
 			}
 		}
 	}

--
Gitblit v1.9.1