mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-21 05:56:53 +01:00
Store repository id in native config file
Hooks can read this repository type dependant config file and handle the changes for the correct repository id
This commit is contained in:
@@ -69,13 +69,4 @@ public interface RepositoryDAO extends GenericDAO<Repository>
|
||||
* @return repository with the specified namespace and name or null
|
||||
*/
|
||||
Repository get(NamespaceAndName namespaceAndName);
|
||||
|
||||
/**
|
||||
* Returns the repository that is associated with the given path. This path
|
||||
* may be the root directory of the repository or any other directory or file
|
||||
* inside the root directory.
|
||||
*
|
||||
* @throws {@link sonia.scm.NotFoundException} when there is no repository for the given path.
|
||||
*/
|
||||
Repository getRepositoryForDirectory(File path);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,15 @@ public final class HookEventFacade
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
public HookEventHandler handle(String id) {
|
||||
Repository repository = repositoryManagerProvider.get().get(id);
|
||||
if (repository == null)
|
||||
{
|
||||
throw notFound(entity("repository", id));
|
||||
}
|
||||
return handle(repository);
|
||||
}
|
||||
|
||||
public HookEventHandler handle(NamespaceAndName namespaceAndName) {
|
||||
Repository repository = repositoryManagerProvider.get().get(namespaceAndName);
|
||||
if (repository == null)
|
||||
|
||||
@@ -183,26 +183,6 @@ public class XmlRepositoryDAO
|
||||
.orElseThrow(() -> new InternalRepositoryException(repository, "could not find base directory for repository")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository getRepositoryForDirectory(File path) {
|
||||
for (RepositoryPath p : db.values()) {
|
||||
if (toRealPath(path.toPath()).startsWith(toRealPath(context.getBaseDirectory().toPath().resolve(p.getPath())))) {
|
||||
return p.getRepository();
|
||||
}
|
||||
}
|
||||
throw new NotFoundException("directory", path.getPath());
|
||||
}
|
||||
|
||||
private Path toRealPath(Path path) {
|
||||
try {
|
||||
// resolve links and other indirections
|
||||
// (see issue #82, https://bitbucket.org/sdorra/scm-manager/issues/82/symbolic-link-in-hg-repository-path)
|
||||
return path.toRealPath();
|
||||
} catch (IOException e) {
|
||||
throw new InternalRepositoryException(entity("directory", path.toString()), "could not get Path$toRealPath for path: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<RepositoryPath> findExistingRepositoryPath(Repository repository) {
|
||||
return db.values().stream()
|
||||
.filter(repoPath -> repoPath.getId().equals(repository.getId()))
|
||||
|
||||
@@ -106,48 +106,4 @@ public class XmlRepositoryDAOTest {
|
||||
|
||||
assertThat(path.toString()).isEqualTo("/tmp/path");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindRepositoryForRelativePath() {
|
||||
new File(context.getBaseDirectory(), "relative/path/data").mkdirs();
|
||||
Repository existingRepository = new Repository("id", "old", null, null);
|
||||
RepositoryPath repositoryPath = new RepositoryPath("relative/path", "id", existingRepository);
|
||||
when(db.values()).thenReturn(asList(repositoryPath));
|
||||
|
||||
XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), fileSystem, context);
|
||||
|
||||
Repository repository = dao.getRepositoryForDirectory(new File(context.getBaseDirectory(), "relative/path/data"));
|
||||
|
||||
assertThat(repository).isSameAs(existingRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindRepositoryForAbsolutePath() throws IOException {
|
||||
Repository existingRepository = new Repository("id", "old", null, null);
|
||||
File folder = temporaryFolder.newFolder("somewhere", "data");
|
||||
RepositoryPath repositoryPath = new RepositoryPath(folder.getParent(), "id", existingRepository);
|
||||
when(db.values()).thenReturn(asList(repositoryPath));
|
||||
|
||||
XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), fileSystem, context);
|
||||
|
||||
Repository repository = dao.getRepositoryForDirectory(folder);
|
||||
|
||||
assertThat(repository).isSameAs(existingRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindRepositoryForLinks() throws IOException {
|
||||
Repository existingRepository = new Repository("id", "old", null, null);
|
||||
File folder = temporaryFolder.newFolder("somewhere", "else", "data");
|
||||
File link = new File(folder.getParentFile().getParentFile(), "link");
|
||||
Files.createSymbolicLink(link.toPath(), folder.getParentFile().toPath());
|
||||
RepositoryPath repositoryPath = new RepositoryPath(new File(link, "data").getPath(), "id", existingRepository);
|
||||
when(db.values()).thenReturn(asList(repositoryPath));
|
||||
|
||||
XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), fileSystem, context);
|
||||
|
||||
Repository repository = dao.getRepositoryForDirectory(folder);
|
||||
|
||||
assertThat(repository).isSameAs(existingRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,21 +38,24 @@ package org.eclipse.jgit.transport;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.RepositoryCache;
|
||||
import sonia.scm.repository.RepositoryDAO;
|
||||
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
import sonia.scm.web.GitReceiveHook;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -72,15 +75,24 @@ public class ScmTransportProtocol extends TransportProtocol
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
// public ScmTransportProtocol() {}
|
||||
public ScmTransportProtocol() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param hookEventFacadeProvider
|
||||
*
|
||||
* @param repositoryHandlerProvider
|
||||
*/
|
||||
@Inject
|
||||
public ScmTransportProtocol(
|
||||
Provider<HookEventFacade> hookEventFacadeProvider,
|
||||
RepositoryDAO repositoryDAO)
|
||||
Provider<GitRepositoryHandler> repositoryHandlerProvider)
|
||||
{
|
||||
this.hookEventFacadeProvider = hookEventFacadeProvider;
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
this.repositoryHandlerProvider = repositoryHandlerProvider;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -138,7 +150,8 @@ public class ScmTransportProtocol extends TransportProtocol
|
||||
//J-
|
||||
return new TransportLocalWithHooks(
|
||||
hookEventFacadeProvider.get(),
|
||||
local, uri, gitDir, repositoryDAO
|
||||
repositoryHandlerProvider.get(),
|
||||
local, uri, gitDir
|
||||
);
|
||||
//J+
|
||||
}
|
||||
@@ -181,12 +194,23 @@ public class ScmTransportProtocol extends TransportProtocol
|
||||
private static class TransportLocalWithHooks extends TransportLocal
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param hookEventFacade
|
||||
* @param handler
|
||||
* @param local
|
||||
* @param uri
|
||||
* @param gitDir
|
||||
*/
|
||||
public TransportLocalWithHooks(HookEventFacade hookEventFacade,
|
||||
Repository local, URIish uri, File gitDir, RepositoryDAO repositoryDAO)
|
||||
GitRepositoryHandler handler, Repository local, URIish uri, File gitDir)
|
||||
{
|
||||
super(local, uri, gitDir);
|
||||
this.hookEventFacade = hookEventFacade;
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
@@ -204,9 +228,9 @@ public class ScmTransportProtocol extends TransportProtocol
|
||||
{
|
||||
ReceivePack pack = new ReceivePack(dst);
|
||||
|
||||
if (hookEventFacade != null)
|
||||
if ((hookEventFacade != null) && (handler != null))
|
||||
{
|
||||
GitReceiveHook hook = new GitReceiveHook(hookEventFacade, repositoryDAO);
|
||||
GitReceiveHook hook = new GitReceiveHook(hookEventFacade, handler);
|
||||
|
||||
pack.setPreReceiveHook(hook);
|
||||
pack.setPostReceiveHook(hook);
|
||||
@@ -217,9 +241,11 @@ public class ScmTransportProtocol extends TransportProtocol
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private GitRepositoryHandler handler;
|
||||
|
||||
/** Field description */
|
||||
private HookEventFacade hookEventFacade;
|
||||
private RepositoryDAO repositoryDAO;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,5 +254,6 @@ public class ScmTransportProtocol extends TransportProtocol
|
||||
/** Field description */
|
||||
private Provider<HookEventFacade> hookEventFacadeProvider;
|
||||
|
||||
private RepositoryDAO repositoryDAO;
|
||||
/** Field description */
|
||||
private Provider<GitRepositoryHandler> repositoryHandlerProvider;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ package sonia.scm.repository;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -88,6 +89,8 @@ public class GitRepositoryHandler
|
||||
GitRepositoryServiceProvider.COMMANDS);
|
||||
|
||||
private static final Object LOCK = new Object();
|
||||
private static final String CONFIG_SECTION_SCMM = "scmm";
|
||||
private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid";
|
||||
|
||||
private final Scheduler scheduler;
|
||||
|
||||
@@ -176,15 +179,26 @@ public class GitRepositoryHandler
|
||||
return getStringFromResource(RESOURCE_VERSION, DEFAULT_VERSION_INFORMATION);
|
||||
}
|
||||
|
||||
public GitWorkdirFactory getWorkdirFactory() {
|
||||
return workdirFactory;
|
||||
}
|
||||
|
||||
public String getRepositoryId(StoredConfig gitConfig) {
|
||||
return gitConfig.getString(GitRepositoryHandler.CONFIG_SECTION_SCMM, null, GitRepositoryHandler.CONFIG_KEY_REPOSITORY_ID);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
protected void create(Repository repository, File directory) throws IOException {
|
||||
try (org.eclipse.jgit.lib.Repository gitRepository = build(directory)) {
|
||||
gitRepository.create(true);
|
||||
StoredConfig config = gitRepository.getConfig();
|
||||
config.setString(CONFIG_SECTION_SCMM, null, CONFIG_KEY_REPOSITORY_ID, repository.getId());
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private org.eclipse.jgit.lib.Repository build(File directory) throws IOException {
|
||||
return new FileRepositoryBuilder()
|
||||
.setGitDir(directory)
|
||||
@@ -218,8 +232,4 @@ public class GitRepositoryHandler
|
||||
{
|
||||
return GitConfig.class;
|
||||
}
|
||||
|
||||
public GitWorkdirFactory getWorkdirFactory() {
|
||||
return workdirFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,18 +36,18 @@ package sonia.scm.web;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.PostReceiveHook;
|
||||
import org.eclipse.jgit.transport.PreReceiveHook;
|
||||
import org.eclipse.jgit.transport.ReceiveCommand;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.RepositoryDAO;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.spi.GitHookContextProvider;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -67,10 +67,19 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
public GitReceiveHook(HookEventFacade hookEventFacade, RepositoryDAO repositoryDAO)
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param hookEventFacade
|
||||
* @param handler
|
||||
*/
|
||||
public GitReceiveHook(HookEventFacade hookEventFacade,
|
||||
GitRepositoryHandler handler)
|
||||
{
|
||||
this.hookEventFacade = hookEventFacade;
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -118,14 +127,14 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
||||
try
|
||||
{
|
||||
Repository repository = rpack.getRepository();
|
||||
sonia.scm.repository.Repository scmRepository = resolveRepositoryId(repository);
|
||||
String repositoryId = resolveRepositoryId(repository);
|
||||
|
||||
logger.trace("resolved repository to {}", scmRepository.getNamespaceAndName());
|
||||
logger.trace("resolved repository to {}", repositoryId);
|
||||
|
||||
GitHookContextProvider context = new GitHookContextProvider(rpack,
|
||||
receiveCommands);
|
||||
|
||||
hookEventFacade.handle(scmRepository).fireHookEvent(type, context);
|
||||
hookEventFacade.handle(repositoryId).fireHookEvent(type, context);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -177,26 +186,17 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private sonia.scm.repository.Repository resolveRepositoryId(Repository repository)
|
||||
private String resolveRepositoryId(Repository repository)
|
||||
{
|
||||
File directory;
|
||||
|
||||
if (repository.isBare())
|
||||
{
|
||||
directory = repository.getDirectory();
|
||||
}
|
||||
else
|
||||
{
|
||||
directory = repository.getWorkTree();
|
||||
}
|
||||
|
||||
return repositoryDAO.getRepositoryForDirectory(directory);
|
||||
StoredConfig gitConfig = repository.getConfig();
|
||||
return handler.getRepositoryId(gitConfig);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private HookEventFacade hookEventFacade;
|
||||
private GitRepositoryHandler handler;
|
||||
|
||||
private final RepositoryDAO repositoryDAO;
|
||||
/** Field description */
|
||||
private HookEventFacade hookEventFacade;
|
||||
}
|
||||
|
||||
@@ -36,19 +36,21 @@ package sonia.scm.web;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory;
|
||||
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.RepositoryDAO;
|
||||
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -57,10 +59,19 @@ public class GitReceivePackFactory
|
||||
implements ReceivePackFactory<HttpServletRequest>
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param hookEventFacade
|
||||
* @param handler
|
||||
*/
|
||||
@Inject
|
||||
public GitReceivePackFactory(HookEventFacade hookEventFacade, RepositoryDAO repositoryDAO)
|
||||
public GitReceivePackFactory(HookEventFacade hookEventFacade,
|
||||
GitRepositoryHandler handler)
|
||||
{
|
||||
hook = new GitReceiveHook(hookEventFacade, repositoryDAO);
|
||||
hook = new GitReceiveHook(hookEventFacade, handler);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
@@ -127,7 +127,15 @@ public class AbstractRemoteCommandTestBase
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
}, new Provider<GitRepositoryHandler>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public GitRepositoryHandler get()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Transport.register(proto);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +41,15 @@ import com.google.inject.Singleton;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ConfigurationException;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.SCMContextProvider;
|
||||
import sonia.scm.installer.HgInstaller;
|
||||
import sonia.scm.installer.HgInstallerFactory;
|
||||
import sonia.scm.io.ExtendedCommand;
|
||||
import sonia.scm.io.INIConfiguration;
|
||||
import sonia.scm.io.INIConfigurationReader;
|
||||
import sonia.scm.io.INIConfigurationWriter;
|
||||
import sonia.scm.io.INISection;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.repository.spi.HgRepositoryServiceProvider;
|
||||
import sonia.scm.store.ConfigurationStoreFactory;
|
||||
@@ -98,6 +103,8 @@ public class HgRepositoryHandler
|
||||
/** Field description */
|
||||
public static final String PATH_HGRC =
|
||||
".hg".concat(File.separator).concat("hgrc");
|
||||
private static final String CONFIG_SECTION_SCMM = "scmm";
|
||||
private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
@@ -322,6 +329,26 @@ public class HgRepositoryHandler
|
||||
protected void postCreate(Repository repository, File directory)
|
||||
throws IOException
|
||||
{
|
||||
File hgrcFile = new File(directory, PATH_HGRC);
|
||||
INIConfiguration hgrc = new INIConfiguration();
|
||||
|
||||
INISection iniSection = new INISection(CONFIG_SECTION_SCMM);
|
||||
iniSection.setParameter(CONFIG_KEY_REPOSITORY_ID, repository.getId());
|
||||
INIConfiguration iniConfiguration = new INIConfiguration();
|
||||
iniConfiguration.addSection(iniSection);
|
||||
hgrc.addSection(iniSection);
|
||||
|
||||
INIConfigurationWriter writer = new INIConfigurationWriter();
|
||||
|
||||
writer.write(hgrc, hgrcFile);
|
||||
}
|
||||
|
||||
public String getRepositoryId(File directory) {
|
||||
try {
|
||||
return new INIConfigurationReader().read(new File(directory, PATH_HGRC)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID);
|
||||
} catch (IOException e) {
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()), "could not read scm configuration file", e);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
@@ -62,11 +62,11 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
public HgHookChangesetProvider(HgRepositoryHandler handler,
|
||||
sonia.scm.repository.Repository repository, HgHookManager hookManager, String startRev,
|
||||
RepositoryHookType type)
|
||||
File repositoryDirectory, HgHookManager hookManager, String startRev,
|
||||
RepositoryHookType type)
|
||||
{
|
||||
this.handler = handler;
|
||||
this.repository = repository;
|
||||
this.repositoryDirectory = repositoryDirectory;
|
||||
this.hookManager = hookManager;
|
||||
this.startRev = startRev;
|
||||
this.type = type;
|
||||
@@ -123,8 +123,6 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
||||
*/
|
||||
private Repository open()
|
||||
{
|
||||
File repositoryDirectory = handler.getDirectory(repository);
|
||||
|
||||
// use HG_PENDING only for pre receive hooks
|
||||
boolean pending = type == RepositoryHookType.PRE_RECEIVE;
|
||||
|
||||
@@ -142,7 +140,7 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
||||
private HgHookManager hookManager;
|
||||
|
||||
/** Field description */
|
||||
private sonia.scm.repository.Repository repository;
|
||||
private File repositoryDirectory;
|
||||
|
||||
/** Field description */
|
||||
private HookChangesetResponse response;
|
||||
|
||||
@@ -45,6 +45,7 @@ import sonia.scm.repository.api.HookFeature;
|
||||
import sonia.scm.repository.api.HookMessageProvider;
|
||||
import sonia.scm.repository.api.HookTagProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -68,16 +69,16 @@ public class HgHookContextProvider extends HookContextProvider
|
||||
* Constructs a new instance.
|
||||
*
|
||||
* @param handler mercurial repository handler
|
||||
* @param repository the changed repository
|
||||
* @param repositoryDirectory the directory of the changed repository
|
||||
* @param hookManager mercurial hook manager
|
||||
* @param startRev start revision
|
||||
* @param type type of hook
|
||||
*/
|
||||
public HgHookContextProvider(HgRepositoryHandler handler,
|
||||
Repository repository, HgHookManager hookManager, String startRev,
|
||||
File repositoryDirectory, HgHookManager hookManager, String startRev,
|
||||
RepositoryHookType type)
|
||||
{
|
||||
this.hookChangesetProvider = new HgHookChangesetProvider(handler, repository, hookManager, startRev, type);
|
||||
this.hookChangesetProvider = new HgHookChangesetProvider(handler, repositoryDirectory, hookManager, startRev, type);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
@@ -44,12 +44,12 @@ import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.HgContext;
|
||||
import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryDAO;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.api.HgHookMessage;
|
||||
import sonia.scm.repository.api.HgHookMessage.Severity;
|
||||
@@ -118,13 +118,12 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
@Inject
|
||||
public HgHookCallbackServlet(HookEventFacade hookEventFacade,
|
||||
HgRepositoryHandler handler, HgHookManager hookManager,
|
||||
Provider<HgContext> contextProvider, RepositoryDAO repositoryDAO)
|
||||
Provider<HgContext> contextProvider)
|
||||
{
|
||||
this.hookEventFacade = hookEventFacade;
|
||||
this.handler = handler;
|
||||
this.hookManager = hookManager;
|
||||
this.contextProvider = contextProvider;
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -171,7 +170,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
if (m.matches())
|
||||
{
|
||||
Repository repository = getRepositoryId(request);
|
||||
File repositoryPath = getRepositoryPath(request);
|
||||
String type = m.group(1);
|
||||
String challenge = request.getParameter(PARAM_CHALLENGE);
|
||||
|
||||
@@ -188,7 +187,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
authenticate(request, credentials);
|
||||
}
|
||||
|
||||
hookCallback(response, repository, type, challenge, node);
|
||||
hookCallback(response, repositoryPath, type, challenge, node);
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
@@ -247,8 +246,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
private void fireHook(HttpServletResponse response, Repository repository,
|
||||
String node, RepositoryHookType type)
|
||||
private void fireHook(HttpServletResponse response, File repositoryDirectory, String node, RepositoryHookType type)
|
||||
throws IOException
|
||||
{
|
||||
HgHookContextProvider context = null;
|
||||
@@ -260,10 +258,11 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
contextProvider.get().setPending(true);
|
||||
}
|
||||
|
||||
context = new HgHookContextProvider(handler, repository, hookManager,
|
||||
context = new HgHookContextProvider(handler, repositoryDirectory, hookManager,
|
||||
node, type);
|
||||
|
||||
hookEventFacade.handle(repository).fireHookEvent(type, context);
|
||||
String repositoryId = getRepositoryId(repositoryDirectory);
|
||||
hookEventFacade.handle(repositoryId).fireHookEvent(type, context);
|
||||
|
||||
printMessages(response, context);
|
||||
}
|
||||
@@ -281,7 +280,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
private void hookCallback(HttpServletResponse response, Repository repository, String typeName, String challenge, String node) throws IOException {
|
||||
private void hookCallback(HttpServletResponse response, File repositoryDirectory, String typeName, String challenge, String node) throws IOException {
|
||||
if (hookManager.isAcceptAble(challenge))
|
||||
{
|
||||
RepositoryHookType type = null;
|
||||
@@ -297,7 +296,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
fireHook(response, repository, node, type);
|
||||
fireHook(response, repositoryDirectory, node, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -442,29 +441,21 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("squid:S2083") // we do nothing with the path given, so this should be no issue
|
||||
private Repository getRepositoryId(HttpServletRequest request)
|
||||
private String getRepositoryId(File repositoryPath)
|
||||
{
|
||||
Repository repository = null;
|
||||
return handler.getRepositoryId(repositoryPath);
|
||||
}
|
||||
|
||||
private File getRepositoryPath(HttpServletRequest request) {
|
||||
String path = request.getParameter(PARAM_REPOSITORYPATH);
|
||||
|
||||
if (Util.isNotEmpty(path)) {
|
||||
repository = repositoryDAO.getRepositoryForDirectory(new File(path));
|
||||
return new File(path);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
else
|
||||
{
|
||||
logger.warn("no repository path parameter found");
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", path), "could not find hgrc in directory");
|
||||
}
|
||||
|
||||
return repository;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
@@ -480,6 +471,4 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
/** Field description */
|
||||
private final HgHookManager hookManager;
|
||||
|
||||
private final RepositoryDAO repositoryDAO;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,7 @@ public class HgHookCallbackServletTest {
|
||||
@Test
|
||||
public void shouldExtractCorrectRepositoryId() throws ServletException, IOException {
|
||||
HgRepositoryHandler handler = mock(HgRepositoryHandler.class);
|
||||
RepositoryDAO repositoryDAO = mock(RepositoryDAO.class);
|
||||
when(repositoryDAO.getRepositoryForDirectory(new File("/tmp/hg/12345"))).thenReturn(new Repository("12345", "git", "space", "name"));
|
||||
HgHookCallbackServlet servlet = new HgHookCallbackServlet(null, handler, null, null, repositoryDAO);
|
||||
HgHookCallbackServlet servlet = new HgHookCallbackServlet(null, handler, null, null);
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@ import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
|
||||
import org.tmatesoft.svn.util.SVNDebugLog;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.io.INIConfiguration;
|
||||
import sonia.scm.io.INIConfigurationReader;
|
||||
import sonia.scm.io.INIConfigurationWriter;
|
||||
import sonia.scm.io.INISection;
|
||||
import sonia.scm.logging.SVNKitLogger;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
@@ -54,6 +59,7 @@ import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
|
||||
@@ -80,6 +86,9 @@ public class SvnRepositoryHandler
|
||||
public static final RepositoryType TYPE = new RepositoryType(TYPE_NAME,
|
||||
TYPE_DISPLAYNAME,
|
||||
SvnRepositoryServiceProvider.COMMANDS);
|
||||
private static final String CONFIG_FILE_NAME = "scm-manager.conf";
|
||||
private static final String CONFIG_SECTION_SCMM = "scmm";
|
||||
private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid";
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(SvnRepositoryHandler.class);
|
||||
@@ -87,8 +96,7 @@ public class SvnRepositoryHandler
|
||||
@Inject
|
||||
public SvnRepositoryHandler(ConfigurationStoreFactory storeFactory,
|
||||
HookEventFacade eventFacade,
|
||||
RepositoryLocationResolver repositoryLocationResolver,
|
||||
RepositoryDAO repositoryDAO)
|
||||
RepositoryLocationResolver repositoryLocationResolver)
|
||||
{
|
||||
super(storeFactory, repositoryLocationResolver);
|
||||
|
||||
@@ -101,7 +109,7 @@ public class SvnRepositoryHandler
|
||||
// register hook
|
||||
if (eventFacade != null)
|
||||
{
|
||||
FSHooks.registerHook(new SvnRepositoryHook(eventFacade, repositoryDAO));
|
||||
FSHooks.registerHook(new SvnRepositoryHook(eventFacade, this));
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
@@ -210,4 +218,21 @@ public class SvnRepositoryHandler
|
||||
{
|
||||
return SvnConfig.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postCreate(Repository repository, File directory) throws IOException {
|
||||
INISection iniSection = new INISection(CONFIG_SECTION_SCMM);
|
||||
iniSection.setParameter(CONFIG_KEY_REPOSITORY_ID, repository.getId());
|
||||
INIConfiguration iniConfiguration = new INIConfiguration();
|
||||
iniConfiguration.addSection(iniSection);
|
||||
new INIConfigurationWriter().write(iniConfiguration, new File(directory, CONFIG_FILE_NAME));
|
||||
}
|
||||
|
||||
String getRepositoryId(File directory) {
|
||||
try {
|
||||
return new INIConfigurationReader().read(new File(directory, CONFIG_FILE_NAME)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID);
|
||||
} catch (IOException e) {
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()), "could not read scm configuration file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +70,10 @@ public class SvnRepositoryHook implements FSHook
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
public SvnRepositoryHook(HookEventFacade hookEventFacade, RepositoryDAO repositoryDAO)
|
||||
public SvnRepositoryHook(HookEventFacade hookEventFacade, SvnRepositoryHandler handler)
|
||||
{
|
||||
this.hookEventFacade = hookEventFacade;
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -154,10 +154,10 @@ public class SvnRepositoryHook implements FSHook
|
||||
{
|
||||
try
|
||||
{
|
||||
Repository repository = getRepositoryId(directory);
|
||||
String repositoryId = getRepositoryId(directory);
|
||||
|
||||
//J-
|
||||
hookEventFacade.handle(repository)
|
||||
hookEventFacade.handle(repositoryId)
|
||||
.fireHookEvent(
|
||||
changesetProvider.getType(),
|
||||
new SvnHookContextProvider(changesetProvider)
|
||||
@@ -188,11 +188,10 @@ public class SvnRepositoryHook implements FSHook
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private Repository getRepositoryId(File directory)
|
||||
private String getRepositoryId(File directory)
|
||||
{
|
||||
AssertUtil.assertIsNotNull(directory);
|
||||
|
||||
return repositoryDAO.getRepositoryForDirectory(directory);
|
||||
return handler.getRepositoryId(directory);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
@@ -200,5 +199,5 @@ public class SvnRepositoryHook implements FSHook
|
||||
/** Field description */
|
||||
private HookEventFacade hookEventFacade;
|
||||
|
||||
private final RepositoryDAO repositoryDAO;
|
||||
private final SvnRepositoryHandler handler;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
||||
File directory) {
|
||||
repositoryLocationResolver = new RepositoryLocationResolver(repoDao, new InitialRepositoryLocationResolver(contextProvider));
|
||||
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory, null, repositoryLocationResolver, repositoryDAO);
|
||||
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory, null, repositoryLocationResolver);
|
||||
|
||||
handler.init(contextProvider);
|
||||
|
||||
@@ -109,7 +109,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
public void getDirectory() {
|
||||
when(factory.getStore(any(), any())).thenReturn(store);
|
||||
SvnRepositoryHandler repositoryHandler = new SvnRepositoryHandler(factory,
|
||||
facade, repositoryLocationResolver, repositoryDAO);
|
||||
facade, repositoryLocationResolver);
|
||||
|
||||
SvnConfig svnConfig = new SvnConfig();
|
||||
repositoryHandler.setConfig(svnConfig);
|
||||
|
||||
Reference in New Issue
Block a user