mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
Use clone and push to create branches
Generalize workdir creation for git and hg and create branches in clones instead of the scm repository, so that hooks will be fired correctly once the changes are pushed back. Missing: - Evaluation of the git response from the push command - configuration of the hg environment and the authentication, so that the scmhooks.py script can be triggeret correctly and can callback the scm manager
This commit is contained in:
@@ -53,6 +53,7 @@ import sonia.scm.io.INISection;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.plugin.PluginLoader;
|
||||
import sonia.scm.repository.spi.HgRepositoryServiceProvider;
|
||||
import sonia.scm.repository.spi.HgWorkdirFactory;
|
||||
import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.util.IOUtil;
|
||||
import sonia.scm.util.SystemUtil;
|
||||
@@ -113,10 +114,11 @@ public class HgRepositoryHandler
|
||||
public HgRepositoryHandler(ConfigurationStoreFactory storeFactory,
|
||||
Provider<HgContext> hgContextProvider,
|
||||
RepositoryLocationResolver repositoryLocationResolver,
|
||||
PluginLoader pluginLoader)
|
||||
PluginLoader pluginLoader, HgWorkdirFactory workdirFactory)
|
||||
{
|
||||
super(storeFactory, repositoryLocationResolver, pluginLoader);
|
||||
this.hgContextProvider = hgContextProvider;
|
||||
this.workdirFactory = workdirFactory;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -408,6 +410,10 @@ public class HgRepositoryHandler
|
||||
}
|
||||
}
|
||||
|
||||
public HgWorkdirFactory getWorkdirFactory() {
|
||||
return workdirFactory;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@@ -415,4 +421,6 @@ public class HgRepositoryHandler
|
||||
|
||||
/** Field description */
|
||||
private JAXBContext jaxbContext;
|
||||
|
||||
private final HgWorkdirFactory workdirFactory;
|
||||
}
|
||||
|
||||
@@ -32,10 +32,14 @@ package sonia.scm.repository.spi;
|
||||
|
||||
import com.aragost.javahg.Changeset;
|
||||
import com.aragost.javahg.commands.CommitCommand;
|
||||
import com.aragost.javahg.commands.PushCommand;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.Branch;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.util.WorkingCopy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Mercurial implementation of the {@link BranchCommand}.
|
||||
@@ -45,24 +49,37 @@ public class HgBranchCommand extends AbstractCommand implements BranchCommand {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HgBranchCommand.class);
|
||||
|
||||
HgBranchCommand(HgCommandContext context, Repository repository) {
|
||||
private final HgWorkdirFactory workdirFactory;
|
||||
|
||||
HgBranchCommand(HgCommandContext context, Repository repository, HgWorkdirFactory workdirFactory) {
|
||||
super(context, repository);
|
||||
this.workdirFactory = workdirFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Branch branch(String name) {
|
||||
com.aragost.javahg.Repository repository = open();
|
||||
com.aragost.javahg.commands.BranchCommand.on(repository).set(name);
|
||||
public Branch branch(String name) throws IOException {
|
||||
try (WorkingCopy<RepositoryCloseableWrapper> workingCopy = workdirFactory.createWorkingCopy(getContext())) {
|
||||
com.aragost.javahg.Repository repository = workingCopy.get().get();
|
||||
com.aragost.javahg.commands.BranchCommand.on(repository).set(name);
|
||||
|
||||
Changeset emptyChangeset = CommitCommand
|
||||
.on(repository)
|
||||
.user("SCM-Manager")
|
||||
.message("Create new branch " + name)
|
||||
.execute();
|
||||
Changeset emptyChangeset = CommitCommand
|
||||
.on(repository)
|
||||
.user("SCM-Manager")
|
||||
.message("Create new branch " + name)
|
||||
.execute();
|
||||
|
||||
LOG.debug("Created new branch '{}' in repository {} with changeset {}",
|
||||
name, getRepository().getNamespaceAndName(), emptyChangeset.getNode());
|
||||
PushCommand pushCommand = PushCommand
|
||||
.on(repository)
|
||||
.branch(name)
|
||||
.newBranch();
|
||||
pushCommand
|
||||
.cmdAppend("--config", "");
|
||||
pushCommand .execute();
|
||||
|
||||
return Branch.normalBranch(name, emptyChangeset.getNode());
|
||||
LOG.debug("Created new branch '{}' in repository {} with changeset {}",
|
||||
name, getRepository().getNamespaceAndName(), emptyChangeset.getNode());
|
||||
|
||||
return Branch.normalBranch(name, emptyChangeset.getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider
|
||||
|
||||
@Override
|
||||
public BranchCommand getBranchCommand() {
|
||||
return new HgBranchCommand(context, repository);
|
||||
return new HgBranchCommand(context, repository, handler.getWorkdirFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.util.WorkdirFactory;
|
||||
|
||||
public interface HgWorkdirFactory extends WorkdirFactory<RepositoryCloseableWrapper, HgCommandContext> {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import com.aragost.javahg.Repository;
|
||||
import com.aragost.javahg.commands.CloneCommand;
|
||||
import sonia.scm.repository.util.SimpleWorkdirFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SimpleHgWorkdirFactory extends SimpleWorkdirFactory<RepositoryCloseableWrapper, HgCommandContext> implements HgWorkdirFactory {
|
||||
public SimpleHgWorkdirFactory() {
|
||||
super(null, new HgCloneProvider());
|
||||
}
|
||||
|
||||
public SimpleHgWorkdirFactory(File poolDirectory) {
|
||||
super(poolDirectory, null, new HgCloneProvider());
|
||||
}
|
||||
|
||||
private static class HgCloneProvider implements CloneProvider<RepositoryCloseableWrapper, HgCommandContext> {
|
||||
|
||||
@Override
|
||||
public RepositoryCloseableWrapper cloneRepository(HgCommandContext context, File target) throws IOException {
|
||||
String execute = CloneCommand.on(context.open()).execute(target.getAbsolutePath());
|
||||
return new RepositoryCloseableWrapper(Repository.open(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RepositoryCloseableWrapper implements AutoCloseable {
|
||||
private final Repository delegate;
|
||||
|
||||
RepositoryCloseableWrapper(Repository delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
Repository get() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,8 @@ import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.repository.HgContext;
|
||||
import sonia.scm.repository.HgContextProvider;
|
||||
import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.spi.HgWorkdirFactory;
|
||||
import sonia.scm.repository.spi.SimpleHgWorkdirFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -81,5 +83,7 @@ public class HgServletModule extends ServletModule
|
||||
|
||||
// bind servlets
|
||||
serve(MAPPING_HOOK).with(HgHookCallbackServlet.class);
|
||||
|
||||
bind(HgWorkdirFactory.class).to(SimpleHgWorkdirFactory.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
|
||||
@Override
|
||||
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory, RepositoryLocationResolver locationResolver, File directory) {
|
||||
HgRepositoryHandler handler = new HgRepositoryHandler(factory, new HgContextProvider(), locationResolver, null);
|
||||
HgRepositoryHandler handler = new HgRepositoryHandler(factory, new HgContextProvider(), locationResolver, null, null);
|
||||
|
||||
handler.init(contextProvider);
|
||||
HgTestUtil.checkForSkip(handler);
|
||||
@@ -87,7 +87,7 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
|
||||
@Test
|
||||
public void getDirectory() {
|
||||
HgRepositoryHandler repositoryHandler = new HgRepositoryHandler(factory, provider, locationResolver, null);
|
||||
HgRepositoryHandler repositoryHandler = new HgRepositoryHandler(factory, provider, locationResolver, null, null);
|
||||
|
||||
HgConfig hgConfig = new HgConfig();
|
||||
hgConfig.setHgBinary("hg");
|
||||
|
||||
@@ -105,7 +105,7 @@ public final class HgTestUtil
|
||||
|
||||
RepositoryLocationResolver repositoryLocationResolver = new RepositoryLocationResolver(context, repoDao, new InitialRepositoryLocationResolver());
|
||||
HgRepositoryHandler handler =
|
||||
new HgRepositoryHandler(new InMemoryConfigurationStoreFactory(), new HgContextProvider(), repositoryLocationResolver, null);
|
||||
new HgRepositoryHandler(new InMemoryConfigurationStoreFactory(), new HgContextProvider(), repositoryLocationResolver, null, null);
|
||||
Path repoDir = directory.toPath();
|
||||
when(repoDao.getPath(any())).thenReturn(repoDir);
|
||||
handler.init(context);
|
||||
|
||||
@@ -4,14 +4,15 @@ import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.Branch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class HgBranchCommandTest extends AbstractHgCommandTestBase {
|
||||
@Test
|
||||
public void x() {
|
||||
public void x() throws IOException {
|
||||
Assertions.assertThat(readBranches()).filteredOn(b -> b.getName().equals("new_branch")).isEmpty();
|
||||
|
||||
new HgBranchCommand(cmdContext, repository).branch("new_branch");
|
||||
new HgBranchCommand(cmdContext, repository, new SimpleHgWorkdirFactory()).branch("new_branch");
|
||||
|
||||
Assertions.assertThat(readBranches()).filteredOn(b -> b.getName().equals("new_branch")).isNotEmpty();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user