mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-05 07:09:48 +01:00
Adjust to repository storage with id
This commit is contained in:
@@ -36,19 +36,16 @@ package sonia.scm.repository;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.repository.ImportResult.Builder;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Abstract base class for directory based {@link ImportHandler} and
|
||||
* {@link AdvancedImportHandler}.
|
||||
@@ -164,23 +161,24 @@ public abstract class AbstactImportHandler implements AdvancedImportHandler
|
||||
|
||||
logger.trace("search for repositories to import");
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
List<String> repositoryNames =
|
||||
RepositoryUtil.getRepositoryNames(getRepositoryHandler(),
|
||||
getDirectoryNames());
|
||||
|
||||
for (String repositoryName : repositoryNames)
|
||||
{
|
||||
importRepository(manager, builder, throwExceptions, repositoryName);
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
// TODO #8783
|
||||
// try
|
||||
// {
|
||||
//
|
||||
// List<String> repositoryNames =
|
||||
// RepositoryUtil.getRepositoryNames(getRepositoryHandler(),
|
||||
// getDirectoryNames());
|
||||
//
|
||||
// for (String repositoryName : repositoryNames)
|
||||
// {
|
||||
// importRepository(manager, builder, throwExceptions, repositoryName);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// catch (IOException ex)
|
||||
// {
|
||||
// handleException(ex, throwExceptions);
|
||||
// }
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@@ -214,46 +212,48 @@ public abstract class AbstactImportHandler implements AdvancedImportHandler
|
||||
* @param manager
|
||||
* @param builder
|
||||
* @param throwExceptions
|
||||
* @param repositoryName
|
||||
* @param directoryName
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
private void importRepository(RepositoryManager manager, Builder builder,
|
||||
boolean throwExceptions, String repositoryName)
|
||||
boolean throwExceptions, String directoryName)
|
||||
throws IOException, RepositoryException
|
||||
{
|
||||
logger.trace("check repository {} for import", repositoryName);
|
||||
logger.trace("check repository {} for import", directoryName);
|
||||
|
||||
Repository repository = manager.get(getTypeName(), repositoryName);
|
||||
|
||||
if (repository == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
importRepository(manager, repositoryName);
|
||||
builder.addImportedDirectory(repositoryName);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
builder.addFailedDirectory(repositoryName);
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
catch (IllegalStateException ex)
|
||||
{
|
||||
builder.addFailedDirectory(repositoryName);
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
catch (RepositoryException ex)
|
||||
{
|
||||
builder.addFailedDirectory(repositoryName);
|
||||
handleException(ex, throwExceptions);
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("repository {} is allready managed", repositoryName);
|
||||
}
|
||||
// TODO #8783
|
||||
//
|
||||
// Repository repository = manager.get(namespaceAndName);
|
||||
//
|
||||
// if (repository == null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// importRepository(manager, repositoryName);
|
||||
// builder.addImportedDirectory(repositoryName);
|
||||
// }
|
||||
// catch (IOException ex)
|
||||
// {
|
||||
// builder.addFailedDirectory(repositoryName);
|
||||
// handleException(ex, throwExceptions);
|
||||
// }
|
||||
// catch (IllegalStateException ex)
|
||||
// {
|
||||
// builder.addFailedDirectory(repositoryName);
|
||||
// handleException(ex, throwExceptions);
|
||||
// }
|
||||
// catch (RepositoryException ex)
|
||||
// {
|
||||
// builder.addFailedDirectory(repositoryName);
|
||||
// handleException(ex, throwExceptions);
|
||||
// }
|
||||
// }
|
||||
// else if (logger.isDebugEnabled())
|
||||
// {
|
||||
// logger.debug("repository {} is already managed", repositoryName);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package sonia.scm.repository;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class NamespaceAndName {
|
||||
|
||||
private final String namespace;
|
||||
private final String name;
|
||||
|
||||
public NamespaceAndName(String namespace, String name) {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "a non empty namespace is required");
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "a non empty name is required");
|
||||
this.namespace = namespace;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getNamespace() + "/" + getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
NamespaceAndName that = (NamespaceAndName) o;
|
||||
return Objects.equals(namespace, that.namespace) &&
|
||||
Objects.equals(name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(namespace, name);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,12 @@ import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.util.ValidationUtil;
|
||||
|
||||
import javax.xml.bind.annotation.*;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -95,9 +100,10 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
||||
* @param type type of the {@link Repository}
|
||||
* @param name name of the {@link Repository}
|
||||
*/
|
||||
public Repository(String id, String type, String name) {
|
||||
public Repository(String id, String type, String namespace, String name) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.namespace = namespace;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -189,6 +195,11 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
||||
|
||||
public String getNamespace() { return namespace; }
|
||||
|
||||
@XmlTransient
|
||||
public NamespaceAndName getNamespaceAndName() {
|
||||
return new NamespaceAndName(getNamespace(), getName());
|
||||
}
|
||||
|
||||
public List<Permission> getPermissions() {
|
||||
if (permissions == null) {
|
||||
permissions = Lists.newArrayList();
|
||||
@@ -347,7 +358,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
||||
public String createUrl(String baseUrl) {
|
||||
String url = HttpUtil.append(baseUrl, type);
|
||||
|
||||
return HttpUtil.append(url, name);
|
||||
return HttpUtil.concatenate(url, namespace, name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,27 +49,22 @@ public interface RepositoryDAO extends GenericDAO<Repository>
|
||||
|
||||
/**
|
||||
* Returns true if a repository with specified
|
||||
* type and name exists in the backend.
|
||||
* namespace and name exists in the backend.
|
||||
*
|
||||
*
|
||||
* @param type type of the repository
|
||||
* @param name name of the repository
|
||||
* @param namespaceAndName namespace and name of the repository
|
||||
*
|
||||
* @return true if the repository exists
|
||||
*/
|
||||
public boolean contains(String type, String name);
|
||||
boolean contains(NamespaceAndName namespaceAndName);
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the repository with the specified type and name or null
|
||||
* Returns the repository with the specified namespace and name or null
|
||||
* if no such repository exists in the backend.
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return repository with the specified type and name or null
|
||||
* @return repository with the specified namespace and name or null
|
||||
*/
|
||||
public Repository get(String type, String name);
|
||||
Repository get(NamespaceAndName namespaceAndName);
|
||||
}
|
||||
|
||||
@@ -38,13 +38,11 @@ package sonia.scm.repository;
|
||||
import sonia.scm.Type;
|
||||
import sonia.scm.TypeManager;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The central class for managing {@link Repository} objects.
|
||||
@@ -83,18 +81,17 @@ public interface RepositoryManager
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a {@link Repository} by its type and name or
|
||||
* Returns a {@link Repository} by its namespace and name or
|
||||
* null if the {@link Repository} could not be found.
|
||||
*
|
||||
*
|
||||
* @param type type of the {@link Repository}
|
||||
* @param name name of the {@link Repository}
|
||||
* @param namespaceAndName namespace and name of the {@link Repository}
|
||||
*
|
||||
*
|
||||
* @return {@link Repository} by its type and name or null
|
||||
* @return {@link Repository} by its namespace and name or null
|
||||
* if the {@link Repository} could not be found
|
||||
*/
|
||||
public Repository get(String type, String name);
|
||||
public Repository get(NamespaceAndName namespaceAndName);
|
||||
|
||||
/**
|
||||
* Returns all configured repository types.
|
||||
@@ -115,18 +112,6 @@ public interface RepositoryManager
|
||||
*/
|
||||
public Repository getFromRequest(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* Returns the {@link Repository} associated to the given type and path.
|
||||
*
|
||||
*
|
||||
* @param type type of the repository (hg, git ...)
|
||||
* @param uri
|
||||
*
|
||||
* @return the {@link Repository} associated to the given type and path
|
||||
* @since 1.9
|
||||
*/
|
||||
public Repository getFromTypeAndUri(String type, String uri);
|
||||
|
||||
/**
|
||||
* Returns the {@link Repository} associated to the request uri.
|
||||
*
|
||||
|
||||
@@ -38,13 +38,11 @@ package sonia.scm.repository;
|
||||
import sonia.scm.ManagerDecorator;
|
||||
import sonia.scm.Type;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Decorator for {@link RepositoryManager}.
|
||||
@@ -92,19 +90,10 @@ public class RepositoryManagerDecorator
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Repository get(String type, String name)
|
||||
public Repository get(NamespaceAndName namespaceAndName)
|
||||
{
|
||||
return decorated.get(type, name);
|
||||
return decorated.get(namespaceAndName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,21 +135,6 @@ public class RepositoryManagerDecorator
|
||||
return decorated.getFromRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param uri
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Repository getFromTypeAndUri(String type, String uri)
|
||||
{
|
||||
return decorated.getFromTypeAndUri(type, uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
||||
@@ -35,21 +35,20 @@ package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.io.DirectoryFileFilter;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -82,204 +81,43 @@ public final class RepositoryUtil
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static List<File> searchRepositoryDirectories(File directory,
|
||||
String... names)
|
||||
{
|
||||
List<File> repositories = new ArrayList<File>();
|
||||
public static List<File> searchRepositoryDirectories(File directory, String... names) {
|
||||
List<File> repositories = new ArrayList<>();
|
||||
|
||||
searchRepositoryDirectories(repositories, directory, Arrays.asList(names));
|
||||
|
||||
return repositories;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param handler
|
||||
* @param directoryPath
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getRepositoryName(AbstractRepositoryHandler handler,
|
||||
String directoryPath)
|
||||
throws IOException
|
||||
{
|
||||
return getRepositoryName(handler.getConfig().getRepositoryDirectory(),
|
||||
new File(directoryPath));
|
||||
public static String getRepositoryId(AbstractRepositoryHandler handler, String directoryPath) throws IOException {
|
||||
return getRepositoryId(handler.getConfig().getRepositoryDirectory(), new File(directoryPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
* @param directoryPath
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getRepositoryName(SimpleRepositoryConfig config,
|
||||
String directoryPath)
|
||||
throws IOException
|
||||
{
|
||||
return getRepositoryName(config.getRepositoryDirectory(),
|
||||
new File(directoryPath));
|
||||
public static String getRepositoryId(AbstractRepositoryHandler handler, File directory) throws IOException {
|
||||
return getRepositoryId(handler.getConfig(), directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param handler
|
||||
* @param directory
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getRepositoryName(AbstractRepositoryHandler handler,
|
||||
File directory)
|
||||
throws IOException
|
||||
{
|
||||
return getRepositoryName(handler.getConfig().getRepositoryDirectory(),
|
||||
directory);
|
||||
public static String getRepositoryId(SimpleRepositoryConfig config, File directory) throws IOException {
|
||||
return getRepositoryId(config.getRepositoryDirectory(), directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
* @param directory
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getRepositoryName(SimpleRepositoryConfig config,
|
||||
File directory)
|
||||
throws IOException
|
||||
{
|
||||
return getRepositoryName(config.getRepositoryDirectory(), directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param baseDirectory
|
||||
* @param directory
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getRepositoryName(File baseDirectory, File directory)
|
||||
throws IOException
|
||||
{
|
||||
String name = null;
|
||||
public static String getRepositoryId(File baseDirectory, File directory) throws IOException {
|
||||
String path = directory.getCanonicalPath();
|
||||
int directoryLength = baseDirectory.getCanonicalPath().length();
|
||||
|
||||
if (directoryLength < path.length())
|
||||
{
|
||||
name = IOUtil.trimSeperatorChars(path.substring(directoryLength));
|
||||
|
||||
// replace windows path seperator
|
||||
name = name.replaceAll("\\\\", "/");
|
||||
String id = IOUtil.trimSeperatorChars(path.substring(directoryLength));
|
||||
Preconditions.checkState(!id.contains("\\") && !id.contains("/"),
|
||||
"got illegal repository directory with separators in id: " + path);
|
||||
return id;
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
else
|
||||
{
|
||||
logger.warn("path is shorter as the main repository path");
|
||||
throw new IllegalStateException("path is shorter as the main repository path");
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param handler
|
||||
* @param directoryNames
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static List<String> getRepositoryNames(
|
||||
AbstractRepositoryHandler handler, String... directoryNames)
|
||||
throws IOException
|
||||
{
|
||||
return getRepositoryNames(handler.getConfig(), directoryNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
* @param directoryNames
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static List<String> getRepositoryNames(SimpleRepositoryConfig config,
|
||||
String... directoryNames)
|
||||
throws IOException
|
||||
{
|
||||
return getRepositoryNames(config.getRepositoryDirectory(), directoryNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param baseDirectory
|
||||
* @param directoryNames
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static List<String> getRepositoryNames(File baseDirectory,
|
||||
String... directoryNames)
|
||||
throws IOException
|
||||
{
|
||||
List<String> repositories = new ArrayList<String>();
|
||||
List<File> repositoryFiles = searchRepositoryDirectories(baseDirectory,
|
||||
directoryNames);
|
||||
|
||||
for (File file : repositoryFiles)
|
||||
{
|
||||
String name = getRepositoryName(baseDirectory, file);
|
||||
|
||||
if (name != null)
|
||||
{
|
||||
repositories.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return repositories;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param repositories
|
||||
* @param directory
|
||||
* @param names
|
||||
*/
|
||||
private static void searchRepositoryDirectories(List<File> repositories,
|
||||
File directory, List<String> names)
|
||||
{
|
||||
|
||||
@@ -37,20 +37,20 @@ package sonia.scm.repository.api;
|
||||
|
||||
import com.github.legman.ReferenceType;
|
||||
import com.github.legman.Subscribe;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.HandlerEventType;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.repository.ClearRepositoryCacheEvent;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
|
||||
import sonia.scm.repository.PreProcessorUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
@@ -63,11 +63,9 @@ import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.spi.RepositoryServiceResolver;
|
||||
import sonia.scm.security.ScmSecurityException;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Set;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.repository.ClearRepositoryCacheEvent;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The {@link RepositoryServiceFactory} is the entrypoint of the repository api.
|
||||
@@ -190,8 +188,7 @@ public final class RepositoryServiceFactory
|
||||
* Creates a new RepositoryService for the given repository.
|
||||
*
|
||||
*
|
||||
* @param type type of the repository
|
||||
* @param name name of the repository
|
||||
* @param namespaceAndName namespace and name of the repository
|
||||
*
|
||||
* @return a implementation of RepositoryService
|
||||
* for the given type of repository
|
||||
@@ -204,24 +201,19 @@ public final class RepositoryServiceFactory
|
||||
* @throws ScmSecurityException if current user has not read permissions
|
||||
* for that repository
|
||||
*/
|
||||
public RepositoryService create(String type, String name)
|
||||
public RepositoryService create(NamespaceAndName namespaceAndName)
|
||||
throws RepositoryNotFoundException
|
||||
{
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(type),
|
||||
"a non empty type is required");
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(name),
|
||||
"a non empty name is required");
|
||||
Preconditions.checkArgument(namespaceAndName != null,
|
||||
"a non empty namespace and name is required");
|
||||
|
||||
Repository repository = repositoryManager.get(type, name);
|
||||
Repository repository = repositoryManager.get(namespaceAndName);
|
||||
|
||||
if (repository == null)
|
||||
{
|
||||
StringBuilder msg =
|
||||
new StringBuilder("could not find a repository with type ");
|
||||
String msg = "could not find a repository with namespace/name " + namespaceAndName;
|
||||
|
||||
msg.append(type).append(" and name ").append(name);
|
||||
|
||||
throw new RepositoryNotFoundException(msg.toString());
|
||||
throw new RepositoryNotFoundException(msg);
|
||||
}
|
||||
|
||||
return create(repository);
|
||||
|
||||
@@ -35,7 +35,7 @@ package sonia.scm.repository.spi;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryException;
|
||||
import sonia.scm.repository.RepositoryHookEvent;
|
||||
@@ -72,50 +72,15 @@ public final class HookEventFacade
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public HookEventHandler handle(String id) throws RepositoryException
|
||||
{
|
||||
public HookEventHandler handle(String id) throws RepositoryException {
|
||||
return handle(repositoryManagerProvider.get().get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param repositoryName
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public HookEventHandler handle(String type, String repositoryName)
|
||||
throws RepositoryException
|
||||
{
|
||||
return handle(repositoryManagerProvider.get().get(type, repositoryName));
|
||||
public HookEventHandler handle(NamespaceAndName namespaceAndName) throws RepositoryException {
|
||||
return handle(repositoryManagerProvider.get().get(namespaceAndName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param repository
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public HookEventHandler handle(Repository repository)
|
||||
throws RepositoryException
|
||||
public HookEventHandler handle(Repository repository) throws RepositoryException
|
||||
{
|
||||
if (repository == null)
|
||||
{
|
||||
|
||||
@@ -39,27 +39,23 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Util method for the http protocol.
|
||||
@@ -252,13 +248,15 @@ public final class HttpUtil
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
public static String concatenate(String... pathElements) {
|
||||
return Arrays.stream(pathElements).reduce(HttpUtil::append).orElse("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the suffix to given uri.
|
||||
*
|
||||
*
|
||||
* @param uri uri
|
||||
* @param uri uri
|
||||
* @param suffix suffix
|
||||
*
|
||||
* @return
|
||||
* @since 1.9
|
||||
*/
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.web.filter;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public abstract class RegexPermissionFilter extends PermissionFilter
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final Pattern PATTERN_REPOSITORYNAME =
|
||||
Pattern.compile("/[^/]+/([^/]+)(?:/.*)?");
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param repositoryManager
|
||||
*/
|
||||
public RegexPermissionFilter(ScmConfiguration configuration,
|
||||
RepositoryManager repositoryManager)
|
||||
{
|
||||
super(configuration);
|
||||
this.repositoryManager = repositoryManager;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract String getType();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected Repository getRepository(HttpServletRequest request)
|
||||
{
|
||||
Repository repository = null;
|
||||
String uri = request.getRequestURI();
|
||||
|
||||
uri = uri.substring(request.getContextPath().length());
|
||||
|
||||
Matcher m = PATTERN_REPOSITORYNAME.matcher(uri);
|
||||
|
||||
if (m.matches())
|
||||
{
|
||||
String repositoryname = m.group(1);
|
||||
|
||||
repository = getRepository(repositoryname);
|
||||
}
|
||||
|
||||
return repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected Repository getRepository(String name)
|
||||
{
|
||||
return repositoryManager.get(getType(), name);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private RepositoryManager repositoryManager;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ package sonia.scm.repository;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -50,7 +50,7 @@ public class RepositoryTest
|
||||
@Test
|
||||
public void testCreateUrl()
|
||||
{
|
||||
Repository repository = new Repository("123", "hg", "test/repo");
|
||||
Repository repository = new Repository("123", "hg", "test", "repo");
|
||||
|
||||
assertEquals("http://localhost:8080/scm/hg/test/repo",
|
||||
repository.createUrl("http://localhost:8080/scm"));
|
||||
|
||||
@@ -36,11 +36,11 @@ package sonia.scm.repository.xml;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryDAO;
|
||||
import sonia.scm.xml.AbstractXmlDAO;
|
||||
import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.xml.AbstractXmlDAO;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -71,36 +71,18 @@ public class XmlRepositoryDAO
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(String type, String name)
|
||||
public boolean contains(NamespaceAndName namespaceAndName)
|
||||
{
|
||||
return db.contains(type, name);
|
||||
return db.contains(namespaceAndName);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Repository get(String type, String name)
|
||||
public Repository get(NamespaceAndName namespaceAndName)
|
||||
{
|
||||
return db.get(type, name);
|
||||
return db.get(namespaceAndName);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
@@ -35,34 +35,26 @@ package sonia.scm.repository.xml;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.xml.XmlDatabase;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@XmlRootElement(name = "repository-db")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public XmlRepositoryDatabase()
|
||||
{
|
||||
long c = System.currentTimeMillis();
|
||||
@@ -71,124 +63,53 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
||||
lastModified = c;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static String createKey(String type, String name)
|
||||
static String createKeyX(NamespaceAndName namespaceAndName)
|
||||
{
|
||||
return type.concat(":").concat(name);
|
||||
return namespaceAndName.getNamespace() + ":" + namespaceAndName.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param repository
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static String createKey(Repository repository)
|
||||
static String createKeyX(Repository repository)
|
||||
{
|
||||
return createKey(repository.getType(), repository.getName());
|
||||
return createKeyX(repository.getNamespaceAndName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param repository
|
||||
*/
|
||||
@Override
|
||||
public void add(Repository repository)
|
||||
{
|
||||
repositoryMap.put(createKey(repository), repository);
|
||||
repositoryMap.put(createKeyX(repository), repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(String type, String name)
|
||||
public boolean contains(NamespaceAndName namespaceAndName)
|
||||
{
|
||||
return repositoryMap.containsKey(createKey(type, name));
|
||||
return repositoryMap.containsKey(createKeyX(namespaceAndName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(String id)
|
||||
{
|
||||
return get(id) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param repository
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(Repository repository)
|
||||
{
|
||||
return repositoryMap.containsKey(createKey(repository));
|
||||
return repositoryMap.containsKey(createKeyX(repository));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param repository
|
||||
*/
|
||||
public void remove(Repository repository)
|
||||
public void removeX(Repository repository)
|
||||
{
|
||||
repositoryMap.remove(createKey(repository));
|
||||
repositoryMap.remove(createKeyX(repository));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Repository remove(String id)
|
||||
{
|
||||
Repository r = get(id);
|
||||
|
||||
remove(r);
|
||||
removeX(r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Collection<Repository> values()
|
||||
{
|
||||
@@ -197,18 +118,9 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Repository get(String type, String name)
|
||||
public Repository get(NamespaceAndName namespaceAndName)
|
||||
{
|
||||
return repositoryMap.get(createKey(type, name));
|
||||
return repositoryMap.get(createKeyX(namespaceAndName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,6 +210,5 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
||||
/** Field description */
|
||||
@XmlJavaTypeAdapter(XmlRepositoryMapAdapter.class)
|
||||
@XmlElement(name = "repositories")
|
||||
private Map<String, Repository> repositoryMap = new LinkedHashMap<String,
|
||||
Repository>();
|
||||
private Map<String, Repository> repositoryMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
@@ -37,12 +37,11 @@ package sonia.scm.repository.xml;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -88,7 +87,7 @@ public class XmlRepositoryMapAdapter
|
||||
|
||||
for (Repository repository : repositories)
|
||||
{
|
||||
repositoryMap.put(XmlRepositoryDatabase.createKey(repository),
|
||||
repositoryMap.put(XmlRepositoryDatabase.createKeyX(repository),
|
||||
repository);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,24 +40,21 @@ 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.GitRepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.RepositoryUtil;
|
||||
import sonia.scm.repository.spi.GitHookContextProvider;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -131,15 +128,14 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
||||
try
|
||||
{
|
||||
Repository repository = rpack.getRepository();
|
||||
String repositoryName = resolveRepositoryName(repository);
|
||||
String id = resolveRepositoryId(repository);
|
||||
|
||||
logger.trace("resolved repository name to {}", repositoryName);
|
||||
logger.trace("resolved repository to id {}", id);
|
||||
|
||||
GitHookContextProvider context = new GitHookContextProvider(rpack,
|
||||
receiveCommands);
|
||||
|
||||
hookEventFacade.handle(GitRepositoryHandler.TYPE_NAME,
|
||||
repositoryName).fireHookEvent(type, context);
|
||||
hookEventFacade.handle(id).fireHookEvent(type, context);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -191,7 +187,7 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private String resolveRepositoryName(Repository repository) throws IOException
|
||||
private String resolveRepositoryId(Repository repository) throws IOException
|
||||
{
|
||||
File directory;
|
||||
|
||||
@@ -204,7 +200,7 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
||||
directory = repository.getWorkTree();
|
||||
}
|
||||
|
||||
return RepositoryUtil.getRepositoryName(handler, directory);
|
||||
return RepositoryUtil.getRepositoryId(handler, directory);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
@@ -106,7 +106,7 @@ public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
gitConfig.setRepositoryDirectory(new File("/path"));
|
||||
repositoryHandler.setConfig(gitConfig);
|
||||
|
||||
Repository repository = new Repository("id", "git", "Name");
|
||||
Repository repository = new Repository("id", "git", "Space", "Name");
|
||||
|
||||
File path = repositoryHandler.getDirectory(repository);
|
||||
assertEquals("/path/id", path.getAbsolutePath());
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
package sonia.scm.repository;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GitRepositoryPathMatcher}.
|
||||
@@ -45,18 +47,18 @@ public class GitRepositoryPathMatcherTest {
|
||||
|
||||
@Test
|
||||
public void testIsPathMatching() {
|
||||
assertFalse(pathMatcher.isPathMatching(repository("my-repo"), "my-repoo"));
|
||||
assertFalse(pathMatcher.isPathMatching(repository("my"), "my-repo"));
|
||||
assertFalse(pathMatcher.isPathMatching(repository("my"), "my-repo/with/path"));
|
||||
assertFalse(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repoo"));
|
||||
assertFalse(pathMatcher.isPathMatching(repository("space", "my"), "my-repo"));
|
||||
assertFalse(pathMatcher.isPathMatching(repository("space", "my"), "my-repo/with/path"));
|
||||
|
||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo.git"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo/with/path"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo.git/with/path"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo.git"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo/with/path"));
|
||||
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo.git/with/path"));
|
||||
}
|
||||
|
||||
private Repository repository(String name) {
|
||||
return new Repository(name, GitRepositoryHandler.TYPE_NAME, name);
|
||||
private Repository repository(String namespace, String name) {
|
||||
return new Repository(name, GitRepositoryHandler.TYPE_NAME, namespace, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,34 +38,31 @@ package sonia.scm.repository.spi;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.api.CommitCommand;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.transport.ScmTransportProtocol;
|
||||
import org.eclipse.jgit.transport.Transport;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserTestData;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -88,8 +85,8 @@ public class AbstractRemoteCommandTestBase
|
||||
outgoingDirectory = tempFolder.newFile("outgoing");
|
||||
outgoingDirectory.delete();
|
||||
|
||||
incomgingRepository = new Repository("1", "git", "incoming");
|
||||
outgoingRepository = new Repository("2", "git", "outgoing");
|
||||
incomgingRepository = new Repository("1", "git", "space", "incoming");
|
||||
outgoingRepository = new Repository("2", "git", "space", "outgoing");
|
||||
|
||||
incoming = Git.init().setDirectory(incomingDirectory).setBare(false).call();
|
||||
outgoing = Git.init().setDirectory(outgoingDirectory).setBare(false).call();
|
||||
|
||||
@@ -35,14 +35,15 @@ package sonia.scm.web.lfs;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import static org.mockito.Matchers.matches;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.BlobStoreFactory;
|
||||
|
||||
import static org.mockito.Matchers.matches;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link LfsBlobStoreFactory}.
|
||||
*
|
||||
@@ -59,7 +60,7 @@ public class LfsBlobStoreFactoryTest {
|
||||
|
||||
@Test
|
||||
public void getBlobStore() throws Exception {
|
||||
lfsBlobStoreFactory.getLfsBlobStore(new Repository("the-id", "GIT", "the-name"));
|
||||
lfsBlobStoreFactory.getLfsBlobStore(new Repository("the-id", "GIT", "space", "the-name"));
|
||||
|
||||
// just make sure the right parameter is passed, as properly validating the return value is nearly impossible with
|
||||
// the return value (and should not be part of this test)
|
||||
|
||||
@@ -7,8 +7,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Created by omilke on 18.05.2017.
|
||||
@@ -18,14 +19,15 @@ public class LfsServletFactoryTest {
|
||||
@Test
|
||||
public void buildBaseUri() throws Exception {
|
||||
|
||||
String repositoryNamespace = "space";
|
||||
String repositoryName = "git-lfs-demo";
|
||||
|
||||
String result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryName), RequestWithUri(repositoryName, true));
|
||||
String result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryNamespace, repositoryName), RequestWithUri(repositoryName, true));
|
||||
assertThat(result, is(equalTo("http://localhost:8081/scm/git/git-lfs-demo.git/info/lfs/objects/")));
|
||||
|
||||
|
||||
//result will be with dot-gix suffix, ide
|
||||
result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryName), RequestWithUri(repositoryName, false));
|
||||
result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryNamespace, repositoryName), RequestWithUri(repositoryName, false));
|
||||
assertThat(result, is(equalTo("http://localhost:8081/scm/git/git-lfs-demo.git/info/lfs/objects/")));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,20 +34,18 @@ package sonia.scm.repository.spi;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.aragost.javahg.Repository;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.spi.javahg.HgLogChangesetCommand;
|
||||
import sonia.scm.web.HgUtil;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -63,22 +61,12 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param handler
|
||||
* @param repositoryName
|
||||
* @param hookManager
|
||||
* @param startRev
|
||||
* @param type
|
||||
*/
|
||||
public HgHookChangesetProvider(HgRepositoryHandler handler,
|
||||
String repositoryName, HgHookManager hookManager, String startRev,
|
||||
String id, HgHookManager hookManager, String startRev,
|
||||
RepositoryHookType type)
|
||||
{
|
||||
this.handler = handler;
|
||||
this.repositoryName = repositoryName;
|
||||
this.id = id;
|
||||
this.hookManager = hookManager;
|
||||
this.startRev = startRev;
|
||||
this.type = type;
|
||||
@@ -136,7 +124,7 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
||||
private Repository open()
|
||||
{
|
||||
File directory = handler.getConfig().getRepositoryDirectory();
|
||||
File repositoryDirectory = new File(directory, repositoryName);
|
||||
File repositoryDirectory = new File(directory, id);
|
||||
|
||||
// use HG_PENDING only for pre receive hooks
|
||||
boolean pending = type == RepositoryHookType.PRE_RECEIVE;
|
||||
@@ -155,7 +143,7 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
||||
private HgHookManager hookManager;
|
||||
|
||||
/** Field description */
|
||||
private String repositoryName;
|
||||
private String id;
|
||||
|
||||
/** Field description */
|
||||
private HookChangesetResponse response;
|
||||
|
||||
@@ -38,16 +38,16 @@ import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.api.HgHookBranchProvider;
|
||||
import sonia.scm.repository.api.HgHookMessageProvider;
|
||||
import sonia.scm.repository.api.HgHookTagProvider;
|
||||
import sonia.scm.repository.api.HookBranchProvider;
|
||||
import sonia.scm.repository.api.HookFeature;
|
||||
import sonia.scm.repository.api.HookMessageProvider;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
import sonia.scm.repository.api.HookTagProvider;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import sonia.scm.repository.api.HgHookTagProvider;
|
||||
import sonia.scm.repository.api.HookTagProvider;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mercurial implementation of {@link HookContextProvider}.
|
||||
@@ -67,17 +67,16 @@ public class HgHookContextProvider extends HookContextProvider
|
||||
* Constructs a new instance.
|
||||
*
|
||||
* @param handler mercurial repository handler
|
||||
* @param repositoryName name of changed repository
|
||||
* @param namespaceAndName namespace and name of changed repository
|
||||
* @param hookManager mercurial hook manager
|
||||
* @param startRev start revision
|
||||
* @param type type of hook
|
||||
*/
|
||||
public HgHookContextProvider(HgRepositoryHandler handler,
|
||||
String repositoryName, HgHookManager hookManager, String startRev,
|
||||
String id, HgHookManager hookManager, String startRev,
|
||||
RepositoryHookType type)
|
||||
{
|
||||
this.hookChangesetProvider = new HgHookChangesetProvider(handler,
|
||||
repositoryName, hookManager, startRev, type);
|
||||
this.hookChangesetProvider = new HgHookChangesetProvider(handler, id, hookManager, startRev, type);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
@@ -40,13 +40,10 @@ import com.google.common.io.Closeables;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.repository.HgContext;
|
||||
import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
@@ -62,19 +59,17 @@ import sonia.scm.security.Tokens;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -187,7 +182,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
if (m.matches())
|
||||
{
|
||||
String repositoryId = getRepositoryName(request);
|
||||
String id = getRepositoryId(request);
|
||||
String type = m.group(1);
|
||||
String challenge = request.getParameter(PARAM_CHALLENGE);
|
||||
|
||||
@@ -204,7 +199,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
authenticate(request, credentials);
|
||||
}
|
||||
|
||||
hookCallback(response, repositoryId, type, challenge, node);
|
||||
hookCallback(response, id, type, challenge, node);
|
||||
}
|
||||
else if (logger.isDebugEnabled())
|
||||
{
|
||||
@@ -227,13 +222,6 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param credentials
|
||||
*/
|
||||
private void authenticate(HttpServletRequest request, String credentials)
|
||||
{
|
||||
try
|
||||
@@ -270,18 +258,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param response
|
||||
* @param repositoryName
|
||||
* @param node
|
||||
* @param type
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void fireHook(HttpServletResponse response, String repositoryName,
|
||||
private void fireHook(HttpServletResponse response, String id,
|
||||
String node, RepositoryHookType type)
|
||||
throws IOException
|
||||
{
|
||||
@@ -294,11 +271,10 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
contextProvider.get().setPending(true);
|
||||
}
|
||||
|
||||
context = new HgHookContextProvider(handler, repositoryName, hookManager,
|
||||
context = new HgHookContextProvider(handler, id, hookManager,
|
||||
node, type);
|
||||
|
||||
hookEventFacade.handle(HgRepositoryHandler.TYPE_NAME,
|
||||
repositoryName).fireHookEvent(type, context);
|
||||
hookEventFacade.handle(id).fireHookEvent(type, context);
|
||||
|
||||
printMessages(response, context);
|
||||
}
|
||||
@@ -306,7 +282,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
{
|
||||
if (logger.isErrorEnabled())
|
||||
{
|
||||
logger.error("could not find repository {}", repositoryName);
|
||||
logger.error("could not find repository with id {}", id);
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
@@ -322,22 +298,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param response
|
||||
* @param repositoryName
|
||||
* @param typeName
|
||||
* @param challenge
|
||||
* @param node
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void hookCallback(HttpServletResponse response,
|
||||
String repositoryName, String typeName, String challenge, String node)
|
||||
throws IOException
|
||||
{
|
||||
private void hookCallback(HttpServletResponse response, String id, String typeName, String challenge, String node) throws IOException {
|
||||
if (hookManager.isAcceptAble(challenge))
|
||||
{
|
||||
RepositoryHookType type = null;
|
||||
@@ -353,7 +314,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
fireHook(response, repositoryName, node, type);
|
||||
fireHook(response, id, node, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -403,12 +364,12 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param resonse
|
||||
* @param response
|
||||
* @param context
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void printMessages(HttpServletResponse resonse,
|
||||
private void printMessages(HttpServletResponse response,
|
||||
HgHookContextProvider context)
|
||||
throws IOException
|
||||
{
|
||||
@@ -420,7 +381,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
try
|
||||
{
|
||||
writer = resonse.getWriter();
|
||||
writer = response.getWriter();
|
||||
|
||||
printMessages(writer, msgs);
|
||||
}
|
||||
@@ -506,9 +467,9 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getRepositoryName(HttpServletRequest request)
|
||||
private String getRepositoryId(HttpServletRequest request)
|
||||
{
|
||||
String name = null;
|
||||
String id = null;
|
||||
String path = request.getParameter(PARAM_REPOSITORYPATH);
|
||||
|
||||
if (Util.isNotEmpty(path))
|
||||
@@ -520,11 +481,11 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
*/
|
||||
try
|
||||
{
|
||||
name = RepositoryUtil.getRepositoryName(handler, path);
|
||||
id = RepositoryUtil.getRepositoryId(handler, path);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.error("could not find name of repository", ex);
|
||||
logger.error("could not find namespace and name of repository", ex);
|
||||
}
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
@@ -532,7 +493,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
logger.warn("no repository path parameter found");
|
||||
}
|
||||
|
||||
return name;
|
||||
return id;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
@@ -101,7 +101,7 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
hgConfig.setPythonBinary("python");
|
||||
repositoryHandler.setConfig(hgConfig);
|
||||
|
||||
Repository repository = new Repository("id", "git", "Name");
|
||||
Repository repository = new Repository("id", "git", "Space", "Name");
|
||||
|
||||
File path = repositoryHandler.getDirectory(repository);
|
||||
assertEquals("/path/id", path.getAbsolutePath());
|
||||
|
||||
@@ -41,14 +41,11 @@ import com.aragost.javahg.Repository;
|
||||
import com.aragost.javahg.RepositoryConfiguration;
|
||||
import com.aragost.javahg.commands.AddCommand;
|
||||
import com.aragost.javahg.commands.CommitCommand;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import sonia.scm.AbstractTestBase;
|
||||
import sonia.scm.repository.HgConfig;
|
||||
import sonia.scm.repository.HgContext;
|
||||
@@ -58,15 +55,15 @@ import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserTestData;
|
||||
import sonia.scm.util.MockUtil;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -90,10 +87,8 @@ public abstract class IncomingOutgoingTestBase extends AbstractTestBase
|
||||
incomingDirectory = tempFolder.newFolder("incoming");
|
||||
outgoingDirectory = tempFolder.newFolder("outgoing");
|
||||
|
||||
incomingRepository = new sonia.scm.repository.Repository("1", "hg",
|
||||
"incoming");
|
||||
outgoingRepository = new sonia.scm.repository.Repository("2", "hg",
|
||||
"outgoing");
|
||||
incomingRepository = new sonia.scm.repository.Repository("1", "hg", "space", "incoming");
|
||||
outgoingRepository = new sonia.scm.repository.Repository("2", "hg", "space", "outgoing");
|
||||
|
||||
incoming = Repository.create(createConfig(temp), incomingDirectory);
|
||||
outgoing = Repository.create(createConfig(temp), outgoingDirectory);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package sonia.scm.web;
|
||||
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.HgConfig;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sonia.scm.web.HgHookCallbackServlet.PARAM_REPOSITORYPATH;
|
||||
|
||||
public class HgHookCallbackServletTest {
|
||||
|
||||
@Test
|
||||
public void shouldExtractCorrectRepositoryId() throws ServletException, IOException {
|
||||
HgRepositoryHandler handler = mock(HgRepositoryHandler.class);
|
||||
HgHookCallbackServlet servlet = new HgHookCallbackServlet(null, handler, null, null);
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
HgConfig config = mock(HgConfig.class);
|
||||
|
||||
when(request.getContextPath()).thenReturn("http://example.com/scm");
|
||||
when(request.getRequestURI()).thenReturn("http://example.com/scm/hook/hg/pretxnchangegroup");
|
||||
when(request.getParameter(PARAM_REPOSITORYPATH)).thenReturn("/tmp/hg/12345");
|
||||
|
||||
when(handler.getConfig()).thenReturn(config);
|
||||
when(config.getRepositoryDirectory()).thenReturn(new File("/tmp/hg"));
|
||||
|
||||
servlet.doPost(request, response);
|
||||
|
||||
verify(response, never()).sendError(anyInt());
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ package sonia.scm.repository;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNCancelException;
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
@@ -45,21 +44,19 @@ import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.internal.io.fs.FSHook;
|
||||
import org.tmatesoft.svn.core.internal.io.fs.FSHookEvent;
|
||||
import org.tmatesoft.svn.core.internal.io.fs.FSHooks;
|
||||
|
||||
import sonia.scm.repository.spi.AbstractSvnHookChangesetProvider;
|
||||
import sonia.scm.repository.spi.HookEventFacade;
|
||||
import sonia.scm.repository.spi.SvnHookContextProvider;
|
||||
import sonia.scm.repository.spi.SvnPostReceiveHookChangesetProvier;
|
||||
import sonia.scm.repository.spi.SvnPreReceiveHookChangesetProvier;
|
||||
import sonia.scm.util.AssertUtil;
|
||||
import sonia.scm.util.IOUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -166,12 +163,10 @@ public class SvnRepositoryHook implements FSHook
|
||||
{
|
||||
try
|
||||
{
|
||||
String name = getRepositoryName(directory);
|
||||
|
||||
name = IOUtil.trimSeperatorChars(name);
|
||||
String id = getRepositoryId(directory);
|
||||
|
||||
//J-
|
||||
hookEventFacade.handle(SvnRepositoryHandler.TYPE_NAME, name)
|
||||
hookEventFacade.handle(id)
|
||||
.fireHookEvent(
|
||||
changesetProvider.getType(),
|
||||
new SvnHookContextProvider(changesetProvider)
|
||||
@@ -202,11 +197,11 @@ public class SvnRepositoryHook implements FSHook
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private String getRepositoryName(File directory) throws IOException
|
||||
private String getRepositoryId(File directory) throws IOException
|
||||
{
|
||||
AssertUtil.assertIsNotNull(directory);
|
||||
|
||||
return RepositoryUtil.getRepositoryName(handler, directory);
|
||||
return RepositoryUtil.getRepositoryId(handler, directory);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
@@ -113,7 +113,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
svnConfig.setRepositoryDirectory(new File("/path"));
|
||||
repositoryHandler.setConfig(svnConfig);
|
||||
|
||||
Repository repository = new Repository("id", "svn", "Name");
|
||||
Repository repository = new Repository("id", "svn", "Space", "Name");
|
||||
|
||||
File path = repositoryHandler.getDirectory(repository);
|
||||
assertEquals("/path/id", path.getAbsolutePath());
|
||||
|
||||
@@ -56,7 +56,7 @@ public class DummyRepositoryHandler
|
||||
|
||||
public static final Type TYPE = new Type(TYPE_NAME, TYPE_DISPLAYNAME);
|
||||
|
||||
private Set<String> existingRepoNames = new HashSet<>();
|
||||
private final Set<String> existingRepoNames = new HashSet<>();
|
||||
|
||||
public DummyRepositoryHandler(ConfigurationStoreFactory storeFactory) {
|
||||
super(storeFactory, new DefaultFileSystem());
|
||||
@@ -69,12 +69,12 @@ public class DummyRepositoryHandler
|
||||
|
||||
|
||||
@Override
|
||||
protected void create(Repository repository, File directory)
|
||||
throws RepositoryException {
|
||||
if (existingRepoNames.contains(repository.getNamespace() + repository.getName())) {
|
||||
protected void create(Repository repository, File directory) throws RepositoryException {
|
||||
String key = repository.getNamespace() + "/" + repository.getName();
|
||||
if (existingRepoNames.contains(key)) {
|
||||
throw new RepositoryAlreadyExistsException("Repo exists");
|
||||
} else {
|
||||
existingRepoNames.add(repository.getNamespace() + repository.getName());
|
||||
existingRepoNames.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package sonia.scm.repository;
|
||||
|
||||
public class RepositoryBuilder {
|
||||
|
||||
private String id = "id-" + ++nextID;
|
||||
private String contact = "test@example.com";
|
||||
private String description = "";
|
||||
private String namespace = "test";
|
||||
private String name = "name";
|
||||
private String type = "git";
|
||||
|
||||
private static int nextID = 0;
|
||||
|
||||
public RepositoryBuilder type(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RepositoryBuilder contact(String contact) {
|
||||
this.contact = contact;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RepositoryBuilder namespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RepositoryBuilder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RepositoryBuilder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Repository build() {
|
||||
Repository repository = new Repository();
|
||||
repository.setId(id);
|
||||
repository.setType(type);
|
||||
repository.setContact(contact);
|
||||
repository.setNamespace(namespace);
|
||||
repository.setName(name);
|
||||
repository.setDescription(description);
|
||||
return repository;
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,13 @@
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
@@ -26,26 +26,22 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
public final class RepositoryTestData
|
||||
{
|
||||
public final class RepositoryTestData {
|
||||
|
||||
private RepositoryTestData() {}
|
||||
private RepositoryTestData() {
|
||||
}
|
||||
|
||||
public static Repository create42Puzzle()
|
||||
{
|
||||
public static Repository create42Puzzle() {
|
||||
return create42Puzzle(DummyRepositoryHandler.TYPE_NAME);
|
||||
}
|
||||
|
||||
public static Repository create42Puzzle(String type)
|
||||
{
|
||||
return new Builder()
|
||||
public static Repository create42Puzzle(String type) {
|
||||
return new RepositoryBuilder()
|
||||
.type(type)
|
||||
.contact("douglas.adams@hitchhiker.com")
|
||||
.name("42Puzzle")
|
||||
@@ -53,15 +49,13 @@ public final class RepositoryTestData
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Repository createHappyVerticalPeopleTransporter()
|
||||
{
|
||||
public static Repository createHappyVerticalPeopleTransporter() {
|
||||
return createHappyVerticalPeopleTransporter(
|
||||
DummyRepositoryHandler.TYPE_NAME);
|
||||
}
|
||||
|
||||
public static Repository createHappyVerticalPeopleTransporter(String type)
|
||||
{
|
||||
return new Builder()
|
||||
public static Repository createHappyVerticalPeopleTransporter(String type) {
|
||||
return new RepositoryBuilder()
|
||||
.type(type)
|
||||
.contact("zaphod.beeblebrox@hitchhiker.com")
|
||||
.name("happyVerticalPeopleTransporter")
|
||||
@@ -69,14 +63,12 @@ public final class RepositoryTestData
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Repository createHeartOfGold()
|
||||
{
|
||||
public static Repository createHeartOfGold() {
|
||||
return createHeartOfGold(DummyRepositoryHandler.TYPE_NAME);
|
||||
}
|
||||
|
||||
public static Repository createHeartOfGold(String type)
|
||||
{
|
||||
return new Builder()
|
||||
public static Repository createHeartOfGold(String type) {
|
||||
return new RepositoryBuilder()
|
||||
.type(type)
|
||||
.contact("zaphod.beeblebrox@hitchhiker.com")
|
||||
.name("HeartOfGold")
|
||||
@@ -85,51 +77,17 @@ public final class RepositoryTestData
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Repository createRestaurantAtTheEndOfTheUniverse()
|
||||
{
|
||||
public static Repository createRestaurantAtTheEndOfTheUniverse() {
|
||||
return createRestaurantAtTheEndOfTheUniverse(
|
||||
DummyRepositoryHandler.TYPE_NAME);
|
||||
}
|
||||
|
||||
public static Repository createRestaurantAtTheEndOfTheUniverse(String type)
|
||||
{
|
||||
return new Builder()
|
||||
public static Repository createRestaurantAtTheEndOfTheUniverse(String type) {
|
||||
return new RepositoryBuilder()
|
||||
.type(type)
|
||||
.contact("douglas.adams@hitchhiker.com")
|
||||
.name("RestaurantAtTheEndOfTheUniverse")
|
||||
.description("The Restaurant at the End of the Universe")
|
||||
.build();
|
||||
}
|
||||
|
||||
private static class Builder {
|
||||
private static int nextID = 0;
|
||||
Repository repository = new Repository();
|
||||
{
|
||||
repository.setId("ID-" + ++nextID);
|
||||
}
|
||||
|
||||
Builder type(String type) {
|
||||
repository.setType(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder contact(String contact) {
|
||||
repository.setContact(contact);
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder name(String name) {
|
||||
repository.setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder description(String description) {
|
||||
repository.setDescription(description);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Repository build() {
|
||||
return repository;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +40,10 @@ import sonia.scm.store.InMemoryConfigurationStoreFactory;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
@@ -59,19 +60,12 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
ConfigurationStoreFactory factory, File directory);
|
||||
|
||||
@Test
|
||||
public void testCreate() throws RepositoryException, IOException {
|
||||
createRepository();
|
||||
}
|
||||
|
||||
@Test(expected = RepositoryAlreadyExistsException.class)
|
||||
public void testCreateExisitingRepository()
|
||||
throws RepositoryException, IOException {
|
||||
createRepository();
|
||||
public void testCreate() throws RepositoryException {
|
||||
createRepository();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateResourcePath() throws RepositoryException, IOException {
|
||||
public void testCreateResourcePath() throws RepositoryException {
|
||||
Repository repository = createRepository();
|
||||
String path = handler.createResourcePath(repository);
|
||||
|
||||
@@ -81,7 +75,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws RepositoryException, IOException {
|
||||
public void testDelete() throws RepositoryException {
|
||||
Repository repository = createRepository();
|
||||
|
||||
handler.delete(repository);
|
||||
@@ -92,7 +86,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postSetUp() throws Exception {
|
||||
protected void postSetUp() {
|
||||
InMemoryConfigurationStoreFactory storeFactory = new InMemoryConfigurationStoreFactory();
|
||||
baseDirectory = new File(contextProvider.getBaseDirectory(), "repositories");
|
||||
IOUtil.mkdirs(baseDirectory);
|
||||
@@ -106,7 +100,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private Repository createRepository() throws RepositoryException, IOException {
|
||||
private Repository createRepository() throws RepositoryException {
|
||||
Repository repository = RepositoryTestData.createHeartOfGold();
|
||||
|
||||
handler.create(repository);
|
||||
@@ -120,7 +114,6 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
return repository;
|
||||
}
|
||||
|
||||
|
||||
protected File baseDirectory;
|
||||
|
||||
private RepositoryHandler handler;
|
||||
|
||||
@@ -543,7 +543,8 @@ public class RepositoryImportResource
|
||||
|
||||
try
|
||||
{
|
||||
repository = new Repository(null, type, name);
|
||||
// TODO #8783
|
||||
// repository = new Repository(null, type, name);
|
||||
manager.create(repository);
|
||||
}
|
||||
catch (RepositoryAlreadyExistsException ex)
|
||||
@@ -738,7 +739,8 @@ public class RepositoryImportResource
|
||||
{
|
||||
for (String repositoryName : repositoryNames)
|
||||
{
|
||||
Repository repository = manager.get(type, repositoryName);
|
||||
// TODO #8783
|
||||
Repository repository = null; //manager.get(type, repositoryName);
|
||||
|
||||
if (repository != null)
|
||||
{
|
||||
|
||||
@@ -561,42 +561,6 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Repository} with the specified type and name.
|
||||
*
|
||||
* @param type the type of the repository
|
||||
* @param name the name of the repository
|
||||
*
|
||||
* @return the {@link Repository} with the specified type and name
|
||||
*/
|
||||
@GET
|
||||
@Path("{type: [a-z]+}/{name: .*}")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 404, condition = "not found, no repository with the specified type and name available"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(Repository.class)
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public Response getByTypeAndName(@PathParam("type") String type,
|
||||
@PathParam("name") String name)
|
||||
{
|
||||
Response response;
|
||||
Repository repository = repositoryManager.get(type, name);
|
||||
|
||||
if (repository != null)
|
||||
{
|
||||
prepareForReturn(repository);
|
||||
response = Response.ok(repository).build();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Changeset} from the given repository
|
||||
* with the specified revision.
|
||||
|
||||
@@ -42,14 +42,29 @@ import com.google.inject.Singleton;
|
||||
import org.apache.shiro.concurrent.SubjectAwareExecutorService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.*;
|
||||
import sonia.scm.ArgumentIsInvalidException;
|
||||
import sonia.scm.ConfigurationException;
|
||||
import sonia.scm.HandlerEventType;
|
||||
import sonia.scm.SCMContextProvider;
|
||||
import sonia.scm.Type;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.security.KeyGenerator;
|
||||
import sonia.scm.util.*;
|
||||
import sonia.scm.util.AssertUtil;
|
||||
import sonia.scm.util.CollectionAppender;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.IOUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
@@ -105,7 +120,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
executorService.shutdown();
|
||||
|
||||
for (RepositoryHandler handler : handlerMap.values()) {
|
||||
@@ -115,13 +130,12 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
|
||||
public void create(Repository repository, boolean initRepository)
|
||||
throws RepositoryException {
|
||||
logger.info("create repository {} of type {}", repository.getName(),
|
||||
repository.getType());
|
||||
logger.info("create repository {} of type {}", repository.getNamespaceAndName(), repository.getType());
|
||||
|
||||
RepositoryPermissions.create().check();
|
||||
AssertUtil.assertIsValid(repository);
|
||||
|
||||
if (repositoryDAO.contains(repository)) {
|
||||
if (repositoryDAO.contains(repository.getNamespaceAndName())) {
|
||||
throw RepositoryAlreadyExistsException.create(repository);
|
||||
}
|
||||
|
||||
@@ -190,8 +204,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
|
||||
AssertUtil.assertIsValid(repository);
|
||||
|
||||
Repository oldRepository = repositoryDAO.get(repository.getType(),
|
||||
repository.getName());
|
||||
Repository oldRepository = repositoryDAO.get(repository.getNamespaceAndName());
|
||||
|
||||
if (oldRepository != null) {
|
||||
RepositoryPermissions.modify(oldRepository).check();
|
||||
@@ -212,8 +225,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
AssertUtil.assertIsNotNull(repository);
|
||||
RepositoryPermissions.read(repository).check();
|
||||
|
||||
Repository fresh = repositoryDAO.get(repository.getType(),
|
||||
repository.getName());
|
||||
Repository fresh = repositoryDAO.get(repository.getNamespaceAndName());
|
||||
|
||||
if (fresh != null) {
|
||||
fresh.copyProperties(repository);
|
||||
@@ -240,11 +252,12 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository get(String type, String name) {
|
||||
AssertUtil.assertIsNotEmpty(type);
|
||||
AssertUtil.assertIsNotEmpty(name);
|
||||
public Repository get(NamespaceAndName namespaceAndName) {
|
||||
AssertUtil.assertIsNotNull(namespaceAndName);
|
||||
AssertUtil.assertIsNotEmpty(namespaceAndName.getNamespace());
|
||||
AssertUtil.assertIsNotEmpty(namespaceAndName.getName());
|
||||
|
||||
Repository repository = repositoryDAO.get(type, name);
|
||||
Repository repository = repositoryDAO.get(namespaceAndName);
|
||||
|
||||
if (repository != null) {
|
||||
RepositoryPermissions.read(repository).check();
|
||||
@@ -325,7 +338,27 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository getFromTypeAndUri(String type, String uri) {
|
||||
public Repository getFromUri(String uri) {
|
||||
AssertUtil.assertIsNotEmpty(uri);
|
||||
|
||||
if (uri.startsWith(HttpUtil.SEPARATOR_PATH)) {
|
||||
uri = uri.substring(1);
|
||||
}
|
||||
|
||||
int typeSeparator = uri.indexOf(HttpUtil.SEPARATOR_PATH);
|
||||
Repository repository = null;
|
||||
|
||||
if (typeSeparator > 0) {
|
||||
String type = uri.substring(0, typeSeparator);
|
||||
|
||||
uri = uri.substring(typeSeparator + 1);
|
||||
repository = getFromTypeAndUri(type, uri);
|
||||
}
|
||||
|
||||
return repository;
|
||||
}
|
||||
|
||||
private Repository getFromTypeAndUri(String type, String uri) {
|
||||
if (Strings.isNullOrEmpty(type)) {
|
||||
throw new ArgumentIsInvalidException("argument type is required");
|
||||
}
|
||||
@@ -362,27 +395,6 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
||||
return repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository getFromUri(String uri) {
|
||||
AssertUtil.assertIsNotEmpty(uri);
|
||||
|
||||
if (uri.startsWith(HttpUtil.SEPARATOR_PATH)) {
|
||||
uri = uri.substring(1);
|
||||
}
|
||||
|
||||
int typeSeperator = uri.indexOf(HttpUtil.SEPARATOR_PATH);
|
||||
Repository repository = null;
|
||||
|
||||
if (typeSeperator > 0) {
|
||||
String type = uri.substring(0, typeSeperator);
|
||||
|
||||
uri = uri.substring(typeSeperator + 1);
|
||||
repository = getFromTypeAndUri(type, uri);
|
||||
}
|
||||
|
||||
return repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositoryHandler getHandler(String type) {
|
||||
return handlerMap.get(type);
|
||||
|
||||
@@ -32,14 +32,15 @@
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* RepositoryMatcher is able to check if a repository matches the requested path.
|
||||
@@ -83,9 +84,24 @@ public final class RepositoryMatcher {
|
||||
}
|
||||
|
||||
private boolean isPathMatching(Repository repository, String path) {
|
||||
return getPathMatcherForType(repository.getType()).isPathMatching(repository, path);
|
||||
|
||||
String namespace = extractNamespace(path);
|
||||
String remainingPath = path.substring(namespace.length() + 1);
|
||||
|
||||
return getPathMatcherForType(repository.getType()).isPathMatching(repository, remainingPath);
|
||||
}
|
||||
|
||||
|
||||
private String extractNamespace(String path) {
|
||||
if (path.startsWith(HttpUtil.SEPARATOR_PATH)) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
int namespaceSeparator = path.indexOf(HttpUtil.SEPARATOR_PATH);
|
||||
if (namespaceSeparator > 0) {
|
||||
return path.substring(0, namespaceSeparator);
|
||||
}
|
||||
throw new IllegalArgumentException("no namespace in path " + path);
|
||||
}
|
||||
|
||||
private RepositoryPathMatcher getPathMatcherForType(String type) {
|
||||
RepositoryPathMatcher pathMatcher = pathMatchers.get(type);
|
||||
if (pathMatcher == null) {
|
||||
|
||||
@@ -34,7 +34,11 @@ import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provider;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.*;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||
@@ -57,7 +61,12 @@ import sonia.scm.security.DefaultKeyGenerator;
|
||||
import sonia.scm.security.KeyGenerator;
|
||||
import sonia.scm.user.UserTestData;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -174,8 +183,8 @@ private long calculateAverage(List<Long> times) {
|
||||
when(repositoryDAO.getAll()).thenReturn(repositories.values());
|
||||
}
|
||||
|
||||
private Repository createTestRepository(int number){
|
||||
Repository repository = new Repository(keyGenerator.createKey(), REPOSITORY_TYPE, "repo-" + number);
|
||||
private Repository createTestRepository(int number) {
|
||||
Repository repository = new Repository(keyGenerator.createKey(), REPOSITORY_TYPE, "namespace", "repo-" + number);
|
||||
repository.getPermissions().add(new Permission("trillian", PermissionType.READ));
|
||||
return repository;
|
||||
}
|
||||
|
||||
@@ -58,11 +58,26 @@ import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.store.JAXBConfigurationStoreFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.hasProperty;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
@@ -84,12 +99,8 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#create(sonia.scm.repository.Repository)}.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
private String mockedNamespace = "default_namespace";
|
||||
|
||||
@Test
|
||||
public void testCreate() throws RepositoryException, IOException {
|
||||
Repository heartOfGold = createTestRepository();
|
||||
@@ -99,12 +110,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
assertRepositoriesEquals(dbRepo, heartOfGold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#create(sonia.scm.repository.Repository)} without the required permissions.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@SubjectAware(
|
||||
username = "unpriv"
|
||||
)
|
||||
@@ -113,35 +118,17 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
createTestRepository();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#create(sonia.scm.repository.Repository)} with a already existing repository.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test(expected = RepositoryAlreadyExistsException.class)
|
||||
public void testCreateExisting() throws RepositoryException, IOException {
|
||||
createTestRepository();
|
||||
createTestRepository();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)}.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testDelete() throws RepositoryException, IOException {
|
||||
delete(manager, createTestRepository());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} without the required permissions.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@SubjectAware(
|
||||
username = "unpriv"
|
||||
)
|
||||
@@ -150,35 +137,16 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
delete(manager, createTestRepository());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} with a non archived repository and with
|
||||
* enabled archive mode.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test(expected = RepositoryIsNotArchivedException.class)
|
||||
public void testDeleteNonArchived() throws RepositoryException, IOException {
|
||||
delete(createRepositoryManager(true), createTestRepository());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} with a non existing repository.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test(expected = RepositoryNotFoundException.class)
|
||||
public void testDeleteNotFound() throws RepositoryException, IOException {
|
||||
manager.delete(createRepositoryWithId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} with enabled archive mode.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteWithEnabledArchive()
|
||||
throws RepositoryException, IOException {
|
||||
@@ -190,12 +158,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
delete(drm, repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#get(java.lang.String)} .
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testGet() throws RepositoryException, IOException {
|
||||
Repository heartOfGold = createTestRepository();
|
||||
@@ -211,12 +173,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
assertEquals(description, heartOfGold.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#get(java.lang.String)} without required privileges.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
@SubjectAware(
|
||||
username = "crato"
|
||||
@@ -229,12 +185,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
manager.get(heartOfGold.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#getAll()}.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testGetAll() throws RepositoryException, IOException {
|
||||
Repository heartOfGold = createTestRepository();
|
||||
@@ -271,16 +221,10 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
heartOfGold.getDescription().equals(heartReference.getDescription()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#getAll()} with permission for 2 of 3 repositories.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@SubjectAware(username = "dent")
|
||||
public void testGetAllWithPermissions() throws RepositoryException, IOException {
|
||||
public void testGetAllWithPermissionsForTwoOrThreeRepos() throws RepositoryException, IOException {
|
||||
// mock key generator
|
||||
KeyGenerator keyGenerator = mock(KeyGenerator.class);
|
||||
Stack<String> keys = new Stack<>();
|
||||
@@ -320,12 +264,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests repository manager events.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testEvents() throws RepositoryException, IOException {
|
||||
RepositoryManager repoManager = createRepositoryManager(false);
|
||||
@@ -357,12 +295,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
assertSame(HandlerEventType.DELETE, listener.postEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#modify(sonia.scm.repository.Repository)}.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testModify() throws RepositoryException, IOException {
|
||||
Repository heartOfGold = createTestRepository();
|
||||
@@ -376,13 +308,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
assertEquals(hearReference.getDescription(), "prototype ship");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#modify(sonia.scm.repository.Repository)} without
|
||||
* the required permissions.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
@SubjectAware(username = "crato")
|
||||
public void testModifyWithoutRequiredPermissions() throws RepositoryException, IOException {
|
||||
@@ -394,24 +319,11 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
manager.modify(heartOfGold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#modify(sonia.scm.repository.Repository)} with a non
|
||||
* existing repository.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test(expected = RepositoryNotFoundException.class)
|
||||
public void testModifyNotFound() throws RepositoryException, IOException {
|
||||
manager.modify(createRepositoryWithId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#refresh(sonia.scm.repository.Repository)}.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testRefresh() throws RepositoryException, IOException {
|
||||
Repository heartOfGold = createTestRepository();
|
||||
@@ -422,13 +334,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
assertEquals(description, heartOfGold.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#refresh(sonia.scm.repository.Repository)} without
|
||||
* required permissions.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
@SubjectAware(username = "crato")
|
||||
public void testRefreshWithoutRequiredPermissions() throws RepositoryException, IOException {
|
||||
@@ -440,24 +345,11 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
manager.refresh(heartOfGold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link RepositoryManager#refresh(sonia.scm.repository.Repository)} with a non existing
|
||||
* repository.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test(expected = RepositoryNotFoundException.class)
|
||||
public void testRefreshNotFound() throws RepositoryException, IOException {
|
||||
manager.refresh(createRepositoryWithId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests repository hooks.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testRepositoryHook() throws RepositoryException, IOException {
|
||||
CountingReceiveHook hook = new CountingReceiveHook();
|
||||
@@ -488,21 +380,78 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryFromRequestUriTest() throws RepositoryException, IOException {
|
||||
public void getRepositoryFromRequestUri_withoutLeadingSlash() throws RepositoryException, IOException {
|
||||
RepositoryManager m = createManager();
|
||||
m.init(contextProvider);
|
||||
|
||||
createRepository(m, new Repository("1", "hg", "scm"));
|
||||
createRepository(m, new Repository("2", "hg", "scm-test"));
|
||||
createRepository(m, new Repository("3", "git", "project1/test-1"));
|
||||
createRepository(m, new Repository("4", "git", "project1/test-2"));
|
||||
|
||||
assertEquals("scm", m.getFromUri("hg/scm").getName());
|
||||
assertEquals("scm-test", m.getFromUri("hg/scm-test").getName());
|
||||
assertEquals("scm-test", m.getFromUri("/hg/scm-test").getName());
|
||||
assertEquals("project1/test-1", m.getFromUri("/git/project1/test-1").getName());
|
||||
assertEquals("project1/test-1", m.getFromUri("/git/project1/test-1/ka/some/path").getName());
|
||||
assertNull(m.getFromUri("/git/project1/test-3/ka/some/path"));
|
||||
|
||||
createUriTestRepositories(m);
|
||||
|
||||
assertEquals("scm-test", m.getFromUri("hg/namespace/scm-test").getName());
|
||||
assertEquals("namespace", m.getFromUri("hg/namespace/scm-test").getNamespace());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryFromRequestUri_withLeadingSlash() throws RepositoryException, IOException {
|
||||
RepositoryManager m = createManager();
|
||||
m.init(contextProvider);
|
||||
|
||||
createUriTestRepositories(m);
|
||||
|
||||
assertEquals("scm-test", m.getFromUri("/hg/namespace/scm-test").getName());
|
||||
assertEquals("namespace", m.getFromUri("/hg/namespace/scm-test").getNamespace());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryFromRequestUri_withPartialName() throws RepositoryException, IOException {
|
||||
RepositoryManager m = createManager();
|
||||
m.init(contextProvider);
|
||||
|
||||
createUriTestRepositories(m);
|
||||
|
||||
assertEquals("scm", m.getFromUri("hg/namespace/scm").getName());
|
||||
assertEquals("namespace", m.getFromUri("hg/namespace/scm").getNamespace());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryFromRequestUri_withTrailingFilePath() throws RepositoryException, IOException {
|
||||
RepositoryManager m = createManager();
|
||||
m.init(contextProvider);
|
||||
|
||||
createUriTestRepositories(m);
|
||||
|
||||
assertEquals("test-1", m.getFromUri("/git/namespace/test-1/ka/some/path").getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryFromRequestUri_forNotExistingRepositoryName() throws RepositoryException, IOException {
|
||||
RepositoryManager m = createManager();
|
||||
m.init(contextProvider);
|
||||
|
||||
createUriTestRepositories(m);
|
||||
|
||||
assertNull(m.getFromUri("/git/namespace/test-3/ka/some/path"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepositoryFromRequestUri_forWrongNamespace() throws RepositoryException, IOException {
|
||||
RepositoryManager m = createManager();
|
||||
m.init(contextProvider);
|
||||
|
||||
createUriTestRepositories(m);
|
||||
|
||||
assertNull(m.getFromUri("/git/other/other/test-2"));
|
||||
}
|
||||
|
||||
private void createUriTestRepositories(RepositoryManager m) throws RepositoryException, IOException {
|
||||
mockedNamespace = "namespace";
|
||||
createRepository(m, new Repository("1", "hg", "namespace", "scm"));
|
||||
createRepository(m, new Repository("2", "hg", "namespace", "scm-test"));
|
||||
createRepository(m, new Repository("3", "git", "namespace", "test-1"));
|
||||
createRepository(m, new Repository("4", "git", "namespace", "test-2"));
|
||||
|
||||
mockedNamespace = "other";
|
||||
createRepository(m, new Repository("1", "hg", "other", "scm"));
|
||||
createRepository(m, new Repository("2", "hg", "other", "scm-test"));
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -540,7 +489,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
||||
configuration.setEnableRepositoryArchive(archiveEnabled);
|
||||
|
||||
NamespaceStrategy namespaceStrategy = mock(NamespaceStrategy.class);
|
||||
when(namespaceStrategy.getNamespace()).thenReturn("default_namespace");
|
||||
when(namespaceStrategy.getNamespace()).thenAnswer(invocation -> mockedNamespace);
|
||||
|
||||
return new DefaultRepositoryManager(configuration, contextProvider,
|
||||
keyGenerator, repositoryDAO, handlerSet, createRepositoryMatcher(), namespaceStrategy);
|
||||
|
||||
@@ -31,10 +31,13 @@
|
||||
package sonia.scm.repository;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Set;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RepositoryMatcher}.
|
||||
@@ -54,11 +57,11 @@ public class RepositoryMatcherTest {
|
||||
|
||||
@Test
|
||||
public void testMatches() {
|
||||
assertFalse(matcher.matches(repository("hg", "scm"), "hg", "scm-test/ka"));
|
||||
assertFalse(matcher.matches(repository("git", "scm-test"), "hg", "scm-test"));
|
||||
assertFalse(matcher.matches(repository("hg", "scm"), "hg", "namespace/scm-test/ka"));
|
||||
assertFalse(matcher.matches(repository("git", "scm-test"), "hg", "namespace/scm-test"));
|
||||
|
||||
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "scm-test/ka"));
|
||||
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "scm-test"));
|
||||
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "namespace/scm-test/ka"));
|
||||
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "namespace/scm-test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -68,7 +71,7 @@ public class RepositoryMatcherTest {
|
||||
}
|
||||
|
||||
private Repository repository(String type, String name) {
|
||||
return new Repository(type + "-" + name, type, name);
|
||||
return new Repository(type + "-" + name, type, "namespace", name);
|
||||
}
|
||||
|
||||
private static class AbcRepositoryPathMatcher implements RepositoryPathMatcher {
|
||||
|
||||
Reference in New Issue
Block a user