summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.classpath6
-rw-r--r--build.moxie6
-rw-r--r--gitblit.iml22
-rw-r--r--releases.moxie7
-rw-r--r--src/main/java/com/gitblit/DaggerModule.java2
-rw-r--r--src/main/java/com/gitblit/extensions/GitblitPlugin.java (renamed from src/test/java/com/gitblit/tests/ActivityTest.java)59
-rw-r--r--src/main/java/com/gitblit/git/PatchsetReceivePack.java15
-rw-r--r--src/main/java/com/gitblit/manager/GitblitManager.java6
-rw-r--r--src/main/java/com/gitblit/manager/IPluginManager.java8
-rw-r--r--src/main/java/com/gitblit/manager/PluginManager.java21
-rw-r--r--src/main/java/com/gitblit/models/GravatarProfile.java83
-rw-r--r--src/main/java/com/gitblit/models/PluginRegistry.java8
-rw-r--r--src/main/java/com/gitblit/servlet/GitblitContext.java5
-rw-r--r--src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java72
-rw-r--r--src/main/java/com/gitblit/utils/ActivityUtils.java46
-rw-r--r--src/main/java/com/gitblit/wicket/GitBlitWebApp.java9
-rw-r--r--src/site/plugins_extensions.mkd61
-rw-r--r--src/site/plugins_overview.mkd5
-rw-r--r--src/site/setup_transport_ssh.mkd11
19 files changed, 233 insertions, 219 deletions
diff --git a/.classpath b/.classpath
index 6b0d864e..f61ebd24 100644
--- a/.classpath
+++ b/.classpath
@@ -11,8 +11,8 @@
<classpathentry kind="lib" path="ext/javawriter-2.1.1.jar" sourcepath="ext/src/javawriter-2.1.1.jar" />
<classpathentry kind="lib" path="ext/annotations-12.0.jar" sourcepath="ext/src/annotations-12.0.jar" />
<classpathentry kind="lib" path="ext/log4j-1.2.17.jar" sourcepath="ext/src/log4j-1.2.17.jar" />
- <classpathentry kind="lib" path="ext/slf4j-api-1.6.6.jar" sourcepath="ext/src/slf4j-api-1.6.6.jar" />
- <classpathentry kind="lib" path="ext/slf4j-log4j12-1.6.6.jar" sourcepath="ext/src/slf4j-log4j12-1.6.6.jar" />
+ <classpathentry kind="lib" path="ext/slf4j-api-1.7.5.jar" />
+ <classpathentry kind="lib" path="ext/slf4j-log4j12-1.7.5.jar" />
<classpathentry kind="lib" path="ext/mail-1.4.3.jar" sourcepath="ext/src/mail-1.4.3.jar" />
<classpathentry kind="lib" path="ext/javax.servlet-api-3.1.0.jar" sourcepath="ext/src/javax.servlet-api-3.1.0.jar" />
<classpathentry kind="lib" path="ext/jetty-all-9.1.4.v20140401.jar" sourcepath="ext/src/jetty-all-9.1.4.v20140401.jar" />
@@ -75,7 +75,7 @@
<classpathentry kind="lib" path="ext/args4j-2.0.26.jar" sourcepath="ext/src/args4j-2.0.26.jar" />
<classpathentry kind="lib" path="ext/jedis-2.3.1.jar" sourcepath="ext/src/jedis-2.3.1.jar" />
<classpathentry kind="lib" path="ext/commons-pool2-2.0.jar" sourcepath="ext/src/commons-pool2-2.0.jar" />
- <classpathentry kind="lib" path="ext/pf4j-0.7.1.jar" sourcepath="ext/src/pf4j-0.7.1.jar" />
+ <classpathentry kind="lib" path="ext/pf4j-0.8.0.jar" sourcepath="ext/src/pf4j-0.8.0.jar" />
<classpathentry kind="lib" path="ext/junit-4.11.jar" sourcepath="ext/src/junit-4.11.jar" />
<classpathentry kind="lib" path="ext/hamcrest-core-1.3.jar" sourcepath="ext/src/hamcrest-core-1.3.jar" />
<classpathentry kind="lib" path="ext/selenium-java-2.28.0.jar" sourcepath="ext/src/selenium-java-2.28.0.jar" />
diff --git a/build.moxie b/build.moxie
index 0f7ac81f..7b5aa210 100644
--- a/build.moxie
+++ b/build.moxie
@@ -131,8 +131,8 @@ dependencies:
# Standard dependencies
- compile 'com.intellij:annotations:12.0' :war
- compile 'log4j:log4j:1.2.17' :war :fedclient :authority
-- compile 'org.slf4j:slf4j-api:1.6.6' :war :fedclient :authority
-- compile 'org.slf4j:slf4j-log4j12:1.6.6' :war :fedclient :authority
+- compile 'org.slf4j:slf4j-api:1.7.5' :war :fedclient :authority
+- compile 'org.slf4j:slf4j-log4j12:1.7.5' :war :fedclient :authority
- compile 'javax.mail:mail:1.4.3' :war :authority
- compile 'javax.servlet:javax.servlet-api:3.1.0' :fedclient
- compile 'org.eclipse.jetty.aggregate:jetty-all:${jetty.version}' @jar
@@ -173,7 +173,7 @@ dependencies:
- compile 'args4j:args4j:2.0.26' :war :fedclient :authority
- compile 'commons-codec:commons-codec:1.7' :war
- compile 'redis.clients:jedis:2.3.1' :war
-- compile 'ro.fortsoft.pf4j:pf4j:0.7.1' :war
+- compile 'ro.fortsoft.pf4j:pf4j:0.8.0' :war
- test 'junit'
# Dependencies for Selenium web page testing
- test 'org.seleniumhq.selenium:selenium-java:${selenium.version}' @jar
diff --git a/gitblit.iml b/gitblit.iml
index 69bd8e46..48a1c226 100644
--- a/gitblit.iml
+++ b/gitblit.iml
@@ -80,25 +80,21 @@
</library>
</orderEntry>
<orderEntry type="module-library">
- <library name="slf4j-api-1.6.6.jar">
+ <library name="slf4j-api-1.7.5.jar">
<CLASSES>
- <root url="jar://$MODULE_DIR$/ext/slf4j-api-1.6.6.jar!/" />
+ <root url="jar://$MODULE_DIR$/ext/slf4j-api-1.7.5.jar!/" />
</CLASSES>
<JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/ext/src/slf4j-api-1.6.6.jar!/" />
- </SOURCES>
+ <SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
- <library name="slf4j-log4j12-1.6.6.jar">
+ <library name="slf4j-log4j12-1.7.5.jar">
<CLASSES>
- <root url="jar://$MODULE_DIR$/ext/slf4j-log4j12-1.6.6.jar!/" />
+ <root url="jar://$MODULE_DIR$/ext/slf4j-log4j12-1.7.5.jar!/" />
</CLASSES>
<JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/ext/src/slf4j-log4j12-1.6.6.jar!/" />
- </SOURCES>
+ <SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
@@ -780,13 +776,13 @@
</library>
</orderEntry>
<orderEntry type="module-library">
- <library name="pf4j-0.7.1.jar">
+ <library name="pf4j-0.8.0.jar">
<CLASSES>
- <root url="jar://$MODULE_DIR$/ext/pf4j-0.7.1.jar!/" />
+ <root url="jar://$MODULE_DIR$/ext/pf4j-0.8.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$MODULE_DIR$/ext/src/pf4j-0.7.1.jar!/" />
+ <root url="jar://$MODULE_DIR$/ext/src/pf4j-0.8.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
diff --git a/releases.moxie b/releases.moxie
index f683f2bd..15d333d4 100644
--- a/releases.moxie
+++ b/releases.moxie
@@ -21,8 +21,10 @@ r22: {
- Repository mailing lists could not be reset from the Edit Repository page (issue-399)
- Fix intermittent NPE in determining commit date in RefModel (issue-401)
- Fix closing ticket on push by parsing commit messages for closes|fixes (issue-404)
+ - Fix diffstat display for a ticket with a pending submodule change (issue-407)
- Ensure the Lucene ticket index is updated on repository deletion.
- Fixed failure to properly determine hasTicket in RedisTicketService
+ - Fixed handling of pushing ticket branch deletions
changes:
- Switch from GoogleCharts to self-hosted flotr2 charts (issue-283, ticket-43, pr-166)
- Specify the --dailyLogFile option for the Ubuntu and CentOS service scripts (issue-348)
@@ -47,7 +49,8 @@ r22: {
- args4j 2.0.26
- JGit 3.3.1
- Mina SSHD 0.10.1
- - pf4j 0.7.1
+ - pf4j 0.8.0
+ - SLF4J 1.7.5
contributors:
- James Moger
- David Ostrovsky
@@ -55,6 +58,8 @@ r22: {
- Jeremie Brebec
- Tim Ryan
- Decebal Suiu
+ - Eric Myrhe
+ - Kevin Walter
settings:
- { name: 'realm.ldap.bindpattern', defaultValue: ' ' }
- { name: 'tickets.closeOnPushCommitMessageRegex', defaultValue: '(?:fixes|closes)[\\s-]+#?(\\d+)' }
diff --git a/src/main/java/com/gitblit/DaggerModule.java b/src/main/java/com/gitblit/DaggerModule.java
index e448867a..b89f8c44 100644
--- a/src/main/java/com/gitblit/DaggerModule.java
+++ b/src/main/java/com/gitblit/DaggerModule.java
@@ -185,6 +185,7 @@ public class DaggerModule {
@Provides @Singleton GitBlitWebApp provideWebApplication(
IRuntimeManager runtimeManager,
+ IPluginManager pluginManager,
INotificationManager notificationManager,
IUserManager userManager,
IAuthenticationManager authenticationManager,
@@ -196,6 +197,7 @@ public class DaggerModule {
return new GitBlitWebApp(
runtimeManager,
+ pluginManager,
notificationManager,
userManager,
authenticationManager,
diff --git a/src/test/java/com/gitblit/tests/ActivityTest.java b/src/main/java/com/gitblit/extensions/GitblitPlugin.java
index b7382b87..129f584c 100644
--- a/src/test/java/com/gitblit/tests/ActivityTest.java
+++ b/src/main/java/com/gitblit/extensions/GitblitPlugin.java
@@ -1,32 +1,27 @@
-/*
- * Copyright 2011 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.tests;
-
-import java.io.IOException;
-
-import org.junit.Test;
-
-import com.gitblit.models.GravatarProfile;
-import com.gitblit.utils.ActivityUtils;
-
-public class ActivityTest extends GitblitUnitTest {
-
- @Test
- public void testGravatarProfile() throws IOException {
- GravatarProfile profile = ActivityUtils.getGravatarProfile("beau@dentedreality.com.au");
- assertEquals("beau", profile.preferredUsername);
- }
-} \ No newline at end of file
+/*
+ * 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 ro.fortsoft.pf4j.Plugin;
+import ro.fortsoft.pf4j.PluginWrapper;
+
+public abstract class GitblitPlugin extends Plugin {
+
+ public GitblitPlugin(PluginWrapper wrapper) {
+ super(wrapper);
+ }
+
+}
diff --git a/src/main/java/com/gitblit/git/PatchsetReceivePack.java b/src/main/java/com/gitblit/git/PatchsetReceivePack.java
index 77d5a71e..43efc54a 100644
--- a/src/main/java/com/gitblit/git/PatchsetReceivePack.java
+++ b/src/main/java/com/gitblit/git/PatchsetReceivePack.java
@@ -309,6 +309,7 @@ public class PatchsetReceivePack extends GitblitReceivePack {
}
if (isPatchsetRef(cmd.getRefName()) && processPatchsets) {
+
if (ticketService == null) {
sendRejection(cmd, "Sorry, the ticket service is unavailable and can not accept patchsets at this time.");
continue;
@@ -346,6 +347,20 @@ public class PatchsetReceivePack extends GitblitReceivePack {
continue;
}
+ if (cmd.getNewId().equals(ObjectId.zeroId())) {
+ // ref deletion request
+ if (cmd.getRefName().startsWith(Constants.R_TICKET)) {
+ if (user.canDeleteRef(repository)) {
+ batch.addCommand(cmd);
+ } else {
+ sendRejection(cmd, "Sorry, you do not have permission to delete {}", cmd.getRefName());
+ }
+ } else {
+ sendRejection(cmd, "Sorry, you can not delete {}", cmd.getRefName());
+ }
+ continue;
+ }
+
if (patchsetRefCmd != null) {
sendRejection(cmd, "You may only push one patchset at a time.");
continue;
diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java
index 56a71d41..4ecb9c6d 100644
--- a/src/main/java/com/gitblit/manager/GitblitManager.java
+++ b/src/main/java/com/gitblit/manager/GitblitManager.java
@@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
import ro.fortsoft.pf4j.PluginState;
import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.Version;
import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
@@ -1190,6 +1191,11 @@ public class GitblitManager implements IGitblit {
*/
@Override
+ public Version getSystemVersion() {
+ return pluginManager.getSystemVersion();
+ }
+
+ @Override
public void startPlugins() {
pluginManager.startPlugins();
}
diff --git a/src/main/java/com/gitblit/manager/IPluginManager.java b/src/main/java/com/gitblit/manager/IPluginManager.java
index 317cff73..bf04619c 100644
--- a/src/main/java/com/gitblit/manager/IPluginManager.java
+++ b/src/main/java/com/gitblit/manager/IPluginManager.java
@@ -20,6 +20,7 @@ import java.util.List;
import ro.fortsoft.pf4j.PluginState;
import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.Version;
import com.gitblit.models.PluginRegistry.InstallState;
import com.gitblit.models.PluginRegistry.PluginRegistration;
@@ -28,6 +29,13 @@ import com.gitblit.models.PluginRegistry.PluginRelease;
public interface IPluginManager extends IManager {
/**
+ * Returns the system version.
+ *
+ * @return the system version
+ */
+ Version getSystemVersion();
+
+ /**
* Starts all plugins.
*/
void startPlugins();
diff --git a/src/main/java/com/gitblit/manager/PluginManager.java b/src/main/java/com/gitblit/manager/PluginManager.java
index b2a87ab3..405dc510 100644
--- a/src/main/java/com/gitblit/manager/PluginManager.java
+++ b/src/main/java/com/gitblit/manager/PluginManager.java
@@ -42,9 +42,10 @@ import ro.fortsoft.pf4j.PluginClassLoader;
import ro.fortsoft.pf4j.PluginState;
import ro.fortsoft.pf4j.PluginStateEvent;
import ro.fortsoft.pf4j.PluginStateListener;
-import ro.fortsoft.pf4j.PluginVersion;
import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.Version;
+import com.gitblit.Constants;
import com.gitblit.Keys;
import com.gitblit.models.PluginRegistry;
import com.gitblit.models.PluginRegistry.InstallState;
@@ -63,6 +64,7 @@ import com.google.common.io.InputSupplier;
* the Dagger DI and retrieve extensions provided by active plugins.
*
* @author David Ostrovsky
+ * @author James Moger
*
*/
public class PluginManager implements IPluginManager, PluginStateListener {
@@ -82,7 +84,20 @@ public class PluginManager implements IPluginManager, PluginStateListener {
File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
dir.mkdirs();
this.runtimeManager = runtimeManager;
+
this.pf4j = new DefaultPluginManager(dir);
+
+ try {
+ Version systemVersion = Version.createVersion(Constants.getVersion());
+ pf4j.setSystemVersion(systemVersion);
+ } catch (Exception e) {
+ logger.error(null, e);
+ }
+ }
+
+ @Override
+ public Version getSystemVersion() {
+ return pf4j.getSystemVersion();
}
@Override
@@ -130,6 +145,7 @@ public class PluginManager implements IPluginManager, PluginStateListener {
return PluginState.STARTED.equals(state);
}
+ @Override
public synchronized boolean upgradePlugin(String pluginId, String url, boolean verifyChecksum) throws IOException {
// ensure we can download the update BEFORE we remove the existing one
File file = download(url, verifyChecksum);
@@ -185,7 +201,6 @@ public class PluginManager implements IPluginManager, PluginStateListener {
(file.getName().toLowerCase().endsWith(".sha1")
|| file.getName().toLowerCase().endsWith(".md5"));
}
-
});
if (checksums != null) {
@@ -322,7 +337,7 @@ public class PluginManager implements IPluginManager, PluginStateListener {
for (PluginWrapper pw : pf4j.getPlugins()) {
String id = pw.getDescriptor().getPluginId();
- PluginVersion pv = pw.getDescriptor().getVersion();
+ Version pv = pw.getDescriptor().getVersion();
PluginRegistration reg = map.get(id);
if (reg != null) {
reg.installedRelease = pv.toString();
diff --git a/src/main/java/com/gitblit/models/GravatarProfile.java b/src/main/java/com/gitblit/models/GravatarProfile.java
deleted file mode 100644
index ec1aeea3..00000000
--- a/src/main/java/com/gitblit/models/GravatarProfile.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2011 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.models;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * Represents a Gravatar profile.
- *
- * @author James Moger
- *
- */
-public class GravatarProfile implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- public String id;
- public String hash;
- public String requestHash;
- public String displayName;
- public String preferredUsername;
- public String currentLocation;
- public String aboutMe;
-
- public String profileUrl;
- public String thumbnailUrl;
- public List<ProfileObject> photos;
-// public Map<String, String> profileBackground;
-// public Map<String, String> name;
-
- public List<ProfileObject> phoneNumbers;
- public List<ProfileObject> emails;
- public List<ProfileObject> ims;
- public List<Account> accounts;
- public List<ProfileObject> urls;
-
- public static class ProfileObject implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- public String title;
- public String type;
- public String value;
- public boolean primary;
-
- @Override
- public String toString() {
- return value;
- }
- }
-
- public static class Account implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- public String domain;
- public String display;
- public String url;
- public String username;
- public String userid;
- public boolean verified;
- public String shortname;
-
- @Override
- public String toString() {
- return display;
- }
- }
-}
diff --git a/src/main/java/com/gitblit/models/PluginRegistry.java b/src/main/java/com/gitblit/models/PluginRegistry.java
index 7c1927f5..ef463163 100644
--- a/src/main/java/com/gitblit/models/PluginRegistry.java
+++ b/src/main/java/com/gitblit/models/PluginRegistry.java
@@ -23,7 +23,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.parboiled.common.StringUtils;
-import ro.fortsoft.pf4j.PluginVersion;
+import ro.fortsoft.pf4j.Version;
/**
* Represents a list of plugin registrations.
@@ -125,8 +125,8 @@ public class PluginRegistry implements Serializable {
if (StringUtils.isEmpty(installedRelease)) {
return InstallState.NOT_INSTALLED;
}
- PluginVersion ir = PluginVersion.createVersion(installedRelease);
- PluginVersion cr = PluginVersion.createVersion(currentRelease);
+ Version ir = Version.createVersion(installedRelease);
+ Version cr = Version.createVersion(currentRelease);
switch (ir.compareTo(cr)) {
case -1:
return InstallState.UNKNOWN;
@@ -151,7 +151,7 @@ public class PluginRegistry implements Serializable {
@Override
public int compareTo(PluginRelease o) {
- return PluginVersion.createVersion(version).compareTo(PluginVersion.createVersion(o.version));
+ return Version.createVersion(version).compareTo(Version.createVersion(o.version));
}
}
}
diff --git a/src/main/java/com/gitblit/servlet/GitblitContext.java b/src/main/java/com/gitblit/servlet/GitblitContext.java
index 553651da..b865750b 100644
--- a/src/main/java/com/gitblit/servlet/GitblitContext.java
+++ b/src/main/java/com/gitblit/servlet/GitblitContext.java
@@ -177,7 +177,6 @@ public class GitblitContext extends DaggerContext {
managers.add(runtime);
// start all other managers
- startManager(injector, IPluginManager.class);
startManager(injector, INotificationManager.class);
startManager(injector, IUserManager.class);
startManager(injector, IAuthenticationManager.class);
@@ -187,6 +186,10 @@ public class GitblitContext extends DaggerContext {
startManager(injector, IFederationManager.class);
startManager(injector, IGitblit.class);
+ // start the plugin manager last so that plugins can depend on
+ // deterministic access to all other managers in their start() methods
+ startManager(injector, IPluginManager.class);
+
logger.info("");
logger.info("All managers started.");
logger.info("");
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 f5b68548..37649ead 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
@@ -27,6 +27,7 @@ import ro.fortsoft.pf4j.PluginDependency;
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;
@@ -35,6 +36,7 @@ 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;
/**
@@ -75,7 +77,7 @@ public class PluginDispatcher extends DispatchCommand {
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"};
@@ -86,7 +88,7 @@ public class PluginDispatcher extends DispatchCommand {
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() };
}
@@ -100,7 +102,7 @@ public class PluginDispatcher extends DispatchCommand {
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());
}
@@ -157,7 +159,7 @@ public class PluginDispatcher extends DispatchCommand {
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()));
}
}
}
@@ -185,7 +187,7 @@ public class PluginDispatcher extends DispatchCommand {
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()));
}
}
}
@@ -208,7 +210,7 @@ public class PluginDispatcher extends DispatchCommand {
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()));
}
}
}
@@ -230,7 +232,7 @@ public class PluginDispatcher extends DispatchCommand {
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()));
}
}
}
@@ -258,9 +260,9 @@ public class PluginDispatcher extends DispatchCommand {
protected String buildFieldTable(PluginWrapper pw, PluginRegistration reg) {
final String id = pw == null ? reg.id : pw.getPluginId();
- final String description = reg == null ? ""/*pw.getDescriptor().getDescription()*/ : reg.description;
+ final String description = reg == null ? pw.getDescriptor().getPluginDescription() : 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 requires = pw == null ? reg.getCurrentRelease().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();
@@ -516,22 +518,35 @@ public class PluginDispatcher extends DispatchCommand {
if (gitblit.installPlugin(urlOrId, !disableChecksum)) {
stdout.println(String.format("Installed %s", urlOrId));
} else {
- new Failure(1, String.format("Failed to install %s", urlOrId));
+ new UnloggedFailure(1, String.format("Failed to install %s", urlOrId));
}
} else {
- PluginRelease pv = gitblit.lookupRelease(urlOrId, version);
- if (pv == null) {
- throw new Failure(1, String.format("Plugin \"%s\" is not in the registry!", urlOrId));
+ 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)) {
+
+ // 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", urlOrId));
+ throw new UnloggedFailure(1, String.format("Failed to install %s", urlOrId));
}
}
} catch (IOException e) {
log.error("Failed to install " + urlOrId, e);
- throw new Failure(1, String.format("Failed to install %s", urlOrId), e);
+ throw new UnloggedFailure(1, String.format("Failed to install %s", urlOrId), e);
}
}
}
@@ -556,20 +571,31 @@ public class PluginDispatcher extends DispatchCommand {
throw new UnloggedFailure("Invalid plugin specified!");
}
- PluginRelease pv = gitblit.lookupRelease(pluginWrapper.getPluginId(), version);
- if (pv == null) {
- throw new Failure(1, String.format("Plugin \"%s\" is not in the registry!", pluginWrapper.getPluginId()));
+ 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(), pv.url, !disableChecksum)) {
+ if (gitblit.upgradePlugin(pluginWrapper.getPluginId(), pr.url, !disableChecksum)) {
stdout.println(String.format("Upgraded %s", pluginWrapper.getPluginId()));
} else {
- throw new Failure(1, String.format("Failed to upgrade %s", pluginWrapper.getPluginId()));
+ 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 Failure(1, String.format("Failed to upgrade %s", pluginWrapper.getPluginId()), e);
+ throw new UnloggedFailure(1, String.format("Failed to upgrade %s", pluginWrapper.getPluginId()), e);
}
}
}
@@ -591,7 +617,7 @@ public class PluginDispatcher extends DispatchCommand {
if (gitblit.deletePlugin(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()));
}
}
}
diff --git a/src/main/java/com/gitblit/utils/ActivityUtils.java b/src/main/java/com/gitblit/utils/ActivityUtils.java
index 3a54d33f..ba5599a1 100644
--- a/src/main/java/com/gitblit/utils/ActivityUtils.java
+++ b/src/main/java/com/gitblit/utils/ActivityUtils.java
@@ -15,9 +15,6 @@
*/
package com.gitblit.utils;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
@@ -38,11 +35,9 @@ import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.models.Activity;
-import com.gitblit.models.GravatarProfile;
import com.gitblit.models.RefModel;
import com.gitblit.models.RepositoryCommit;
import com.gitblit.models.RepositoryModel;
-import com.google.gson.reflect.TypeToken;
/**
* Utility class for building activity information from repositories.
@@ -162,19 +157,6 @@ public class ActivityUtils {
}
/**
- * Returns the Gravatar profile, if available, for the specified email
- * address.
- *
- * @param emailaddress
- * @return a Gravatar Profile
- * @throws IOException
- */
- public static GravatarProfile getGravatarProfileFromAddress(String emailaddress)
- throws IOException {
- return getGravatarProfile(StringUtils.getMD5(emailaddress.toLowerCase()));
- }
-
- /**
* Creates a Gravatar thumbnail url from the specified email address.
*
* @param email
@@ -211,32 +193,4 @@ public class ActivityUtils {
"https://www.gravatar.com/avatar/{0}?s={1,number,0}&d=mm", emailHash, width);
return url;
}
-
- /**
- * Returns the Gravatar profile, if available, for the specified hashcode.
- * address.
- *
- * @param hash
- * the hash of the email address
- * @return a Gravatar Profile
- * @throws IOException
- */
- public static GravatarProfile getGravatarProfile(String hash) throws IOException {
- String url = MessageFormat.format("https://www.gravatar.com/{0}.json", hash);
- // Gravatar has a complex json structure
- Type profileType = new TypeToken<Map<String, List<GravatarProfile>>>() {
- }.getType();
- Map<String, List<GravatarProfile>> profiles = null;
- try {
- profiles = JsonUtils.retrieveJson(url, profileType);
- } catch (FileNotFoundException e) {
- }
- if (profiles == null || profiles.size() == 0) {
- return null;
- }
- // due to the complex json structure we need to pull out the profile
- // from a list 2 levels deep
- GravatarProfile profile = profiles.values().iterator().next().get(0);
- return profile;
- }
}
diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
index 6e8aa05f..58fc5b7a 100644
--- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
+++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
@@ -34,6 +34,7 @@ import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IFederationManager;
import com.gitblit.manager.IGitblit;
import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
@@ -90,6 +91,8 @@ public class GitBlitWebApp extends WebApplication {
private final IRuntimeManager runtimeManager;
+ private final IPluginManager pluginManager;
+
private final INotificationManager notificationManager;
private final IUserManager userManager;
@@ -108,6 +111,7 @@ public class GitBlitWebApp extends WebApplication {
public GitBlitWebApp(
IRuntimeManager runtimeManager,
+ IPluginManager pluginManager,
INotificationManager notificationManager,
IUserManager userManager,
IAuthenticationManager authenticationManager,
@@ -120,6 +124,7 @@ public class GitBlitWebApp extends WebApplication {
super();
this.settings = runtimeManager.getSettings();
this.runtimeManager = runtimeManager;
+ this.pluginManager = pluginManager;
this.notificationManager = notificationManager;
this.userManager = userManager;
this.authenticationManager = authenticationManager;
@@ -273,6 +278,10 @@ public class GitBlitWebApp extends WebApplication {
return runtimeManager;
}
+ public IPluginManager plugins() {
+ return pluginManager;
+ }
+
public INotificationManager notifier() {
return notificationManager;
}
diff --git a/src/site/plugins_extensions.mkd b/src/site/plugins_extensions.mkd
index d7469ac6..6e0e52e6 100644
--- a/src/site/plugins_extensions.mkd
+++ b/src/site/plugins_extensions.mkd
@@ -2,20 +2,56 @@
Gitblit offers several extension points for enhancing and customizing it's runtime behavior.
-Each available extension point has a sample implementation in the [gitblit-cookbook-plugin (Maven project)](https://dev.gitblit.com/summary/gitblit-cookbook-plugin.git).
+Each available extension point has a sample implementation in the [gitblit-cookbook-plugin (Maven project)](https://github.com/gitblit/gitblit-cookbook-plugin).
+
+**NOTE:**
+Gitblit does not yet offer a comprehensize dependency injection architecture. This will be addressed in a subsequent release. For now you may access all of Gitblit's core managers through a static singleton app context:
+
+```java
+import com.gitblit.extensions.GitblitPlugin;
+import com.gitblit.servlet.GitblitContext;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IUserManager;
+import com.gitblit.manager.IAuthenticationManager;
+import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IRepositoryManager;
+import com.gitblit.manager.IProjectManager;
+import com.gitblit.manager.IFederationManager;
+import com.gitblit.manager.IPluginManager;
+import com.gitblit.manager.IGitblit;
+
+public class ExamplePlugin extends GitblitPlugin {
+
+ @Override
+ public void start() {
+ IRuntimeManager runtime = GitblitContext.getManager(IRuntimeManager.class);
+ IUserManager users = GitblitContext.getManager(IUserManager.class);
+ IAuthenticationManager auth = GitblitContext.getManager(IAuthenticationManager.class);
+ INotificationManager notifications = GitblitContext.getManager(INotificationManager.class);
+ IRepositoryManager repos = GitblitContext.getManager(IRepositoryManager.class);
+ IProjectManager projects = GitblitContext.getManager(IProjectManager.class);
+ IFederationManager federation = GitblitContext.getManager(IFederationManager.class);
+ IPluginManager plugins = GitblitContext.getManager(IPluginManager.class);
+ IGitblit gitblit = GitblitContext.getManager(IGitblit.class);
+ }
+}
+```
### SSH Dispatch Command
*SINCE 1.5.0*
-You can provide your own custom SSH commands by subclassing the *DispatchCommand* class.
+You can provide your own custom SSH command hierarchies by subclassing the *DispatchCommand* class.
```java
import ro.fortsoft.pf4j.Extension;
-
+import org.kohsuke.args4j.Option;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.gitblit.models.UserModel;
import com.gitblit.transport.ssh.commands.CommandMetaData;
import com.gitblit.transport.ssh.commands.DispatchCommand;
+import com.gitblit.transport.ssh.commands.UsageExample;
@Extension
@CommandMetaData(name = "mycommands", description = "Sample SSH dispatcher")
@@ -31,6 +67,25 @@ public class MyDispatcher extends DispatchCommand {
register(user, SubDispatcher1.class);
register(user, SubDispatcher2.class);
}
+
+ @CommandMetaData(name = "commanda", aliases = { "ca" }, description = "description of command a")
+ @UsageExample(syntax = "${cmd} --myflag", description = "description of commanda with --myflag")
+ public static class CommandA extends SshCommand {
+
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Option(name = "--myflag", aliases = { "-m" }, usage = "enable myflag")
+ boolean myflag;
+
+ @Override
+ public void run() throws Failure {
+ if (myflag) {
+ log.info("Run with --myflag");
+ } else {
+ log.info("Run without --myflag");
+ }
+ }
+ }
}
```
diff --git a/src/site/plugins_overview.mkd b/src/site/plugins_overview.mkd
index 5cb60d07..45a54344 100644
--- a/src/site/plugins_overview.mkd
+++ b/src/site/plugins_overview.mkd
@@ -23,6 +23,7 @@ A plugin defines it's metadata in the META-INF/MANIFEST.MF file:
Plugin-Description: Command and control Gitblit over SSH
Plugin-Class: com.gitblit.plugin.powertools.Powertools
Plugin-Version: 1.2.0
+ Plugin-Requires: 1.5.0
Plugin-Provider: gitblit.com
In addition to extending Gitblit core, plugins can also define extension points that may be implemented by other plugins. Therefore a plugin may depend on other plugins.
@@ -32,9 +33,9 @@ In addition to extending Gitblit core, plugins can also define extension points
**NOTE:**
The pf4j plugin framework relies on a javac apt processor to generate compile-time extension information, so be sure to enable apt processing in your build process.
-#### Limitations of Dependencies & Requires
+#### Limitations of Dependencies
-Plugins may specify dependencies by ID, but may not specify specific versions of a dependency. The plugin registry allows you to specify a *requires* version of Gitblit, but this is not currently enforced.
+Plugins may specify dependencies by ID, but may not specify specific versions of a dependency.
### Managing Plugins
diff --git a/src/site/setup_transport_ssh.mkd b/src/site/setup_transport_ssh.mkd
index a671e5af..7b53624b 100644
--- a/src/site/setup_transport_ssh.mkd
+++ b/src/site/setup_transport_ssh.mkd
@@ -80,7 +80,14 @@ You can also remove all your public keys from your account.
ssh -l <username> -p 29418 <hostname> keys remove ALL
-### SSH Command Plugins
+##### keys permission
+
+You may control the access permission for each SSH key. This is more of a safety feature than a security measure.
+
+| Permission | Description |
+| ---------- | ----------------------------------------------- |
+| V | SSH key may not be used for clone/fetch or push |
+| R | SSH key may be used to clone/fetch |
+| RW | SSH key may be used to clone/fetch and push |
-Gitblit supports loading custom SSH command plugins.