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:
René Pfeuffer
2018-11-26 17:22:17 +01:00
parent 6b663de7dd
commit 00ab764dab
17 changed files with 204 additions and 175 deletions

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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()))

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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 --------------------------------------------------------------

View File

@@ -127,7 +127,15 @@ public class AbstractRemoteCommandTestBase
{
return null;
}
}, null);
}, new Provider<GitRepositoryHandler>()
{
@Override
public GitRepositoryHandler get()
{
return null;
}
});
Transport.register(proto);
}

View File

@@ -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 ----------------------------------------------------------

View File

@@ -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;

View File

@@ -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 ----------------------------------------------------------

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View File

@@ -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);