ChangeScreen2: Show download commands defined by plugins

The download commands are returned as part of the FetchInfo of a
revision, but only if the download commands are requested by setting
the option DOWNLOAD_COMMANDS.

This allows to completely customize the download commands on a Gerrit
installation.

This change only effects the download commands that are shown on
ChangeScreen2.

For non-anonymous download commands the username is now again included
into the displayed download commands. Also the HTTP scheme and the
Anonymous HTTP scheme can be used at the same time.

With this change the patch download (base64 & zipped) is still
hard-coded in Gerrit core and does not come from a plugin.

Bug: issue 2116
Change-Id: I8fb21fdeb1a98548ce9027655e1b5e467ee2d27e
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
Edwin Kempin
2013-10-16 12:58:24 +02:00
committed by David Pursehouse
parent 78e868ef89
commit ea62148983
11 changed files with 278 additions and 275 deletions

View File

@@ -23,6 +23,7 @@ import static com.google.gerrit.common.changes.ListChangesOption.CURRENT_FILES;
import static com.google.gerrit.common.changes.ListChangesOption.CURRENT_REVISION;
import static com.google.gerrit.common.changes.ListChangesOption.DETAILED_ACCOUNTS;
import static com.google.gerrit.common.changes.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.common.changes.ListChangesOption.DOWNLOAD_COMMANDS;
import static com.google.gerrit.common.changes.ListChangesOption.DRAFT_COMMENTS;
import static com.google.gerrit.common.changes.ListChangesOption.LABELS;
import static com.google.gerrit.common.changes.ListChangesOption.MESSAGES;
@@ -30,7 +31,6 @@ import static com.google.gerrit.common.changes.ListChangesOption.REVIEWED;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
@@ -50,6 +50,8 @@ import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.Url;
@@ -69,8 +71,6 @@ import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountInfo;
import com.google.gerrit.server.actions.ActionInfo;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.extensions.webui.UiActions;
import com.google.gerrit.server.git.LabelNormalizer;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
@@ -79,14 +79,11 @@ import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.ssh.SshAdvertisedAddresses;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -120,30 +117,6 @@ public class ChangeJson {
}
};
@Singleton
static class Urls {
final String git;
final String http;
final String ssh;
@Inject
Urls(@GerritServerConfig Config cfg,
@SshAdvertisedAddresses List<String> sshAddresses) {
this.git = ensureSlash(cfg.getString("gerrit", null, "canonicalGitUrl"));
this.http = ensureSlash(cfg.getString("gerrit", null, "gitHttpUrl"));
this.ssh = !sshAddresses.isEmpty()
? ensureSlash("ssh://" + sshAddresses.get(0))
: null;
}
private static String ensureSlash(String in) {
if (in != null && !in.endsWith("/")) {
return in + "/";
}
return in;
}
}
private final Provider<ReviewDb> db;
private final LabelNormalizer labelNormalizer;
private final Provider<CurrentUser> userProvider;
@@ -153,8 +126,8 @@ public class ChangeJson {
private final PatchSetInfoFactory patchSetInfoFactory;
private final FileInfoJson fileInfoJson;
private final AccountInfo.Loader.Factory accountLoaderFactory;
private final Provider<String> urlProvider;
private final Urls urls;
private final DynamicMap<DownloadScheme> downloadSchemes;
private final DynamicMap<DownloadCommand> downloadCommands;
private final DynamicMap<RestView<ChangeResource>> changes;
private final Revisions revisions;
@@ -175,8 +148,8 @@ public class ChangeJson {
PatchSetInfoFactory psi,
FileInfoJson fileInfoJson,
AccountInfo.Loader.Factory ailf,
@CanonicalWebUrl Provider<String> curl,
Urls urls,
DynamicMap<DownloadScheme> downloadSchemes,
DynamicMap<DownloadCommand> downloadCommands,
DynamicMap<RestView<ChangeResource>> changes,
Revisions revisions) {
this.db = db;
@@ -188,8 +161,8 @@ public class ChangeJson {
this.patchSetInfoFactory = psi;
this.fileInfoJson = fileInfoJson;
this.accountLoaderFactory = ailf;
this.urlProvider = curl;
this.urls = urls;
this.downloadSchemes = downloadSchemes;
this.downloadCommands = downloadCommands;
this.changes = changes;
this.revisions = revisions;
@@ -872,28 +845,37 @@ public class ChangeJson {
private Map<String, FetchInfo> makeFetchMap(ChangeData cd, PatchSet in)
throws OrmException {
Map<String, FetchInfo> r = Maps.newLinkedHashMap();
String refName = in.getRefName();
ChangeControl ctl = control(cd);
if (ctl != null && ctl.forUser(anonymous).isPatchVisible(in, db.get())) {
if (urls.git != null) {
r.put("git", new FetchInfo(urls.git
+ cd.change(db).getProject().get(), refName));
for (DynamicMap.Entry<DownloadScheme> e : downloadSchemes) {
String schemeName = e.getExportName();
DownloadScheme scheme = e.getProvider().get();
if (!scheme.isEnabled()
|| (scheme.isAuthRequired() && !userProvider.get().isIdentifiedUser())) {
continue;
}
}
if (urls.http != null) {
r.put("http", new FetchInfo(urls.http
+ cd.change(db).getProject().get(), refName));
} else {
String http = urlProvider.get();
if (!Strings.isNullOrEmpty(http)) {
r.put("http", new FetchInfo(http
+ cd.change(db).getProject().get(), refName));
ChangeControl ctl = control(cd);
if (!scheme.isAuthRequired()
&& !ctl.forUser(anonymous).isPatchVisible(in, db.get())) {
continue;
}
String projectName = ctl.getProject().getNameKey().get();
String url = scheme.getUrl(projectName);
String refName = in.getRefName();
FetchInfo fetchInfo = new FetchInfo(url, refName);
r.put(schemeName, fetchInfo);
if (has(DOWNLOAD_COMMANDS)) {
for (DynamicMap.Entry<DownloadCommand> e2 : downloadCommands) {
String commandName = e2.getExportName();
DownloadCommand command = e2.getProvider().get();
String c = command.getCommand(scheme, projectName, refName);
if (c != null) {
fetchInfo.addCommand(commandName, c);
}
}
}
}
if (urls.ssh != null) {
r.put("ssh", new FetchInfo(
urls.ssh + cd.change(db).getProject().get(),
refName));
}
return r;
@@ -960,11 +942,19 @@ public class ChangeJson {
static class FetchInfo {
String url;
String ref;
Map<String, String> commands;
FetchInfo(String url, String ref) {
this.url = url;
this.ref = ref;
}
void addCommand(String name, String command) {
if (commands == null) {
commands = Maps.newTreeMap();
}
commands.put(name, command);
}
}
static class GitPerson {