implement svnModifyCommand

This commit is contained in:
Eduard Heimbuch
2019-10-23 14:42:19 +02:00
parent 5c47a266cb
commit 1d7d854ea8
6 changed files with 194 additions and 5 deletions

View File

@@ -58,6 +58,6 @@ public class SimpleSvnWorkDirFactory extends SimpleWorkdirFactory<File, File, Sv
svnOperationFactory.dispose();
}
return new ParentAndClone<>(workingCopy, workingCopy);
return new ParentAndClone<>(context.getDirectory(), workingCopy);
}
}

View File

@@ -0,0 +1,84 @@
package sonia.scm.repository.spi;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNWCClient;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Repository;
import sonia.scm.repository.SvnWorkDirFactory;
import sonia.scm.repository.util.WorkingCopy;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
public class SvnModifyCommand implements ModifyCommand {
private SvnContext context;
private SvnWorkDirFactory workDirFactory;
private Repository repository;
public SvnModifyCommand(SvnContext context, Repository repository, SvnWorkDirFactory workDirFactory) {
this.context = context;
this.repository = repository;
this.workDirFactory = workDirFactory;
}
@Override
public String execute(ModifyCommandRequest request) {
SVNClientManager clientManager = SVNClientManager.newInstance();
try (WorkingCopy<File, File> workingCopy = workDirFactory.createWorkingCopy(context, null)) {
File workingRepository = workingCopy.getWorkingRepository();
for (ModifyCommandRequest.PartialRequest partialRequest : request.getRequests()) {
try {
SVNWCClient wcClient = clientManager.getWCClient();
partialRequest.execute(new ModifyWorkerHelper() {
@Override
public void doScmDelete(String toBeDeleted){
try {
wcClient.doDelete(new File(String.format("%s/%s", workingRepository, toBeDeleted)), true, true, false);
} catch (SVNException e) {
throw new InternalRepositoryException(repository, "could not delete file from repository");
}
}
@Override
public void addFileToScm(String name, Path file) {
try {
wcClient.doAdd(file.toFile(), true, false, true, SVNDepth.INFINITY, false, true);
} catch (SVNException e) {
throw new InternalRepositoryException(repository, "could not add file to repository");
}
}
@Override
public File getWorkDir() {
return workingRepository;
}
@Override
public Repository getRepository() {
return repository;
}
@Override
public String getBranch() {
return null;
}
});
} catch (IOException e) {
throw new InternalRepositoryException(repository, "could not read files from repository");
}
}
try {
clientManager.getCommitClient().doCommit(new File[] {workingRepository}, false,
request.getCommitMessage(), null, null, false, true, SVNDepth.INFINITY);
//I can't get the newest revision after commiting without creating a new working copy
return String.valueOf(clientManager.getStatusClient().doStatus(workingRepository, false).getCommittedRevision().getNumber() + 1);
} catch (SVNException e) {
throw new InternalRepositoryException(repository, "could not commit changes on repository");
}
}
}
}

View File

@@ -37,8 +37,10 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.io.Closeables;
import sonia.scm.repository.Repository;
import sonia.scm.repository.SvnRepositoryHandler;
import sonia.scm.repository.SvnWorkDirFactory;
import sonia.scm.repository.api.Command;
import javax.inject.Inject;
import java.io.IOException;
import java.util.Set;
@@ -53,17 +55,19 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider
//J-
public static final Set<Command> COMMANDS = ImmutableSet.of(
Command.BLAME, Command.BROWSE, Command.CAT, Command.DIFF,
Command.LOG, Command.BUNDLE, Command.UNBUNDLE
Command.LOG, Command.BUNDLE, Command.UNBUNDLE, Command.MODIFY
);
//J+
//~--- constructors ---------------------------------------------------------
@Inject
SvnRepositoryServiceProvider(SvnRepositoryHandler handler,
Repository repository)
Repository repository, SvnWorkDirFactory workdirFactory)
{
this.repository = repository;
this.context = new SvnContext(handler.getDirectory(repository.getId()));
this.workDirFactory = workdirFactory;
}
//~--- methods --------------------------------------------------------------
@@ -158,6 +162,10 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider
return new SvnModificationsCommand(context, repository);
}
public ModifyCommand getModifyCommand() {
return new SvnModifyCommand(context, repository, workDirFactory);
}
/**
* Method description
*
@@ -189,4 +197,6 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider
/** Field description */
private final Repository repository;
private final SvnWorkDirFactory workDirFactory;
}

View File

