Always use http to get commit-msg hook
Http should always be available from primary servers and using scp
is getting complicated since the implementation of scp varies between
different OpenSSH versions.
Bug: Issue 16705
Bug: Issue 15944
Change-Id: Ifb61fa66325d771cc606814f38af4d99d0d68c87
diff --git a/src/main/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHook.java b/src/main/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHook.java
index 135d9b2..ccdfeda 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHook.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHook.java
@@ -15,115 +15,98 @@
package com.googlesource.gerrit.plugins.download.command;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.config.DownloadScheme;
-import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.download.scheme.AnonymousHttpScheme;
import com.googlesource.gerrit.plugins.download.scheme.HttpScheme;
import com.googlesource.gerrit.plugins.download.scheme.SshScheme;
-import java.util.Optional;
import org.eclipse.jgit.lib.Config;
public class CloneWithCommitMsgHook extends CloneCommand {
@VisibleForTesting protected static final String HOOK_COMMAND_KEY = "installCommitMsgHookCommand";
@VisibleForTesting protected static final String EXTRA_COMMAND_KEY = "installCommitExtraCommand";
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final String HOOK = "hooks/commit-msg";
private static final String TARGET = " `git rev-parse --git-dir`/";
private final String configCommand;
private final String extraCommand;
- private final SshScheme sshScheme;
- private final Provider<CurrentUser> userProvider;
+ private final String canonicalWebUrl;
@Inject
CloneWithCommitMsgHook(
- @GerritServerConfig Config config, SshScheme sshScheme, Provider<CurrentUser> userProvider) {
- this.configCommand = config.getString("gerrit", null, HOOK_COMMAND_KEY);
- this.extraCommand = config.getString("gerrit", null, EXTRA_COMMAND_KEY);
- this.sshScheme = sshScheme;
- this.userProvider = userProvider;
+ @GerritServerConfig Config config, @CanonicalWebUrl @Nullable Provider<String> urlProvider) {
+ this.configCommand = config.getString("gerrit", null, "installCommitMsgHookCommand");
+ this.extraCommand = config.getString("gerrit", null, "installCommitExtraCommand");
+ this.canonicalWebUrl = urlProvider != null ? urlProvider.get() : null;
}
@Nullable
@Override
public String getCommand(DownloadScheme scheme, String project) {
- Optional<String> username = userProvider.get().getUserName();
- if (!username.isPresent()) {
- return null;
- }
String projectName = getBaseName(project);
+ StringBuilder command = null;
+
if (configCommand != null) {
- return new StringBuilder()
- .append(super.getCommand(scheme, project))
+ command =
+ new StringBuilder()
+ .append(super.getCommand(scheme, project))
+ .append(" && (cd ")
+ .append(QuoteUtil.quote(projectName))
+ .append(" && ")
+ .append(configCommand)
+ .append(")");
+ } else if (scheme instanceof HttpScheme
+ || scheme instanceof AnonymousHttpScheme
+ || scheme instanceof SshScheme) {
+ command =
+ new StringBuilder()
+ .append(super.getCommand(scheme, project))
+ .append(" && (cd ")
+ .append(QuoteUtil.quote(projectName))
+ .append(" && mkdir -p .git/hooks")
+ .append(" && curl -Lo")
+ .append(TARGET)
+ .append(HOOK)
+ .append(" ")
+ .append(getHookUrl())
+ .append("; chmod +x")
+ .append(TARGET)
+ .append(HOOK)
+ .append(")");
+ }
+
+ if (extraCommand != null && command != null) {
+ command
.append(" && (cd ")
.append(QuoteUtil.quote(projectName))
.append(" && ")
- .append(configCommand)
- .append(")")
- .toString();
+ .append(extraCommand)
+ .append(")");
}
-
- if (scheme instanceof SshScheme) {
- StringBuilder b =
- new StringBuilder().append(super.getCommand(scheme, project)).append(" && scp -p");
-
- if (sshScheme.getSshdPort() != 22) {
- b.append(" -P ").append(sshScheme.getSshdPort());
- }
-
- b.append(" ")
- .append(username.get())
- .append("@")
- .append(sshScheme.getSshdHost())
- .append(":")
- .append(HOOK)
- .append(" ")
- .append(QuoteUtil.quote(projectName + "/.git/hooks/"));
- if (extraCommand != null) {
- b.append(" && (cd ")
- .append(QuoteUtil.quote(projectName))
- .append(" && ")
- .append(extraCommand)
- .append(")");
- }
- return b.toString();
- }
-
- if (scheme instanceof HttpScheme || scheme instanceof AnonymousHttpScheme) {
- return new StringBuilder()
- .append(super.getCommand(scheme, project))
- .append(" && (cd ")
- .append(QuoteUtil.quote(projectName))
- .append(" && mkdir -p .git/hooks")
- .append(" && curl -Lo")
- .append(TARGET)
- .append(HOOK)
- .append(" ")
- .append(getHttpHost(scheme, project))
- .append("tools/")
- .append(HOOK)
- .append("; chmod +x")
- .append(TARGET)
- .append(HOOK)
- .append(")")
- .toString();
- }
- return null;
+ return command != null ? command.toString() : null;
}
- private String getHttpHost(DownloadScheme scheme, String project) {
- String host = scheme.getUrl(project);
- host = host.substring(0, host.lastIndexOf(project));
- int auth = host.lastIndexOf("/a/");
- if (auth > -1) {
- host = host.substring(0, auth + 1);
+ private StringBuilder getHookUrl() {
+ StringBuilder hookUrl = new StringBuilder();
+ if (canonicalWebUrl != null) {
+ hookUrl.append(canonicalWebUrl);
+ if (!canonicalWebUrl.endsWith("/")) {
+ hookUrl.append("/");
+ }
+ hookUrl.append("tools/").append(HOOK);
+ } else {
+ logger.atWarning().log(
+ "Cannot add commit-msg hook URL since gerrit.canonicalWebUrl isn't configured.");
}
- return host;
+ return hookUrl;
}
private static String getBaseName(String project) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHookTest.java b/src/test/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHookTest.java
index 03c1ba0..3d1f810 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHookTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/download/command/CloneWithCommitMsgHookTest.java
@@ -29,12 +29,8 @@
assertThat(command)
.isEqualTo(
String.format(
- "git clone \"%s\" && scp -p -P %d %s@%s:hooks/commit-msg %s/.git/hooks/",
- sshScheme.getUrl(ENV.projectName),
- ENV.sshPort,
- ENV.userName,
- ENV.fqdn,
- baseName(ENV.projectName)));
+ "git clone \"%s\" && %s",
+ sshScheme.getUrl(ENV.projectName), getDefaultHookCommand()));
}
@Test
@@ -68,8 +64,12 @@
assertThat(command)
.isEqualTo(
String.format(
- "git clone \"%s\" && (cd %s && %s)",
- sshScheme.getUrl(ENV.projectName), baseName(ENV.projectName), hookCommand));
+ "git clone \"%s\" && (cd %s && %s) && (cd %s && %s)",
+ sshScheme.getUrl(ENV.projectName),
+ baseName(ENV.projectName),
+ hookCommand,
+ baseName(ENV.projectName),
+ extraCommand));
}
@Test
@@ -78,11 +78,8 @@
assertThat(command)
.isEqualTo(
String.format(
- "git clone \"%s\" && (cd %s && mkdir -p .git/hooks && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg https://%s@%s/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)",
- httpScheme.getUrl(ENV.projectName),
- baseName(ENV.projectName),
- ENV.urlEncodedUserName(),
- ENV.fqdn));
+ "git clone \"%s\" && %s",
+ httpScheme.getUrl(ENV.projectName), getDefaultHookCommand()));
}
@Test
@@ -105,18 +102,28 @@
assertThat(command)
.isEqualTo(
String.format(
- "git clone \"%s\" && (cd %s && %s)",
- httpScheme.getUrl(ENV.projectName), baseName(ENV.projectName), hookCommand));
+ "git clone \"%s\" && (cd %s && %s) && (cd %s && %s)",
+ httpScheme.getUrl(ENV.projectName),
+ baseName(ENV.projectName),
+ hookCommand,
+ baseName(ENV.projectName),
+ extraCommand));
}
private String baseName(String projectName) {
return projectName.substring(projectName.lastIndexOf('/') + 1);
}
+ private String getDefaultHookCommand() {
+ return String.format(
+ "(cd %s && mkdir -p .git/hooks && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg https://%s/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)",
+ baseName(ENV.projectName), ENV.fqdn);
+ }
+
private CloneCommand getCloneCommand(String hookCommand, String extraCommand) {
Config cfg = new Config();
cfg.setString("gerrit", null, HOOK_COMMAND_KEY, hookCommand);
cfg.setString("gerrit", null, EXTRA_COMMAND_KEY, extraCommand);
- return new CloneWithCommitMsgHook(cfg, sshScheme, userProvider);
+ return new CloneWithCommitMsgHook(cfg, urlProvider);
}
}