mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-06 21:45:43 +01:00
Do not map not found exception manually
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package sonia.scm.protocolcommand.git;
|
||||
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.protocolcommand.RepositoryContextResolver;
|
||||
import sonia.scm.protocolcommand.ScmSshProtocol;
|
||||
|
||||
@Extension
|
||||
public class GitProtocolModule extends ServletModule {
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
bind(RepositoryContextResolver.class).to(GitRepositoryContextResolver.class);
|
||||
bind(ScmSshProtocol.class).to(GitSshProtocol.class);
|
||||
}
|
||||
}
|
||||
@@ -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,68 @@
|
||||
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.util.FS;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.protocolcommand.CommandContext;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
import sonia.scm.protocolcommand.ScmSshProtocol;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
|
||||
public class GitSshProtocol implements ScmSshProtocol {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GitSshProtocol.class);
|
||||
|
||||
private SshUploadPackFactory uploadPackFactory;
|
||||
private SshReceivePackFactory receivePackFactory;
|
||||
|
||||
@Inject
|
||||
public GitSshProtocol(SshUploadPackFactory uploadPackFactory, SshReceivePackFactory 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());
|
||||
}
|
||||
}
|
||||
|
||||
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.inject.Inject;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import sonia.scm.protocolcommand.RepositoryContext;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
import sonia.scm.web.CollectingPackParserListener;
|
||||
import sonia.scm.web.GitReceiveHook;
|
||||
|
||||
/**
|
||||
* TODO we should have a single/abstract ReceivePackFactory for http and ssh.
|
||||
*/
|
||||
public class SshReceivePackFactory implements ReceivePackFactory<RepositoryContext> {
|
||||
|
||||
private final GitRepositoryHandler handler;
|
||||
private final GitReceiveHook hook;
|
||||
|
||||
@Inject
|
||||
public SshReceivePackFactory(GitRepositoryHandler handler, HookEventFacade hookEventFacade) {
|
||||
this.handler = handler;
|
||||
this.hook = new GitReceiveHook(hookEventFacade, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReceivePack create(RepositoryContext repositoryContext, Repository repository) {
|
||||
ReceivePack receivePack = new ReceivePack(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();
|
||||
}
|
||||
}
|
||||
@@ -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 SshUploadPackFactory implements UploadPackFactory<RepositoryContext> {
|
||||
@Override
|
||||
public UploadPack create(RepositoryContext repositoryContext, Repository repository) {
|
||||
return new UploadPack(repository);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user