@@ -36,15 +36,18 @@ import com.google.inject.Inject;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.Repository;
import sonia.scm.repository.SvnRepositoryHandler;
import sonia.scm.repository.SvnWorkDirFactory;
@Extension
public class SvnRepositoryServiceResolver implements RepositoryServiceResolver {
private SvnRepositoryHandler handler;
private SvnWorkDirFactory workdirFactory;
@Inject
public SvnRepositoryServiceResolver(SvnRepositoryHandler handler) {
public SvnRepositoryServiceResolver(SvnRepositoryHandler handler, SvnWorkDirFactory workdirFactory) {
this.handler = handler;
this.workdirFactory = workdirFactory;
}
@Override
@@ -52,7 +55,7 @@ public class SvnRepositoryServiceResolver implements RepositoryServiceResolver {
SvnRepositoryServiceProvider provider = null;
if (SvnRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType())) {
provider = new SvnRepositoryServiceProvider(handler, repository);
provider = new SvnRepositoryServiceProvider(handler, repository, workdirFactory);
}
return provider;

View File

@@ -38,6 +38,8 @@ import org.mapstruct.factory.Mappers;
import sonia.scm.api.v2.resources.SvnConfigDtoToSvnConfigMapper;
import sonia.scm.api.v2.resources.SvnConfigToSvnConfigDtoMapper;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.SvnWorkDirFactory;
import sonia.scm.repository.spi.SimpleSvnWorkDirFactory;
/**
*
@@ -50,5 +52,6 @@ public class SvnServletModule extends ServletModule {
protected void configureServlets() {
bind(SvnConfigDtoToSvnConfigMapper.class).to(Mappers.getMapper(SvnConfigDtoToSvnConfigMapper.class).getClass());
bind(SvnConfigToSvnConfigDtoMapper.class).to(Mappers.getMapper(SvnConfigToSvnConfigDtoMapper.class).getClass());
bind(SvnWorkDirFactory.class).to(SimpleSvnWorkDirFactory.class);
}
}

View File

@@ -0,0 +1,89 @@
package sonia.scm.repository.spi;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import sonia.scm.AlreadyExistsException;
import sonia.scm.repository.Person;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.repository.util.WorkingCopy;
import java.io.File;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class SvnModifyCommandTest extends AbstractSvnCommandTestBase {
private SvnModifyCommand svnModifyCommand;
private SvnContext context;
private SimpleSvnWorkDirFactory workDirFactory;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Before
public void initSvnModifyCommand() {
context = createContext();
workDirFactory = new SimpleSvnWorkDirFactory(new WorkdirProvider(context.getDirectory()));
svnModifyCommand = new SvnModifyCommand(context, createRepository(), workDirFactory);
}
@Test
public void shouldRemoveFiles() {
ModifyCommandRequest request = new ModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.DeleteFileRequest("a.txt"));
request.setCommitMessage("this is great");
request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com"));
svnModifyCommand.execute(request);
WorkingCopy<File, File> workingCopy = workDirFactory.createWorkingCopy(context, null);
assertThat(new File(workingCopy.getWorkingRepository().getAbsolutePath() + "/a.txt")).doesNotExist();
assertThat(new File(workingCopy.getWorkingRepository().getAbsolutePath() + "/c")).exists();
}
@Test
public void shouldAddNewFile() throws IOException {
File testfile = temporaryFolder.newFile("Test123");
ModifyCommandRequest request = new ModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("Test123", testfile, false));
request.setCommitMessage("this is great");
request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com"));
svnModifyCommand.execute(request);
WorkingCopy<File, File> workingCopy = workDirFactory.createWorkingCopy(context, null);
assertThat(new File(workingCopy.getWorkingRepository(), "Test123")).exists();
}
@Test
public void shouldThrowFileAlreadyExistsException() throws IOException {
File testfile = temporaryFolder.newFile("a.txt");
ModifyCommandRequest request = new ModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt", testfile, false));
request.setCommitMessage("this is great");
request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com"));
assertThrows(AlreadyExistsException.class, () -> svnModifyCommand.execute(request));
}
@Test
public void shouldUpdateExistingFile() throws IOException {
File testfile = temporaryFolder.newFile("a.txt");
ModifyCommandRequest request = new ModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt", testfile, true));
request.setCommitMessage("this is great");
request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com"));
svnModifyCommand.execute(request);
WorkingCopy<File, File> workingCopy = workDirFactory.createWorkingCopy(context, null);
assertThat(new File(workingCopy.getWorkingRepository(), "a.txt")).exists();
assertThat(new File(workingCopy.getWorkingRepository(), "a.txt")).hasContent("");
}
}