mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-08-04 22:59:21 +02:00
Merged in feature/changes_for_ssh_plugin (pull request #208)
Changes for ssh plugin
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package sonia.scm.protocolcommand;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class CommandContext {
|
||||
|
||||
private String command;
|
||||
private String[] args;
|
||||
|
||||
private InputStream inputStream;
|
||||
private OutputStream outputStream;
|
||||
private OutputStream errorStream;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package sonia.scm.protocolcommand;
|
||||
|
||||
public interface CommandInterpreter {
|
||||
|
||||
String[] getParsedArgs();
|
||||
|
||||
ScmCommandProtocol getProtocolHandler();
|
||||
|
||||
RepositoryContextResolver getRepositoryContextResolver();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package sonia.scm.protocolcommand;
|
||||
|
||||
import sonia.scm.plugin.ExtensionPoint;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@ExtensionPoint
|
||||
public interface CommandInterpreterFactory {
|
||||
Optional<CommandInterpreter> canHandle(String command);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package sonia.scm.protocolcommand;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class RepositoryContext {
|
||||
private Repository repository;
|
||||
private Path directory;
|
||||
|
||||
public RepositoryContext(Repository repository, Path directory) {
|
||||
this.repository = repository;
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public Path getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package sonia.scm.protocolcommand;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RepositoryContextResolver {
|
||||
|
||||
RepositoryContext resolve(String[] args);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package sonia.scm.protocolcommand;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ScmCommandProtocol {
|
||||
|
||||
void handle(CommandContext context, RepositoryContext repositoryContext) throws IOException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
import sonia.scm.web.CollectingPackParserListener;
|
||||
import sonia.scm.web.GitReceiveHook;
|
||||
|
||||
public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T> {
|
||||
|
||||
private final GitRepositoryHandler handler;
|
||||
private final GitReceiveHook hook;
|
||||
|
||||
protected BaseReceivePackFactory(GitRepositoryHandler handler, HookEventFacade hookEventFacade) {
|
||||
this.handler = handler;
|
||||
this.hook = new GitReceiveHook(hookEventFacade, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ReceivePack create(T connection, Repository repository) throws ServiceNotAuthorizedException, ServiceNotEnabledException {
|
||||
ReceivePack receivePack = createBasicReceivePack(connection, repository);
|
||||
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed());
|
||||
|
||||
receivePack.setPreReceiveHook(hook);
|
||||
receivePack.setPostReceiveHook(hook);
|
||||
// apply collecting listener, to be able to check which commits are new
|
||||
CollectingPackParserListener.set(receivePack);
|
||||
|
||||
return receivePack;
|
||||
}
|
||||
|
||||
protected abstract ReceivePack createBasicReceivePack(T request, Repository repository)
|
||||
throws ServiceNotEnabledException, ServiceNotAuthorizedException;
|
||||
|
||||
private boolean isNonFastForwardAllowed() {
|
||||
return ! handler.getConfig().isNonFastForwardDisallowed();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import sonia.scm.protocolcommand.CommandInterpreter;
|
||||
import sonia.scm.protocolcommand.RepositoryContextResolver;
|
||||
import sonia.scm.protocolcommand.ScmCommandProtocol;
|
||||
|
||||
class GitCommandInterpreter implements CommandInterpreter {
|
||||
private final GitRepositoryContextResolver gitRepositoryContextResolver;
|
||||
private final GitCommandProtocol gitCommandProtocol;
|
||||
private final String[] args;
|
||||
|
||||
GitCommandInterpreter(GitRepositoryContextResolver gitRepositoryContextResolver, GitCommandProtocol gitCommandProtocol, String[] args) {
|
||||
this.gitRepositoryContextResolver = gitRepositoryContextResolver;
|
||||
this.gitCommandProtocol = gitCommandProtocol;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParsedArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScmCommandProtocol getProtocolHandler() {
|
||||
return gitCommandProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryContextResolver getRepositoryContextResolver() {
|
||||
return gitRepositoryContextResolver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.protocolcommand.CommandInterpreter;
|
||||
import sonia.scm.protocolcommand.CommandInterpreterFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
|
||||
@Extension
|
||||
public class GitCommandInterpreterFactory implements CommandInterpreterFactory {
|
||||
private final GitCommandProtocol gitCommandProtocol;
|
||||
private final GitRepositoryContextResolver gitRepositoryContextResolver;
|
||||
|
||||
@Inject
|
||||
public GitCommandInterpreterFactory(GitCommandProtocol gitCommandProtocol, GitRepositoryContextResolver gitRepositoryContextResolver) {
|
||||
this.gitCommandProtocol = gitCommandProtocol;
|
||||
this.gitRepositoryContextResolver = gitRepositoryContextResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CommandInterpreter> canHandle(String command) {
|
||||
try {
|
||||
String[] args = GitCommandParser.parse(command);
|
||||
if (args[0].startsWith("git")) {
|
||||
return of(new GitCommandInterpreter(gitRepositoryContextResolver, gitCommandProtocol, args));
|
||||
} else {
|
||||
return empty();
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class GitCommandParser {
|
||||
|
||||
private GitCommandParser() {
|
||||
}
|
||||
|
||||
static String[] parse(String command) {
|
||||
List<String> strs = parseDelimitedString(command, " ", true);
|
||||
String[] args = strs.toArray(new String[strs.size()]);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String argVal = args[i];
|
||||
if (argVal.startsWith("'") && argVal.endsWith("'")) {
|
||||
args[i] = argVal.substring(1, argVal.length() - 1);
|
||||
argVal = args[i];
|
||||
}
|
||||
if (argVal.startsWith("\"") && argVal.endsWith("\"")) {
|
||||
args[i] = argVal.substring(1, argVal.length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length != 2) {
|
||||
throw new IllegalArgumentException("Invalid git command line (no arguments): " + command);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
private static List<String> parseDelimitedString(String value, String delim, boolean trim) {
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int expecting = 7;
|
||||
boolean isEscaped = false;
|
||||
|
||||
for(int i = 0; i < value.length(); ++i) {
|
||||
char c = value.charAt(i);
|
||||
boolean isDelimiter = delim.indexOf(c) >= 0;
|
||||
if (!isEscaped && c == '\\') {
|
||||
isEscaped = true;
|
||||
} else {
|
||||
if (isEscaped) {
|
||||
sb.append(c);
|
||||
} else if (isDelimiter && (expecting & 2) != 0) {
|
||||
if (trim) {
|
||||
String str = sb.toString();
|
||||
list.add(str.trim());
|
||||
} else {
|
||||
list.add(sb.toString());
|
||||
}
|
||||
|
||||
sb.delete(0, sb.length());
|
||||
expecting = 7;
|
||||
} else if (c == '"' && (expecting & 4) != 0) {
|
||||
sb.append(c);
|
||||
expecting = 9;
|
||||
} else if (c == '"' && (expecting & 8) != 0) {
|
||||
sb.append(c);
|
||||
expecting = 7;
|
||||
} else {
|
||||
if ((expecting & 1) == 0) {
|
||||
throw new IllegalArgumentException("Invalid delimited string: " + value);
|
||||
}
|
||||
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
isEscaped = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (sb.length() > 0) {
|
||||
if (trim) {
|
||||
String str = sb.toString();
|
||||
list.add(str.trim());
|
||||
} else {
|
||||
list.add(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.RepositoryCache;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.UploadPack;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.protocolcommand.CommandContext;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
import sonia.scm.protocolcommand.ScmCommandProtocol;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
|
||||
@Extension
|
||||
public class GitCommandProtocol implements ScmCommandProtocol {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GitCommandProtocol.class);
|
||||
|
||||
private ScmUploadPackFactory uploadPackFactory;
|
||||
private ScmReceivePackFactory receivePackFactory;
|
||||
|
||||
@Inject
|
||||
public GitCommandProtocol(ScmUploadPackFactory uploadPackFactory, ScmReceivePackFactory receivePackFactory) {
|
||||
this.uploadPackFactory = uploadPackFactory;
|
||||
this.receivePackFactory = receivePackFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(CommandContext commandContext, RepositoryContext repositoryContext) throws IOException {
|
||||
String subCommand = commandContext.getArgs()[0];
|
||||
|
||||
if (RemoteConfig.DEFAULT_UPLOAD_PACK.equals(subCommand)) {
|
||||
LOG.trace("got upload pack");
|
||||
upload(commandContext, repositoryContext);
|
||||
} else if (RemoteConfig.DEFAULT_RECEIVE_PACK.equals(subCommand)) {
|
||||
LOG.trace("got receive pack");
|
||||
receive(commandContext, repositoryContext);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown git command: " + commandContext.getCommand());
|
||||
}
|
||||
}
|
||||
|
||||
private void receive(CommandContext commandContext, RepositoryContext repositoryContext) throws IOException {
|
||||
RepositoryPermissions.push(repositoryContext.getRepository()).check();
|
||||
try (Repository repository = open(repositoryContext)) {
|
||||
ReceivePack receivePack = receivePackFactory.create(repositoryContext, repository);
|
||||
receivePack.receive(commandContext.getInputStream(), commandContext.getOutputStream(), commandContext.getErrorStream());
|
||||
} catch (ServiceNotEnabledException | ServiceNotAuthorizedException e) {
|
||||
throw new IOException("error creating receive pack for ssh", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void upload(CommandContext commandContext, RepositoryContext repositoryContext) throws IOException {
|
||||
RepositoryPermissions.pull(repositoryContext.getRepository()).check();
|
||||
try (Repository repository = open(repositoryContext)) {
|
||||
UploadPack uploadPack = uploadPackFactory.create(repositoryContext, repository);
|
||||
uploadPack.upload(commandContext.getInputStream(), commandContext.getOutputStream(), commandContext.getErrorStream());
|
||||
}
|
||||
}
|
||||
|
||||
private Repository open(RepositoryContext repositoryContext) throws IOException {
|
||||
RepositoryCache.FileKey key = RepositoryCache.FileKey.lenient(repositoryContext.getDirectory().toFile(), FS.DETECTED);
|
||||
return key.open(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
import sonia.scm.protocolcommand.RepositoryContextResolver;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryLocationResolver;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class GitRepositoryContextResolver implements RepositoryContextResolver {
|
||||
|
||||
private RepositoryManager repositoryManager;
|
||||
private RepositoryLocationResolver locationResolver;
|
||||
|
||||
@Inject
|
||||
public GitRepositoryContextResolver(RepositoryManager repositoryManager, RepositoryLocationResolver locationResolver) {
|
||||
this.repositoryManager = repositoryManager;
|
||||
this.locationResolver = locationResolver;
|
||||
}
|
||||
|
||||
public RepositoryContext resolve(String[] args) {
|
||||
NamespaceAndName namespaceAndName = extractNamespaceAndName(args);
|
||||
Repository repository = repositoryManager.get(namespaceAndName);
|
||||
Path path = locationResolver.getPath(repository.getId()).resolve("data");
|
||||
return new RepositoryContext(repository, path);
|
||||
}
|
||||
|
||||
private NamespaceAndName extractNamespaceAndName(String[] args) {
|
||||
String path = args[args.length - 1];
|
||||
Iterator<String> it = Splitter.on('/').omitEmptyStrings().split(path).iterator();
|
||||
String type = it.next();
|
||||
if ("repo".equals(type)) {
|
||||
String ns = it.next();
|
||||
String name = it.next();
|
||||
return new NamespaceAndName(ns, name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
|
||||
public class ScmReceivePackFactory extends BaseReceivePackFactory<RepositoryContext> {
|
||||
|
||||
@Inject
|
||||
public ScmReceivePackFactory(GitRepositoryHandler handler, HookEventFacade hookEventFacade) {
|
||||
super(handler, hookEventFacade);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReceivePack createBasicReceivePack(RepositoryContext repositoryContext, Repository repository) {
|
||||
return new ReceivePack(repository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.UploadPack;
|
||||
import org.eclipse.jgit.transport.resolver.UploadPackFactory;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
|
||||
public class ScmUploadPackFactory implements UploadPackFactory<RepositoryContext> {
|
||||
@Override
|
||||
public UploadPack create(RepositoryContext repositoryContext, Repository repository) {
|
||||
return new UploadPack(repository);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,6 @@ package sonia.scm.web;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
@@ -43,6 +42,7 @@ import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import sonia.scm.protocolcommand.git.BaseReceivePackFactory;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
|
||||
@@ -56,42 +56,20 @@ import javax.servlet.http.HttpServletRequest;
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class GitReceivePackFactory implements ReceivePackFactory<HttpServletRequest>
|
||||
public class GitReceivePackFactory extends BaseReceivePackFactory<HttpServletRequest>
|
||||
{
|
||||
|
||||
private final GitRepositoryHandler handler;
|
||||
|
||||
private ReceivePackFactory wrapped;
|
||||
|
||||
private final GitReceiveHook hook;
|
||||
private ReceivePackFactory<HttpServletRequest> wrapped;
|
||||
|
||||
@Inject
|
||||
public GitReceivePackFactory(GitRepositoryHandler handler, HookEventFacade hookEventFacade) {
|
||||
this.handler = handler;
|
||||
this.hook = new GitReceiveHook(hookEventFacade, handler);
|
||||
this.wrapped = new DefaultReceivePackFactory();
|
||||
super(handler, hookEventFacade);
|
||||
this.wrapped = new DefaultReceivePackFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReceivePack create(HttpServletRequest request, Repository repository)
|
||||
protected ReceivePack createBasicReceivePack(HttpServletRequest request, Repository repository)
|
||||
throws ServiceNotEnabledException, ServiceNotAuthorizedException {
|
||||
ReceivePack receivePack = wrapped.create(request, repository);
|
||||
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed());
|
||||
|
||||
receivePack.setPreReceiveHook(hook);
|
||||
receivePack.setPostReceiveHook(hook);
|
||||
// apply collecting listener, to be able to check which commits are new
|
||||
CollectingPackParserListener.set(receivePack);
|
||||
|
||||
return receivePack;
|
||||
}
|
||||
|
||||
private boolean isNonFastForwardAllowed() {
|
||||
return ! handler.getConfig().isNonFastForwardDisallowed();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setWrapped(ReceivePackFactory wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
return wrapped.create(request, repository);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,13 +29,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package sonia.scm.web;
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -45,21 +47,20 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.repository.GitConfig;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.web.CollectingPackParserListener;
|
||||
import sonia.scm.web.GitReceiveHook;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GitReceivePackFactory}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GitReceivePackFactoryTest {
|
||||
public class BaseReceivePackFactoryTest {
|
||||
|
||||
@Mock
|
||||
private GitRepositoryHandler handler;
|
||||
@@ -67,12 +68,11 @@ public class GitReceivePackFactoryTest {
|
||||
private GitConfig config;
|
||||
|
||||
@Mock
|
||||
private ReceivePackFactory wrappedReceivePackFactory;
|
||||
private ReceivePackFactory<Object> wrappedReceivePackFactory;
|
||||
|
||||
private GitReceivePackFactory factory;
|
||||
private BaseReceivePackFactory<Object> factory;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
private Object request = new Object();
|
||||
|
||||
private Repository repository;
|
||||
|
||||
@@ -89,8 +89,12 @@ public class GitReceivePackFactoryTest {
|
||||
ReceivePack receivePack = new ReceivePack(repository);
|
||||
when(wrappedReceivePackFactory.create(request, repository)).thenReturn(receivePack);
|
||||
|
||||
factory = new GitReceivePackFactory(handler, null);
|
||||
factory.setWrapped(wrappedReceivePackFactory);
|
||||
factory = new BaseReceivePackFactory<Object>(handler, null) {
|
||||
@Override
|
||||
protected ReceivePack createBasicReceivePack(Object request, Repository repository) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
|
||||
return wrappedReceivePackFactory.create(request, repository);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Repository createRepositoryForTesting() throws GitAPIException, IOException {
|
||||
@@ -105,6 +109,7 @@ public class GitReceivePackFactoryTest {
|
||||
assertThat(receivePack.getPreReceiveHook(), instanceOf(GitReceiveHook.class));
|
||||
assertThat(receivePack.getPostReceiveHook(), instanceOf(GitReceiveHook.class));
|
||||
assertTrue(receivePack.isAllowNonFastForwards());
|
||||
verify(wrappedReceivePackFactory).create(request, repository);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -0,0 +1,45 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryLocationResolver;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class GitRepositoryContextResolverTest {
|
||||
|
||||
private static final Repository REPOSITORY = new Repository("id", "git", "space", "X");
|
||||
|
||||
@Mock
|
||||
RepositoryManager repositoryManager;
|
||||
@Mock
|
||||
RepositoryLocationResolver locationResolver;
|
||||
|
||||
@InjectMocks
|
||||
GitRepositoryContextResolver resolver;
|
||||
|
||||
@Test
|
||||
void shouldResolveCorrectRepository() throws IOException {
|
||||
when(repositoryManager.get(new NamespaceAndName("space", "X"))).thenReturn(REPOSITORY);
|
||||
Path repositoryPath = File.createTempFile("test", "scm").toPath();
|
||||
when(locationResolver.getPath("id")).thenReturn(repositoryPath);
|
||||
|
||||
RepositoryContext context = resolver.resolve(new String[] {"git", "repo/space/X/something/else"});
|
||||
|
||||
assertThat(context.getRepository()).isSameAs(REPOSITORY);
|
||||
assertThat(context.getDirectory()).isEqualTo(repositoryPath.resolve("data"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user