mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
Differentiate types for central and cloned repository
This commit is contained in:
@@ -8,7 +8,7 @@ import sonia.scm.repository.Repository;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C> {
|
||||
public abstract class SimpleWorkdirFactory<R, W, C> implements WorkdirFactory<R, W, C> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SimpleWorkdirFactory.class);
|
||||
|
||||
@@ -19,11 +19,11 @@ public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C>
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkingCopy<R> createWorkingCopy(C context, String initialBranch) {
|
||||
public WorkingCopy<R, W> createWorkingCopy(C context, String initialBranch) {
|
||||
try {
|
||||
File directory = workdirProvider.createNewWorkdir();
|
||||
ParentAndClone<R> parentAndClone = cloneRepository(context, directory, initialBranch);
|
||||
return new WorkingCopy<>(parentAndClone.getClone(), parentAndClone.getParent(), this::close, directory);
|
||||
ParentAndClone<R, W> parentAndClone = cloneRepository(context, directory, initialBranch);
|
||||
return new WorkingCopy<>(parentAndClone.getClone(), parentAndClone.getParent(), this::closeWorkdir, this::closeCentral, directory);
|
||||
} catch (IOException e) {
|
||||
throw new InternalRepositoryException(getScmRepository(context), "could not clone repository in temporary directory", e);
|
||||
}
|
||||
@@ -34,10 +34,11 @@ public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C>
|
||||
@SuppressWarnings("squid:S00112")
|
||||
// We do allow implementations to throw arbitrary exceptions here, so that we can handle them in close
|
||||
protected abstract void closeRepository(R repository) throws Exception;
|
||||
protected abstract void closeWorkdirInternal(W workdir) throws Exception;
|
||||
|
||||
protected abstract ParentAndClone<R> cloneRepository(C context, File target, String initialBranch) throws IOException;
|
||||
protected abstract ParentAndClone<R, W> cloneRepository(C context, File target, String initialBranch) throws IOException;
|
||||
|
||||
private void close(R repository) {
|
||||
private void closeCentral(R repository) {
|
||||
try {
|
||||
closeRepository(repository);
|
||||
} catch (Exception e) {
|
||||
@@ -45,11 +46,19 @@ public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C>
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ParentAndClone<R> {
|
||||
private final R parent;
|
||||
private final R clone;
|
||||
private void closeWorkdir(W repository) {
|
||||
try {
|
||||
closeWorkdirInternal(repository);
|
||||
} catch (Exception e) {
|
||||
logger.warn("could not close temporary repository clone", e);
|
||||
}
|
||||
}
|
||||
|
||||
public ParentAndClone(R parent, R clone) {
|
||||
protected static class ParentAndClone<R, W> {
|
||||
private final R parent;
|
||||
private final W clone;
|
||||
|
||||
public ParentAndClone(R parent, W clone) {
|
||||
this.parent = parent;
|
||||
this.clone = clone;
|
||||
}
|
||||
@@ -58,7 +67,7 @@ public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C>
|
||||
return parent;
|
||||
}
|
||||
|
||||
public R getClone() {
|
||||
public W getClone() {
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package sonia.scm.repository.util;
|
||||
|
||||
public interface WorkdirFactory<R, C> {
|
||||
WorkingCopy<R> createWorkingCopy(C context, String initialBranch);
|
||||
public interface WorkdirFactory<R, W, C> {
|
||||
WorkingCopy<R, W> createWorkingCopy(C context, String initialBranch);
|
||||
}
|
||||
|
||||
@@ -8,23 +8,25 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class WorkingCopy<R> implements AutoCloseable {
|
||||
public class WorkingCopy<R, W> implements AutoCloseable {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WorkingCopy.class);
|
||||
|
||||
private final File directory;
|
||||
private final R workingRepository;
|
||||
private final W workingRepository;
|
||||
private final R centralRepository;
|
||||
private final Consumer<R> cleanup;
|
||||
private final Consumer<W> cleanupWorkdir;
|
||||
private final Consumer<R> cleanupCentral;
|
||||
|
||||
public WorkingCopy(R workingRepository, R centralRepository, Consumer<R> cleanup, File directory) {
|
||||
public WorkingCopy(W workingRepository, R centralRepository, Consumer<W> cleanupWorkdir, Consumer<R> cleanupCentral, File directory) {
|
||||
this.directory = directory;
|
||||
this.workingRepository = workingRepository;
|
||||
this.centralRepository = centralRepository;
|
||||
this.cleanup = cleanup;
|
||||
this.cleanupCentral = cleanupCentral;
|
||||
this.cleanupWorkdir = cleanupWorkdir;
|
||||
}
|
||||
|
||||
public R getWorkingRepository() {
|
||||
public W getWorkingRepository() {
|
||||
return workingRepository;
|
||||
}
|
||||
|
||||
@@ -39,8 +41,8 @@ public class WorkingCopy<R> implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
cleanup.accept(workingRepository);
|
||||
cleanup.accept(centralRepository);
|
||||
cleanupWorkdir.accept(workingRepository);
|
||||
cleanupCentral.accept(centralRepository);
|
||||
IOUtil.delete(directory);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("could not delete temporary workdir '{}'", directory, e);
|
||||
|
||||
@@ -24,14 +24,14 @@ public class SimpleWorkdirFactoryTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
private SimpleWorkdirFactory<Closeable, Context> simpleWorkdirFactory;
|
||||
private SimpleWorkdirFactory<Closeable, Closeable, Context> simpleWorkdirFactory;
|
||||
|
||||
private String initialBranchForLastCloneCall;
|
||||
|
||||
@Before
|
||||
public void initFactory() throws IOException {
|
||||
WorkdirProvider workdirProvider = new WorkdirProvider(temporaryFolder.newFolder());
|
||||
simpleWorkdirFactory = new SimpleWorkdirFactory<Closeable, Context>(workdirProvider) {
|
||||
simpleWorkdirFactory = new SimpleWorkdirFactory<Closeable, Closeable, Context>(workdirProvider) {
|
||||
@Override
|
||||
protected Repository getScmRepository(Context context) {
|
||||
return REPOSITORY;
|
||||
@@ -43,7 +43,12 @@ public class SimpleWorkdirFactoryTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParentAndClone<Closeable> cloneRepository(Context context, File target, String initialBranch) {
|
||||
protected void closeWorkdirInternal(Closeable workdir) throws Exception {
|
||||
workdir.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParentAndClone<Closeable, Closeable> cloneRepository(Context context, File target, String initialBranch) {
|
||||
initialBranchForLastCloneCall = initialBranch;
|
||||
return new ParentAndClone<>(parent, clone);
|
||||
}
|
||||
@@ -53,7 +58,7 @@ public class SimpleWorkdirFactoryTest {
|
||||
@Test
|
||||
public void shouldCreateParentAndClone() {
|
||||
Context context = new Context();
|
||||
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, null)) {
|
||||
try (WorkingCopy<Closeable, Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, null)) {
|
||||
assertThat(workingCopy.getCentralRepository()).isSameAs(parent);
|
||||
assertThat(workingCopy.getWorkingRepository()).isSameAs(clone);
|
||||
}
|
||||
@@ -62,7 +67,7 @@ public class SimpleWorkdirFactoryTest {
|
||||
@Test
|
||||
public void shouldCloseParent() throws IOException {
|
||||
Context context = new Context();
|
||||
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, null)) {}
|
||||
try (WorkingCopy<Closeable, Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, null)) {}
|
||||
|
||||
verify(parent).close();
|
||||
}
|
||||
@@ -70,7 +75,7 @@ public class SimpleWorkdirFactoryTest {
|
||||
@Test
|
||||
public void shouldCloseClone() throws IOException {
|
||||
Context context = new Context();
|
||||
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, null)) {}
|
||||
try (WorkingCopy<Closeable, Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, null)) {}
|
||||
|
||||
verify(clone).close();
|
||||
}
|
||||
@@ -78,7 +83,7 @@ public class SimpleWorkdirFactoryTest {
|
||||
@Test
|
||||
public void shouldPropagateInitialBranch() {
|
||||
Context context = new Context();
|
||||
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, "some")) {
|
||||
try (WorkingCopy<Closeable, Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context, "some")) {
|
||||
assertThat(initialBranchForLastCloneCall).isEqualTo("some");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ import org.eclipse.jgit.lib.Repository;
|
||||
import sonia.scm.repository.spi.GitContext;
|
||||
import sonia.scm.repository.util.WorkdirFactory;
|
||||
|
||||
public interface GitWorkdirFactory extends WorkdirFactory<Repository, GitContext> {
|
||||
public interface GitWorkdirFactory extends WorkdirFactory<Repository, Repository, GitContext> {
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ class AbstractGitCommand
|
||||
}
|
||||
|
||||
<R, W extends GitCloneWorker<R>> R inClone(Function<Git, W> workerSupplier, GitWorkdirFactory workdirFactory, String initialBranch) {
|
||||
try (WorkingCopy<Repository> workingCopy = workdirFactory.createWorkingCopy(context, initialBranch)) {
|
||||
try (WorkingCopy<Repository, Repository> workingCopy = workdirFactory.createWorkingCopy(context, initialBranch)) {
|
||||
Repository repository = workingCopy.getWorkingRepository();
|
||||
logger.debug("cloned repository to folder {}", repository.getWorkTree());
|
||||
return workerSupplier.apply(new Git(repository)).run();
|
||||
|
||||
@@ -58,7 +58,7 @@ public class GitBranchCommand extends AbstractGitCommand implements BranchComman
|
||||
|
||||
@Override
|
||||
public Branch branch(BranchRequest request) {
|
||||
try (WorkingCopy<org.eclipse.jgit.lib.Repository> workingCopy = workdirFactory.createWorkingCopy(context, request.getParentBranch())) {
|
||||
try (WorkingCopy<org.eclipse.jgit.lib.Repository, org.eclipse.jgit.lib.Repository> workingCopy = workdirFactory.createWorkingCopy(context, request.getParentBranch())) {
|
||||
Git clone = new Git(workingCopy.getWorkingRepository());
|
||||
Ref ref = clone.branchCreate().setName(request.getNewBranch()).call();
|
||||
Iterable<PushResult> call = clone.push().add(request.getNewBranch()).call();
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.io.IOException;
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, GitContext> implements GitWorkdirFactory {
|
||||
public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, Repository, GitContext> implements GitWorkdirFactory {
|
||||
|
||||
@Inject
|
||||
public SimpleGitWorkdirFactory(WorkdirProvider workdirProvider) {
|
||||
@@ -26,7 +26,7 @@ public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, Gi
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParentAndClone<Repository> cloneRepository(GitContext context, File target, String initialBranch) {
|
||||
public ParentAndClone<Repository, Repository> cloneRepository(GitContext context, File target, String initialBranch) {
|
||||
try {
|
||||
Repository clone = Git.cloneRepository()
|
||||
.setURI(createScmTransportProtocolUri(context.getDirectory()))
|
||||
@@ -60,6 +60,13 @@ public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, Gi
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeWorkdirInternal(Repository workdir) throws Exception {
|
||||
if (workdir != null) {
|
||||
workdir.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected sonia.scm.repository.Repository getScmRepository(GitContext context) {
|
||||
return context.getRepository();
|
||||
|
||||
@@ -45,7 +45,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
|
||||
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
|
||||
File masterRepo = createRepositoryDirectory();
|
||||
|
||||
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
|
||||
assertThat(workingCopy.getDirectory())
|
||||
.exists()
|
||||
@@ -62,7 +62,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
|
||||
public void shouldCheckoutInitialBranch() {
|
||||
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
|
||||
|
||||
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext(), "test-branch")) {
|
||||
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), "test-branch")) {
|
||||
assertThat(new File(workingCopy.getWorkingRepository().getWorkTree(), "a.txt"))
|
||||
.exists()
|
||||
.isFile()
|
||||
@@ -75,10 +75,10 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
|
||||
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
|
||||
|
||||
File firstDirectory;
|
||||
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
firstDirectory = workingCopy.getDirectory();
|
||||
}
|
||||
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
File secondDirectory = workingCopy.getDirectory();
|
||||
assertThat(secondDirectory).isNotEqualTo(firstDirectory);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
|
||||
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
|
||||
|
||||
File directory;
|
||||
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
try (WorkingCopy<Repository, Repository> workingCopy = factory.createWorkingCopy(createContext(), null)) {
|
||||
directory = workingCopy.getWorkingRepository().getWorkTree();
|
||||
}
|
||||
assertThat(directory).doesNotExist();
|
||||
|
||||
@@ -59,7 +59,7 @@ public class HgBranchCommand extends AbstractCommand implements BranchCommand {
|
||||
|
||||
@Override
|
||||
public Branch branch(BranchRequest request) {
|
||||
try (WorkingCopy<com.aragost.javahg.Repository> workingCopy = workdirFactory.createWorkingCopy(getContext(), request.getParentBranch())) {
|
||||
try (WorkingCopy<com.aragost.javahg.Repository, com.aragost.javahg.Repository> workingCopy = workdirFactory.createWorkingCopy(getContext(), request.getParentBranch())) {
|
||||
com.aragost.javahg.Repository repository = workingCopy.getWorkingRepository();
|
||||
|
||||
Changeset emptyChangeset = createNewBranchWithEmptyCommit(request, repository);
|
||||
@@ -83,7 +83,7 @@ public class HgBranchCommand extends AbstractCommand implements BranchCommand {
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void pullNewBranchIntoCentralRepository(BranchRequest request, WorkingCopy<com.aragost.javahg.Repository> workingCopy) {
|
||||
private void pullNewBranchIntoCentralRepository(BranchRequest request, WorkingCopy<com.aragost.javahg.Repository, com.aragost.javahg.Repository> workingCopy) {
|
||||
try {
|
||||
PullCommand pullCommand = PullCommand.on(workingCopy.getCentralRepository());
|
||||
workdirFactory.configure(pullCommand);
|
||||
|
||||
@@ -29,7 +29,7 @@ public class HgModifyCommand implements ModifyCommand {
|
||||
@Override
|
||||
public String execute(ModifyCommandRequest request) {
|
||||
|
||||
try (WorkingCopy<com.aragost.javahg.Repository> workingCopy = workdirFactory.createWorkingCopy(context, request.getBranch())) {
|
||||
try (WorkingCopy<com.aragost.javahg.Repository, com.aragost.javahg.Repository> workingCopy = workdirFactory.createWorkingCopy(context, request.getBranch())) {
|
||||
Repository workingRepository = workingCopy.getWorkingRepository();
|
||||
request.getRequests().forEach(
|
||||
partialRequest -> {
|
||||
@@ -85,7 +85,7 @@ public class HgModifyCommand implements ModifyCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private List<Changeset> pullModifyChangesToCentralRepository(ModifyCommandRequest request, WorkingCopy<com.aragost.javahg.Repository> workingCopy) {
|
||||
private List<Changeset> pullModifyChangesToCentralRepository(ModifyCommandRequest request, WorkingCopy<com.aragost.javahg.Repository, com.aragost.javahg.Repository> workingCopy) {
|
||||
try {
|
||||
com.aragost.javahg.commands.PullCommand pullCommand = PullCommand.on(workingCopy.getCentralRepository());
|
||||
workdirFactory.configure(pullCommand);
|
||||
|
||||
@@ -4,6 +4,6 @@ import com.aragost.javahg.Repository;
|
||||
import com.aragost.javahg.commands.PullCommand;
|
||||
import sonia.scm.repository.util.WorkdirFactory;
|
||||
|
||||
public interface HgWorkdirFactory extends WorkdirFactory<Repository, HgCommandContext> {
|
||||
public interface HgWorkdirFactory extends WorkdirFactory<Repository, Repository, HgCommandContext> {
|
||||
void configure(PullCommand pullCommand);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class SimpleHgWorkdirFactory extends SimpleWorkdirFactory<Repository, HgCommandContext> implements HgWorkdirFactory {
|
||||
public class SimpleHgWorkdirFactory extends SimpleWorkdirFactory<Repository, Repository, HgCommandContext> implements HgWorkdirFactory {
|
||||
|
||||
private final Provider<HgRepositoryEnvironmentBuilder> hgRepositoryEnvironmentBuilder;
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SimpleHgWorkdirFactory extends SimpleWorkdirFactory<Repository, HgC
|
||||
this.hgRepositoryEnvironmentBuilder = hgRepositoryEnvironmentBuilder;
|
||||
}
|
||||
@Override
|
||||
public ParentAndClone<Repository> cloneRepository(HgCommandContext context, File target, String initialBranch) throws IOException {
|
||||
public ParentAndClone<Repository, Repository> cloneRepository(HgCommandContext context, File target, String initialBranch) throws IOException {
|
||||
BiConsumer<sonia.scm.repository.Repository, Map<String, String>> repositoryMapBiConsumer =
|
||||
(repository, environment) -> hgRepositoryEnvironmentBuilder.get().buildFor(repository, null, environment);
|
||||
Repository centralRepository = context.openWithSpecialEnvironment(repositoryMapBiConsumer);
|
||||
@@ -46,6 +46,11 @@ public class SimpleHgWorkdirFactory extends SimpleWorkdirFactory<Repository, HgC
|
||||
repository.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeWorkdirInternal(Repository workdir) throws Exception {
|
||||
workdir.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected sonia.scm.repository.Repository getScmRepository(HgCommandContext context) {
|
||||
return context.getScmRepository();
|
||||
|
||||
Reference in New Issue
Block a user