Top menu improvements
* Add a "browse" link for screens with a project context (fixes
https://code.google.com/p/gerrit/issues/detail?id=2335 using a
new feature in Gerrit 2.11).
* Make all the submenu item titles configurable in a [plugin "gitblit"]
section in gerrit.config.
* Update init step to account for that.
Change-Id: Id43eb206f32499ef0cb3703808e331ea18afcc29
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java
index 329ef60..99cd6de 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java
@@ -13,24 +13,31 @@
// limitations under the License.
package com.googlesource.gerrit.plugins.gitblit;
+import org.eclipse.jgit.lib.Config;
+
import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.pgm.init.api.ConsoleUI;
+import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.pgm.init.api.Section.Factory;
-import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.inject.Inject;
public class GitBlitInitStep implements InitStep {
private final ConsoleUI ui;
private final String pluginName;
private final Factory sections;
+ private final Config cfg;
@Inject
- public GitBlitInitStep(final ConsoleUI ui, final Section.Factory sections,
- @PluginName final String pluginName) {
+ public GitBlitInitStep(ConsoleUI ui,
+ Section.Factory sections,
+ @PluginName String pluginName,
+ InitFlags flags) {
this.ui = ui;
this.pluginName = pluginName;
this.sections = sections;
+ this.cfg = flags.cfg;
}
@Override
@@ -41,21 +48,68 @@
if(ui.yesno(true, "Do you want to use GitBlit as your GitWeb viewer ?")) {
configureGitBlit();
}
+ // If we don't use GitBlit here, we leave a potential [plugin "gitblit"]
+ // section in the config. It won't hurt,
+ // and maybe the user will later re-enable GitBlit, and then he'd be
+ // surprised if his customized settings were
+ // gone.
}
private void configureGitBlit() {
+ initGitWebConfig();
+ initGitBlitPluginConfig();
+ }
+
+ private void initGitWebConfig() {
Section gitWeb = sections.get("gitweb", null);
gitWeb.set("type", "custom");
gitWeb.set("url", "plugins/");
gitWeb.set("project", pluginName + "/summary/?r=${project}");
gitWeb.set("revision", pluginName + "/commit/?r=${project}&h=${commit}");
gitWeb.set("branch", pluginName + "/log/?r=${project}&h=${branch}");
- gitWeb.set("filehistory", pluginName + "/history/?f=${file}&r=${project}&h=${branch}");
- gitWeb.set("file", pluginName + "/blob/?r=${project}&h=${commit}&f=${file}");
+ gitWeb.set("filehistory", pluginName
+ + "/history/?f=${file}&r=${project}&h=${branch}");
+ gitWeb
+ .set("file", pluginName + "/blob/?r=${project}&h=${commit}&f=${file}");
gitWeb.set("roottree", pluginName + "/tree/?r=${project}&h=${commit}");
gitWeb.string("Link name", "linkname", "GitBlit");
}
+ private void initGitBlitPluginConfig() {
+ Section pluginCfg = sections.get("plugin", pluginName);
+ // These values are displayed in the UI.
+ pluginCfg.string("\"Repositories\" submenu title", "repositories",
+ "Repositories", true);
+ pluginCfg
+ .string("\"Activity\" submenu title", "activity", "Activity", true);
+ String originalValue = pluginCfg.get("search");
+ if (originalValue == null) {
+ pluginCfg
+ .string(
+ "\"Search\" submenu title (makes only sense to set if some projects are indexed in GitBlit)",
+ "search", "", true);
+ } else {
+ String newValue =
+ ui.readString(
+ originalValue,
+ "%s",
+ "\"Search\" submenu title (makes only sense to set if some projects are indexed in GitBlit; single dash unsets)");
+ if (newValue == null || "-".equals(newValue)) {
+ pluginCfg.unset("search");
+ } else if (!originalValue.equals(newValue)) {
+ pluginCfg.set("search", newValue);
+ }
+ }
+ pluginCfg.string(
+ "\"Browse\" submenu title for the \"Projects\" top-level menu",
+ "browse", "Browse", true);
+ // If everything is at the default, then make sure we don't have the section
+ // at all.
+ if (cfg.getNames("plugin", pluginName).isEmpty()) {
+ cfg.unsetSection("plugin", pluginName);
+ }
+ }
+
@Override
public void postRun() throws Exception {
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitTopMenu.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitTopMenu.java
index b4e5778..5041708 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitTopMenu.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitTopMenu.java
@@ -17,45 +17,68 @@
import java.util.Arrays;
import java.util.List;
+import com.google.common.collect.Lists;
import com.google.gerrit.extensions.annotations.Listen;
+import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.client.GerritTopMenu;
import com.google.gerrit.extensions.webui.TopMenu;
-import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.config.PluginConfig;
+import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
@Listen
public class GitBlitTopMenu implements TopMenu {
+
+ // Not configurable to avoid mis-configurations clashing with predefined top
+ // menus.
+ private static final String GITBLIT_TOPMENU_NAME = "GitBlit";
+
private final MenuEntry fullMenuEntries;
private final MenuEntry restrictedMenuEntries;
+ private final MenuEntry extraProjectEntries;
private final Provider<CurrentUser> userProvider;
@Inject
- public GitBlitTopMenu(final @PluginName String pluginName,
- final Provider<CurrentUser> userProvider) {
+ public GitBlitTopMenu(@PluginName String pluginName,
+ @PluginCanonicalWebUrl String pluginUrl,
+ Provider<CurrentUser> userProvider,
+ PluginConfigFactory cfgProvider) {
this.userProvider = userProvider;
- String gitBlitBaseUrl = "/plugins/" + pluginName + "/";
- this.restrictedMenuEntries =
- menu("Gitblit", item("Repositories", gitBlitBaseUrl + "repositories/"));
- this.fullMenuEntries =
- menu("GitBlit", item("Repositories", gitBlitBaseUrl + "repositories/"),
- item("Activity", gitBlitBaseUrl + "activity/"),
- item("Search", gitBlitBaseUrl + "lucene/"));
- }
-
- private MenuEntry menu(String name, MenuItem... items) {
- return new MenuEntry(name, Arrays.asList(items));
- }
-
- private MenuItem item(String name, String url) {
- return new MenuItem(name, url, "");
+ String gitBlitBaseUrl = pluginUrl;
+ PluginConfig cfg = cfgProvider.getFromGerritConfig(pluginName, true);
+ // We don't have to worry about XSS here; the way these menu item get
+ // created through GWT ensures that these values read from the config
+ // end up as text nodes in the DOM, even if they contain potentially
+ // malicious code. So if somebody sets these values to some HTML snippet,
+ // he'll simply end up with a funny looking menu item, but he can't inject
+ // things here.
+ MenuItem repositories =
+ new MenuItem(cfg.getString("repositories", "Repositories"),
+ gitBlitBaseUrl + "repositories/", "");
+ restrictedMenuEntries =
+ new MenuEntry(GITBLIT_TOPMENU_NAME, Arrays.asList(repositories));
+ List<MenuItem> fullMenuItems = Lists.newArrayList();
+ fullMenuItems.add(repositories);
+ fullMenuItems.add(new MenuItem(cfg.getString("activity", "Activity"),
+ gitBlitBaseUrl + "activity/", ""));
+ String search = cfg.getString("search");
+ if (search != null && !search.isEmpty()) {
+ fullMenuItems.add(new MenuItem(search, gitBlitBaseUrl + "lucene/", ""));
+ }
+ fullMenuEntries = new MenuEntry(GITBLIT_TOPMENU_NAME, fullMenuItems);
+ extraProjectEntries =
+ new MenuEntry(GerritTopMenu.PROJECTS, Arrays.asList(new MenuItem(cfg
+ .getString("browse", "Browse"), gitBlitBaseUrl
+ + "summary?r=${projectName}", "")));
}
@Override
public List<MenuEntry> getEntries() {
- return Arrays.asList(userProvider.get() instanceof AnonymousUser
- ? restrictedMenuEntries : fullMenuEntries);
+ return Arrays.asList(userProvider.get().isIdentifiedUser()
+ ? fullMenuEntries : restrictedMenuEntries, extraProjectEntries);
}
}