Add new extension point for clone commands
The clone commands can be retrieved via REST from the
/config/server/info endpoint.
Bug: Issue 2208
Change-Id: I1a6bcc8eeea38ca30061bb380266e3b5cf7d3515
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index a86c1fd..5a5028d 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -1767,15 +1767,17 @@
[[download-commands]]
== Download Commands
-Gerrit offers commands for downloading changes using different
-download schemes (e.g. for downloading via different network
-protocols). Plugins can contribute download schemes and download
-commands by implementing
-`com.google.gerrit.extensions.config.DownloadScheme` and
-`com.google.gerrit.extensions.config.DownloadCommand`.
+Gerrit offers commands for downloading changes and cloning projects
+using different download schemes (e.g. for downloading via different
+network protocols). Plugins can contribute download schemes, download
+commands and clone commands by implementing
+`com.google.gerrit.extensions.config.DownloadScheme`,
+`com.google.gerrit.extensions.config.DownloadCommand` and
+`com.google.gerrit.extensions.config.CloneCommand`.
-The download schemes and download commands which are used most often
-are provided by the Gerrit core plugin `download-commands`.
+The download schemes, download commands and clone commands which are
+used most often are provided by the Gerrit core plugin
+`download-commands`.
[[included-in]]
== Included In
diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt
index cf49b3a..ece7450 100644
--- a/Documentation/rest-api-config.txt
+++ b/Documentation/rest-api-config.txt
@@ -68,6 +68,10 @@
"Format Patch": "git fetch http://gerrithost:8080/${project} ${ref} \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD",
"Pull": "git pull http://gerrithost:8080/${project} ${ref}",
"Cherry Pick": "git fetch http://gerrithost:8080/${project} ${ref} \u0026\u0026 git cherry-pick FETCH_HEAD"
+ },
+ "clone_commands": {
+ "Clone": "git clone http://gerrithost:8080/${project}"
+ "Clone with commit-msg hook": "git clone http://gerrithost:8080/${project} \u0026\u0026 scp -p -P 29418 jdoe@gerrithost:hooks/commit-msg ${project}/.git/hooks/"
}
},
"http": {
@@ -79,6 +83,10 @@
"Format Patch": "git fetch http://jdoe@gerrithost:8080/${project} ${ref} \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD",
"Pull": "git pull http://jdoe@gerrithost:8080/${project} ${ref}",
"Cherry Pick": "git fetch http://jdoe@gerrithost:8080/${project} ${ref} \u0026\u0026 git cherry-pick FETCH_HEAD"
+ },
+ "clone_commands": {
+ "Clone": "git clone http://jdoe@gerrithost:8080/${project}",
+ "Clone with commit-msg hook": "git clone http://jdoe@gerrithost:8080/${project} \u0026\u0026 scp -p -P 29418 jdoe@gerrithost:hooks/commit-msg ${project}/.git/hooks/"
}
},
"ssh": {
@@ -90,6 +98,10 @@
"Format Patch": "git fetch ssh://jdoe@gerrithost:29418/${project} ${ref} \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD",
"Pull": "git pull ssh://jdoe@gerrithost:29418/${project} ${ref}",
"Cherry Pick": "git fetch ssh://jdoe@gerrithost:29418/${project} ${ref} \u0026\u0026 git cherry-pick FETCH_HEAD"
+ },
+ "clone_commands": {
+ "Clone": "git clone ssh://jdoe@gerrithost:29418/${project}",
+ "Clone with commit-msg hook": "git clone ssh://jdoe@gerrithost:29418/${project} \u0026\u0026 scp -p -P 29418 jdoe@gerrithost:hooks/commit-msg ${project}/.git/hooks/"
}
}
],
@@ -1092,6 +1104,13 @@
Empty, if accessed anonymously and the download scheme requires
authentication.
+|`clone_commands` ||
+Clone commands as a map which maps the command name to the clone
+command. In the clone command '${project}' is used as
+placeholder for the project name.
+
+Empty, if accessed anonymously and the download scheme requires
+authentication.
|=================================
[[entries-info]]
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/config/CloneCommand.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/config/CloneCommand.java
new file mode 100644
index 0000000..f773380
--- /dev/null
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/config/CloneCommand.java
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// 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.google.gerrit.extensions.config;
+
+import com.google.gerrit.extensions.annotations.ExtensionPoint;
+
+@ExtensionPoint
+public abstract class CloneCommand {
+ /**
+ * Returns the clone command for the given download scheme and project.
+ *
+ * @param scheme the download scheme for which the command should be returned
+ * @param project the name of the project for which the clone command
+ * should be returned
+ * @return the clone command
+ */
+ public abstract String getCommand(DownloadScheme scheme, String project);
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
index 78802c9..a6acb99 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -20,6 +20,7 @@
import com.google.gerrit.audit.AuditModule;
import com.google.gerrit.common.EventListener;
import com.google.gerrit.extensions.config.CapabilityDefinition;
+import com.google.gerrit.extensions.config.CloneCommand;
import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme;
import com.google.gerrit.extensions.config.ExternalIncludedIn;
@@ -276,6 +277,7 @@
DynamicSet.setOf(binder(), MessageOfTheDay.class);
DynamicMap.mapOf(binder(), DownloadScheme.class);
DynamicMap.mapOf(binder(), DownloadCommand.class);
+ DynamicMap.mapOf(binder(), CloneCommand.class);
DynamicMap.mapOf(binder(), ExternalIncludedIn.class);
DynamicMap.mapOf(binder(), ProjectConfigEntry.class);
DynamicSet.setOf(binder(), PatchSetWebLink.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java
index 4791725..c79bb5b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GetServerInfo.java
@@ -19,6 +19,7 @@
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GitWebType;
+import com.google.gerrit.extensions.config.CloneCommand;
import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme;
import com.google.gerrit.extensions.registration.DynamicMap;
@@ -45,6 +46,7 @@
private final Realm realm;
private final DynamicMap<DownloadScheme> downloadSchemes;
private final DynamicMap<DownloadCommand> downloadCommands;
+ private final DynamicMap<CloneCommand> cloneCommands;
private final GetArchive.AllowedFormats archiveFormats;
private final AllProjectsName allProjectsName;
private final AllUsersName allUsersName;
@@ -58,6 +60,7 @@
Realm realm,
DynamicMap<DownloadScheme> downloadSchemes,
DynamicMap<DownloadCommand> downloadCommands,
+ DynamicMap<CloneCommand> cloneCommands,
GetArchive.AllowedFormats archiveFormats,
AllProjectsName allProjectsName,
AllUsersName allUsersName,
@@ -68,6 +71,7 @@
this.realm = realm;
this.downloadSchemes = downloadSchemes;
this.downloadCommands = downloadCommands;
+ this.cloneCommands = cloneCommands;
this.archiveFormats = archiveFormats;
this.allProjectsName = allProjectsName;
this.allUsersName = allUsersName;
@@ -82,7 +86,8 @@
info.change = getChangeInfo(config);
info.contactStore = getContactStoreInfo();
info.download =
- getDownloadInfo(downloadSchemes, downloadCommands, archiveFormats);
+ getDownloadInfo(downloadSchemes, downloadCommands, cloneCommands,
+ archiveFormats);
info.gerrit = getGerritInfo(config, allProjectsName, allUsersName);
info.gitWeb = getGitWebInfo(gitWebConfig);
info.suggest = getSuggestInfo(config);
@@ -155,8 +160,10 @@
return contactStore;
}
- private DownloadInfo getDownloadInfo(DynamicMap<DownloadScheme> downloadSchemes,
+ private DownloadInfo getDownloadInfo(
+ DynamicMap<DownloadScheme> downloadSchemes,
DynamicMap<DownloadCommand> downloadCommands,
+ DynamicMap<CloneCommand> cloneCommands,
GetArchive.AllowedFormats archiveFormats) {
DownloadInfo info = new DownloadInfo();
info.schemes = new HashMap<>();
@@ -164,7 +171,7 @@
DownloadScheme scheme = e.getProvider().get();
if (scheme.isEnabled() && scheme.getUrl("${project}") != null) {
info.schemes.put(e.getExportName(),
- getDownloadSchemeInfo(scheme, downloadCommands));
+ getDownloadSchemeInfo(scheme, downloadCommands, cloneCommands));
}
}
info.archives = Lists.newArrayList(Iterables.transform(
@@ -179,7 +186,8 @@
}
private DownloadSchemeInfo getDownloadSchemeInfo(DownloadScheme scheme,
- DynamicMap<DownloadCommand> downloadCommands) {
+ DynamicMap<DownloadCommand> downloadCommands,
+ DynamicMap<CloneCommand> cloneCommands) {
DownloadSchemeInfo info = new DownloadSchemeInfo();
info.url = scheme.getUrl("${project}");
info.isAuthRequired = toBoolean(scheme.isAuthRequired());
@@ -195,6 +203,16 @@
}
}
+ info.cloneCommands = new HashMap<>();
+ for (DynamicMap.Entry<CloneCommand> e : cloneCommands) {
+ String commandName = e.getExportName();
+ CloneCommand command = e.getProvider().get();
+ String c = command.getCommand(scheme, "${project}");
+ if (c != null) {
+ info.cloneCommands.put(commandName, c);
+ }
+ }
+
return info;
}
@@ -282,6 +300,7 @@
public Boolean isAuthRequired;
public Boolean isAuthSupported;
public Map<String, String> commands;
+ public Map<String, String> cloneCommands;
}
public static class GerritInfo {