mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-07-05 19:29:14 +02:00
implement modification api in git, svn and hg. implement the endpoint
This commit is contained in:
@@ -37,32 +37,25 @@ package sonia.scm.repository;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import org.eclipse.jgit.diff.DiffEntry;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevTree;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -224,13 +217,6 @@ public class GitChangesetConverter implements Closeable
|
||||
changeset.setParents(parentList);
|
||||
}
|
||||
|
||||
Modifications modifications = createModifications(treeWalk, commit);
|
||||
|
||||
if (modifications != null)
|
||||
{
|
||||
changeset.setModifications(modifications);
|
||||
}
|
||||
|
||||
Collection<String> tagCollection = tags.get(commit.getId());
|
||||
|
||||
if (Util.isNotEmpty(tagCollection))
|
||||
@@ -245,108 +231,7 @@ public class GitChangesetConverter implements Closeable
|
||||
return changeset;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: copy and rename
|
||||
*
|
||||
*
|
||||
* @param modifications
|
||||
* @param entry
|
||||
*/
|
||||
private void appendModification(Modifications modifications, DiffEntry entry)
|
||||
{
|
||||
switch (entry.getChangeType())
|
||||
{
|
||||
case ADD :
|
||||
modifications.getAdded().add(entry.getNewPath());
|
||||
|
||||
break;
|
||||
|
||||
case MODIFY :
|
||||
modifications.getModified().add(entry.getNewPath());
|
||||
|
||||
break;
|
||||
|
||||
case DELETE :
|
||||
modifications.getRemoved().add(entry.getOldPath());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param treeWalk
|
||||
* @param commit
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private Modifications createModifications(TreeWalk treeWalk, RevCommit commit)
|
||||
throws IOException
|
||||
{
|
||||
Modifications modifications = null;
|
||||
|
||||
treeWalk.reset();
|
||||
treeWalk.setRecursive(true);
|
||||
|
||||
if (commit.getParentCount() > 0)
|
||||
{
|
||||
RevCommit parent = commit.getParent(0);
|
||||
RevTree tree = parent.getTree();
|
||||
|
||||
if ((tree == null) && (revWalk != null))
|
||||
{
|
||||
revWalk.parseHeaders(parent);
|
||||
tree = parent.getTree();
|
||||
}
|
||||
|
||||
if (tree != null)
|
||||
{
|
||||
treeWalk.addTree(tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("no parent tree at position 0 for commit {}",
|
||||
commit.getName());
|
||||
}
|
||||
|
||||
treeWalk.addTree(new EmptyTreeIterator());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("no parent available for commit {}", commit.getName());
|
||||
}
|
||||
|
||||
treeWalk.addTree(new EmptyTreeIterator());
|
||||
}
|
||||
|
||||
treeWalk.addTree(commit.getTree());
|
||||
|
||||
List<DiffEntry> entries = DiffEntry.scan(treeWalk);
|
||||
|
||||
for (DiffEntry e : entries)
|
||||
{
|
||||
if (!e.getOldId().equals(e.getNewId()))
|
||||
{
|
||||
if (modifications == null)
|
||||
{
|
||||
modifications = new Modifications();
|
||||
}
|
||||
|
||||
appendModification(modifications, e);
|
||||
}
|
||||
}
|
||||
|
||||
return modifications;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.jgit.diff.DiffEntry;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevTree;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class GitModificationsCommand extends AbstractGitCommand implements ModificationsCommand {
|
||||
|
||||
protected GitModificationsCommand(GitContext context, Repository repository) {
|
||||
super(context, repository);
|
||||
}
|
||||
|
||||
private Modifications createModifications(TreeWalk treeWalk, RevCommit commit, RevWalk revWalk, String revision)
|
||||
throws IOException, UnsupportedModificationTypeException {
|
||||
treeWalk.reset();
|
||||
treeWalk.setRecursive(true);
|
||||
if (commit.getParentCount() > 0) {
|
||||
RevCommit parent = commit.getParent(0);
|
||||
RevTree tree = parent.getTree();
|
||||
if ((tree == null) && (revWalk != null)) {
|
||||
revWalk.parseHeaders(parent);
|
||||
tree = parent.getTree();
|
||||
}
|
||||
if (tree != null) {
|
||||
treeWalk.addTree(tree);
|
||||
} else {
|
||||
log.trace("no parent tree at position 0 for commit {}", commit.getName());
|
||||
treeWalk.addTree(new EmptyTreeIterator());
|
||||
}
|
||||
} else {
|
||||
log.trace("no parent available for commit {}", commit.getName());
|
||||
treeWalk.addTree(new EmptyTreeIterator());
|
||||
}
|
||||
treeWalk.addTree(commit.getTree());
|
||||
List<DiffEntry> entries = DiffEntry.scan(treeWalk);
|
||||
Modifications modifications = new Modifications();
|
||||
for (DiffEntry e : entries) {
|
||||
if (!e.getOldId().equals(e.getNewId())) {
|
||||
appendModification(modifications, e);
|
||||
}
|
||||
}
|
||||
modifications.setRevision(revision);
|
||||
return modifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifications getModifications(String revision) {
|
||||
org.eclipse.jgit.lib.Repository gitRepository = null;
|
||||
RevWalk revWalk = null;
|
||||
try {
|
||||
gitRepository = open();
|
||||
if (!gitRepository.getAllRefs().isEmpty()) {
|
||||
revWalk = new RevWalk(gitRepository);
|
||||
ObjectId id = GitUtil.getRevisionId(gitRepository, revision);
|
||||
RevCommit commit = revWalk.parseCommit(id);
|
||||
TreeWalk treeWalk = new TreeWalk(gitRepository);
|
||||
return createModifications(treeWalk, commit, revWalk, revision);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
log.error("could not open repository", ex);
|
||||
throw new InternalRepositoryException(ex);
|
||||
|
||||
} catch (UnsupportedModificationTypeException ex) {
|
||||
log.error("Unsupported modification type", ex);
|
||||
throw new InternalRepositoryException(ex);
|
||||
|
||||
} finally {
|
||||
GitUtil.release(revWalk);
|
||||
GitUtil.close(gitRepository);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifications getModifications(ModificationsCommandRequest request) {
|
||||
return getModifications(request.getRevision());
|
||||
}
|
||||
|
||||
private void appendModification(Modifications modifications, DiffEntry entry) throws UnsupportedModificationTypeException {
|
||||
DiffEntry.ChangeType type = entry.getChangeType();
|
||||
if (type == DiffEntry.ChangeType.ADD) {
|
||||
modifications.getAdded().add(entry.getNewPath());
|
||||
} else if (type == DiffEntry.ChangeType.MODIFY) {
|
||||
modifications.getModified().add(entry.getNewPath());
|
||||
} else if (type == DiffEntry.ChangeType.DELETE) {
|
||||
modifications.getRemoved().add(entry.getOldPath());
|
||||
} else {
|
||||
throw new UnsupportedModificationTypeException(MessageFormat.format("The modification type: {0} is not supported.", type));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,17 +36,15 @@ package sonia.scm.repository.spi;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import sonia.scm.repository.GitRepositoryHandler;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.api.Command;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -188,6 +186,11 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider
|
||||
return new GitLogCommand(context, repository);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModificationsCommand getModificationsCommand() {
|
||||
return new GitModificationsCommand(context,repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
|
||||
public class UnsupportedModificationTypeException extends InternalRepositoryException {
|
||||
public UnsupportedModificationTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -85,14 +85,14 @@ public class AbstractRemoteCommandTestBase
|
||||
outgoingDirectory = tempFolder.newFile("outgoing");
|
||||
outgoingDirectory.delete();
|
||||
|
||||
incomgingRepository = new Repository("1", "git", "space", "incoming");
|
||||
incomingRepository = 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();
|
||||
|
||||
handler = mock(GitRepositoryHandler.class);
|
||||
when(handler.getDirectory(incomgingRepository)).thenReturn(
|
||||
when(handler.getDirectory(incomingRepository)).thenReturn(
|
||||
incomingDirectory);
|
||||
when(handler.getDirectory(outgoingRepository)).thenReturn(
|
||||
outgoingDirectory);
|
||||
@@ -211,7 +211,7 @@ public class AbstractRemoteCommandTestBase
|
||||
protected GitRepositoryHandler handler;
|
||||
|
||||
/** Field description */
|
||||
protected Repository incomgingRepository;
|
||||
protected Repository incomingRepository;
|
||||
|
||||
/** Field description */
|
||||
protected Git incoming;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class GitIncomingCommandTest
|
||||
|
||||
commit(outgoing, "added a");
|
||||
|
||||
GitPullCommand pull = new GitPullCommand(handler, new GitContext(incomingDirectory), incomgingRepository);
|
||||
GitPullCommand pull = new GitPullCommand(handler, new GitContext(incomingDirectory), incomingRepository);
|
||||
PullCommandRequest req = new PullCommandRequest();
|
||||
req.setRemoteRepository(outgoingRepository);
|
||||
pull.pull(req);
|
||||
@@ -192,6 +192,6 @@ public class GitIncomingCommandTest
|
||||
private GitIncomingCommand createCommand()
|
||||
{
|
||||
return new GitIncomingCommand(handler, new GitContext(incomingDirectory),
|
||||
incomgingRepository);
|
||||
incomingRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,21 +168,23 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
||||
Changeset c = command.getChangeset("435df2f061add3589cb3");
|
||||
|
||||
assertNotNull(c);
|
||||
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c.getId());
|
||||
String revision = "435df2f061add3589cb326cc64be9b9c3897ceca";
|
||||
assertEquals(revision, c.getId());
|
||||
assertEquals("added a and b files", c.getDescription());
|
||||
checkDate(c.getDate());
|
||||
assertEquals("Douglas Adams", c.getAuthor().getName());
|
||||
assertEquals("douglas.adams@hitchhiker.com", c.getAuthor().getMail());
|
||||
assertEquals("added a and b files", c.getDescription());
|
||||
|
||||
Modifications mods = c.getModifications();
|
||||
GitModificationsCommand gitModificationsCommand = new GitModificationsCommand(createContext(), repository);
|
||||
Modifications modifications = gitModificationsCommand.getModifications(revision);
|
||||
|
||||
assertNotNull(mods);
|
||||
assertTrue("modified list should be empty", mods.getModified().isEmpty());
|
||||
assertTrue("removed list should be empty", mods.getRemoved().isEmpty());
|
||||
assertFalse("added list should not be empty", mods.getAdded().isEmpty());
|
||||
assertEquals(2, mods.getAdded().size());
|
||||
assertThat(mods.getAdded(), contains("a.txt", "b.txt"));
|
||||
assertNotNull(modifications);
|
||||
assertTrue("modified list should be empty", modifications.getModified().isEmpty());
|
||||
assertTrue("removed list should be empty", modifications.getRemoved().isEmpty());
|
||||
assertFalse("added list should not be empty", modifications.getAdded().isEmpty());
|
||||
assertEquals(2, modifications.getAdded().size());
|
||||
assertThat(modifications.getAdded(), contains("a.txt", "b.txt"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.Modifications;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
|
||||
public class GitModificationsCommandTest extends AbstractRemoteCommandTestBase {
|
||||
|
||||
private GitModificationsCommand incomingModificationsCommand;
|
||||
private GitModificationsCommand outgoingModificationsCommand;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
incomingModificationsCommand = new GitModificationsCommand(new GitContext(incomingDirectory), incomingRepository);
|
||||
outgoingModificationsCommand = new GitModificationsCommand(new GitContext(outgoingDirectory), outgoingRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReadAddedFiles() throws Exception {
|
||||
write(outgoing, outgoingDirectory, "a.txt", "bal bla");
|
||||
RevCommit addedFileCommit = commit(outgoing, "add file");
|
||||
String revision = addedFileCommit.getName();
|
||||
Consumer<Modifications> assertModifications = assertAddedFiles("a.txt");
|
||||
assertModifications.accept(outgoingModificationsCommand.getModifications(revision));
|
||||
pushOutgoingAndPullIncoming();
|
||||
assertModifications.accept(incomingModificationsCommand.getModifications(revision));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReadModifiedFiles() throws Exception {
|
||||
write(outgoing, outgoingDirectory, "a.txt", "bal bla");
|
||||
commit(outgoing, "add file");
|
||||
write(outgoing, outgoingDirectory, "a.txt", "modified content");
|
||||
RevCommit modifiedFileCommit = commit(outgoing, "modify file");
|
||||
String revision = modifiedFileCommit.getName();
|
||||
Consumer<Modifications> assertModifications = assertModifiedFiles("a.txt");
|
||||
assertModifications.accept(outgoingModificationsCommand.getModifications(revision));
|
||||
pushOutgoingAndPullIncoming();
|
||||
assertModifications.accept(incomingModificationsCommand.getModifications(revision));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReadRemovedFiles() throws Exception {
|
||||
String fileName = "a.txt";
|
||||
write(outgoing, outgoingDirectory, fileName, "bal bla");
|
||||
commit(outgoing, "add file");
|
||||
File file = new File(outgoingDirectory, fileName);
|
||||
file.delete();
|
||||
outgoing.add().setUpdate(true).addFilepattern(".").call();
|
||||
RevCommit removedFileCommit = commit(outgoing, "remove file");
|
||||
String revision = removedFileCommit.getName();
|
||||
Consumer<Modifications> assertModifications = assertRemovedFiles(fileName);
|
||||
pushOutgoingAndPullIncoming();
|
||||
assertModifications.accept(incomingModificationsCommand.getModifications(revision));
|
||||
assertModifications.accept(outgoingModificationsCommand.getModifications(revision));
|
||||
}
|
||||
|
||||
void pushOutgoingAndPullIncoming() throws IOException {
|
||||
GitPushCommand cmd = new GitPushCommand(handler, new GitContext(outgoingDirectory),
|
||||
outgoingRepository);
|
||||
PushCommandRequest request = new PushCommandRequest();
|
||||
request.setRemoteRepository(incomingRepository);
|
||||
cmd.push(request);
|
||||
GitPullCommand pullCommand = new GitPullCommand(handler, new GitContext(incomingDirectory),
|
||||
incomingRepository);
|
||||
PullCommandRequest pullRequest = new PullCommandRequest();
|
||||
pullRequest.setRemoteRepository(incomingRepository);
|
||||
pullCommand.pull(pullRequest);
|
||||
}
|
||||
|
||||
Consumer<Modifications> assertRemovedFiles(String fileName) {
|
||||
return (modifications) -> {
|
||||
assertThat(modifications).isNotNull();
|
||||
assertThat(modifications.getAdded())
|
||||
.as("added files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getModified())
|
||||
.as("modified files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getRemoved())
|
||||
.as("removed files modifications")
|
||||
.hasSize(1)
|
||||
.containsOnly(fileName);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Consumer<Modifications> assertModifiedFiles(String file) {
|
||||
return (modifications) -> {
|
||||
assertThat(modifications).isNotNull();
|
||||
assertThat(modifications.getAdded())
|
||||
.as("added files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getModified())
|
||||
.as("modified files modifications")
|
||||
.hasSize(1)
|
||||
.containsOnly(file);
|
||||
assertThat(modifications.getRemoved())
|
||||
.as("removed files modifications")
|
||||
.hasSize(0);
|
||||
};
|
||||
}
|
||||
|
||||
Consumer<Modifications> assertAddedFiles(String file) {
|
||||
return (modifications) -> {
|
||||
assertThat(modifications).isNotNull();
|
||||
assertThat(modifications.getAdded())
|
||||
.as("added files modifications")
|
||||
.hasSize(1)
|
||||
.containsOnly(file);
|
||||
assertThat(modifications.getModified())
|
||||
.as("modified files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getRemoved())
|
||||
.as("removed files modifications")
|
||||
.hasSize(0);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public class GitOutgoingCommandTest extends AbstractRemoteCommandTestBase
|
||||
GitOutgoingCommand cmd = createCommand();
|
||||
OutgoingCommandRequest request = new OutgoingCommandRequest();
|
||||
|
||||
request.setRemoteRepository(incomgingRepository);
|
||||
request.setRemoteRepository(incomingRepository);
|
||||
|
||||
ChangesetPagingResult cpr = cmd.getOutgoingChangesets(request);
|
||||
|
||||
@@ -98,7 +98,7 @@ public class GitOutgoingCommandTest extends AbstractRemoteCommandTestBase
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
@Test
|
||||
public void testGetOutgoingChangesetsWithAllreadyPushedChanges()
|
||||
public void testGetOutgoingChangesetsWithAlreadyPushedChanges()
|
||||
throws IOException, GitAPIException
|
||||
{
|
||||
write(outgoing, outgoingDirectory, "a.txt", "content of a.txt");
|
||||
@@ -110,7 +110,7 @@ public class GitOutgoingCommandTest extends AbstractRemoteCommandTestBase
|
||||
outgoingRepository);
|
||||
PushCommandRequest req = new PushCommandRequest();
|
||||
|
||||
req.setRemoteRepository(incomgingRepository);
|
||||
req.setRemoteRepository(incomingRepository);
|
||||
push.push(req);
|
||||
|
||||
write(outgoing, outgoingDirectory, "b.txt", "content of b.txt");
|
||||
@@ -120,7 +120,7 @@ public class GitOutgoingCommandTest extends AbstractRemoteCommandTestBase
|
||||
GitOutgoingCommand cmd = createCommand();
|
||||
OutgoingCommandRequest request = new OutgoingCommandRequest();
|
||||
|
||||
request.setRemoteRepository(incomgingRepository);
|
||||
request.setRemoteRepository(incomingRepository);
|
||||
|
||||
ChangesetPagingResult cpr = cmd.getOutgoingChangesets(request);
|
||||
|
||||
@@ -144,7 +144,7 @@ public class GitOutgoingCommandTest extends AbstractRemoteCommandTestBase
|
||||
GitOutgoingCommand cmd = createCommand();
|
||||
OutgoingCommandRequest request = new OutgoingCommandRequest();
|
||||
|
||||
request.setRemoteRepository(incomgingRepository);
|
||||
request.setRemoteRepository(incomingRepository);
|
||||
|
||||
ChangesetPagingResult cpr = cmd.getOutgoingChangesets(request);
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class GitPushCommandTest extends AbstractRemoteCommandTestBase
|
||||
GitPushCommand cmd = createCommand();
|
||||
PushCommandRequest request = new PushCommandRequest();
|
||||
|
||||
request.setRemoteRepository(incomgingRepository);
|
||||
request.setRemoteRepository(incomingRepository);
|
||||
|
||||
PushResponse response = cmd.push(request);
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.spi.javahg.HgLogChangesetCommand;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
public class HgModificationsCommand extends AbstractCommand implements ModificationsCommand {
|
||||
|
||||
HgModificationsCommand(HgCommandContext context, Repository repository) {
|
||||
super(context, repository);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Modifications getModifications(String revision) {
|
||||
com.aragost.javahg.Repository repository = open();
|
||||
HgLogChangesetCommand hgLogChangesetCommand = HgLogChangesetCommand.on(repository, getContext().getConfig());
|
||||
int hgRevision = hgLogChangesetCommand.rev(revision).singleRevision();
|
||||
Modifications modifications = hgLogChangesetCommand.rev(MessageFormat.format("{0}:{0}", hgRevision)).extractModifications();
|
||||
modifications.setRevision(revision);
|
||||
return modifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifications getModifications(ModificationsCommandRequest request) {
|
||||
return getModifications(request.getRevision());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -41,21 +41,18 @@ import com.aragost.javahg.internals.AbstractCommand;
|
||||
import com.aragost.javahg.internals.HgInputStream;
|
||||
import com.aragost.javahg.internals.RuntimeIOException;
|
||||
import com.aragost.javahg.internals.Utils;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.HgConfig;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.Person;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -251,33 +248,14 @@ public abstract class AbstractChangesetCommand extends AbstractCommand
|
||||
changeset.getProperties().put(PROPERTY_CLOSE, "true");
|
||||
}
|
||||
|
||||
Modifications modifications = changeset.getModifications();
|
||||
|
||||
String line = in.textUpTo('\n');
|
||||
|
||||
while (line.length() > 0)
|
||||
{
|
||||
|
||||
if (line.startsWith("a "))
|
||||
{
|
||||
modifications.getAdded().add(line.substring(2));
|
||||
}
|
||||
else if (line.startsWith("m "))
|
||||
{
|
||||
modifications.getModified().add(line.substring(2));
|
||||
}
|
||||
else if (line.startsWith("d "))
|
||||
{
|
||||
modifications.getRemoved().add(line.substring(2));
|
||||
}
|
||||
else if (line.startsWith("t "))
|
||||
while (line.length() > 0) {
|
||||
if (line.startsWith("t "))
|
||||
{
|
||||
changeset.getTags().add(line.substring(2));
|
||||
}
|
||||
|
||||
line = in.textUpTo('\n');
|
||||
}
|
||||
|
||||
String message = in.textUpTo('\0');
|
||||
|
||||
changeset.setDescription(message);
|
||||
@@ -285,6 +263,36 @@ public abstract class AbstractChangesetCommand extends AbstractCommand
|
||||
return changeset;
|
||||
}
|
||||
|
||||
protected Modifications readModificationsFromStream(HgInputStream in) {
|
||||
try {
|
||||
boolean found = in.find(CHANGESET_PATTERN);
|
||||
if (found) {
|
||||
while (!in.match(CHANGESET_PATTERN)) {
|
||||
return extractModifications(in);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeIOException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Modifications extractModifications(HgInputStream in) throws IOException {
|
||||
Modifications modifications = new Modifications();
|
||||
String line = in.textUpTo('\n');
|
||||
while (line.length() > 0) {
|
||||
if (line.startsWith("a ")) {
|
||||
modifications.getAdded().add(line.substring(2));
|
||||
} else if (line.startsWith("m ")) {
|
||||
modifications.getModified().add(line.substring(2));
|
||||
} else if (line.startsWith("d ")) {
|
||||
modifications.getRemoved().add(line.substring(2));
|
||||
}
|
||||
line = in.textUpTo('\n');
|
||||
}
|
||||
return modifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -38,14 +38,14 @@ package sonia.scm.repository.spi.javahg;
|
||||
import com.aragost.javahg.Repository;
|
||||
import com.aragost.javahg.internals.HgInputStream;
|
||||
import com.aragost.javahg.internals.Utils;
|
||||
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.HgConfig;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
import sonia.scm.repository.Modifications;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -106,11 +106,22 @@ public class HgLogChangesetCommand extends AbstractChangesetCommand
|
||||
*/
|
||||
public List<Changeset> execute(String... files)
|
||||
{
|
||||
cmdAppend("--style", CHANGESET_EAGER_STYLE_PATH);
|
||||
return readListFromStream(getHgInputStream(files, CHANGESET_EAGER_STYLE_PATH));
|
||||
}
|
||||
|
||||
HgInputStream stream = launchStream(files);
|
||||
/**
|
||||
* Extract Modifications from the Repository files
|
||||
*
|
||||
* @param files repo files
|
||||
* @return modifications
|
||||
*/
|
||||
public Modifications extractModifications(String... files) {
|
||||
return readModificationsFromStream(getHgInputStream(files, CHANGESET_EAGER_STYLE_PATH));
|
||||
}
|
||||
|
||||
return readListFromStream(stream);
|
||||
HgInputStream getHgInputStream(String[] files, String changesetStylePath) {
|
||||
cmdAppend("--style", changesetStylePath);
|
||||
return launchStream(files);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,11 +149,7 @@ public class HgLogChangesetCommand extends AbstractChangesetCommand
|
||||
*/
|
||||
public List<Integer> loadRevisions(String... files)
|
||||
{
|
||||
cmdAppend("--style", CHANGESET_LAZY_STYLE_PATH);
|
||||
|
||||
HgInputStream stream = launchStream(files);
|
||||
|
||||
return loadRevisionsFromStream(stream);
|
||||
return loadRevisionsFromStream(getHgInputStream(files, CHANGESET_LAZY_STYLE_PATH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,11 +32,11 @@ package sonia.scm.repository.client.spi;
|
||||
|
||||
import com.aragost.javahg.Repository;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.io.IOException;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.Person;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Mercurial implementation of the {@link CommitCommand}.
|
||||
*
|
||||
@@ -70,9 +70,6 @@ public class HgCommitCommand implements CommitCommand
|
||||
|
||||
changeset.setBranches(Lists.newArrayList(c.getBranch()));
|
||||
changeset.setTags(c.tags());
|
||||
changeset.setModifications(
|
||||
new Modifications(c.getAddedFiles(), c.getModifiedFiles(), c.getDeletedFiles())
|
||||
);
|
||||
return changeset;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ import org.junit.Test;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -133,27 +136,28 @@ public class HgLogCommandTest extends AbstractHgCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommit() {
|
||||
public void testGetCommit() throws IOException, RevisionNotFoundException {
|
||||
HgLogCommand command = createComamnd();
|
||||
String revision = "a9bacaf1b7fa0cebfca71fed4e59ed69a6319427";
|
||||
Changeset c =
|
||||
command.getChangeset("a9bacaf1b7fa0cebfca71fed4e59ed69a6319427");
|
||||
command.getChangeset(revision);
|
||||
|
||||
assertNotNull(c);
|
||||
assertEquals("a9bacaf1b7fa0cebfca71fed4e59ed69a6319427", c.getId());
|
||||
assertEquals(revision, c.getId());
|
||||
assertEquals("added a and b files", c.getDescription());
|
||||
checkDate(c.getDate());
|
||||
assertEquals("Douglas Adams", c.getAuthor().getName());
|
||||
assertEquals("douglas.adams@hitchhiker.com", c.getAuthor().getMail());
|
||||
assertEquals("added a and b files", c.getDescription());
|
||||
ModificationsCommand modificationsCommand = new HgModificationsCommand(cmdContext, repository);
|
||||
Modifications modifications = modificationsCommand.getModifications(revision);
|
||||
|
||||
Modifications mods = c.getModifications();
|
||||
|
||||
assertNotNull(mods);
|
||||
assertTrue("modified list should be empty", mods.getModified().isEmpty());
|
||||
assertTrue("removed list should be empty", mods.getRemoved().isEmpty());
|
||||
assertFalse("added list should not be empty", mods.getAdded().isEmpty());
|
||||
assertEquals(2, mods.getAdded().size());
|
||||
assertThat(mods.getAdded(), contains("a.txt", "b.txt"));
|
||||
assertNotNull(modifications);
|
||||
assertTrue("modified list should be empty", modifications.getModified().isEmpty());
|
||||
assertTrue("removed list should be empty", modifications.getRemoved().isEmpty());
|
||||
assertFalse("added list should not be empty", modifications.getAdded().isEmpty());
|
||||
assertEquals(2, modifications.getAdded().size());
|
||||
assertThat(modifications.getAdded(), contains("a.txt", "b.txt"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import com.aragost.javahg.Changeset;
|
||||
import com.aragost.javahg.commands.RemoveCommand;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.HgTestUtil;
|
||||
import sonia.scm.repository.Modifications;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
|
||||
public class HgModificationsCommandTest extends IncomingOutgoingTestBase {
|
||||
|
||||
|
||||
private HgModificationsCommand outgoingModificationsCommand;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
HgCommandContext outgoingContext = new HgCommandContext(HgTestUtil.createHookManager(), handler, outgoingRepository, outgoingDirectory);
|
||||
outgoingModificationsCommand = new HgModificationsCommand(outgoingContext, outgoingRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReadAddedFiles() throws Exception {
|
||||
String fileName = "a.txt";
|
||||
writeNewFile(outgoing, outgoingDirectory, fileName, "bal bla");
|
||||
Changeset changeset = commit(outgoing, "added a.txt");
|
||||
String revision = String.valueOf(changeset.getRevision());
|
||||
Consumer<Modifications> assertModifications = assertAddedFile(fileName);
|
||||
assertModifications.accept(outgoingModificationsCommand.getModifications(revision));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReadModifiedFiles() throws Exception {
|
||||
String fileName = "a.txt";
|
||||
writeNewFile(outgoing, outgoingDirectory, fileName, "bal bla");
|
||||
commit(outgoing, "added a.txt");
|
||||
writeNewFile(outgoing, outgoingDirectory, fileName, "new content");
|
||||
Changeset changeset = commit(outgoing, "modified a.txt");
|
||||
String revision = String.valueOf(changeset.getRevision());
|
||||
Consumer<Modifications> assertModifications = assertModifiedFiles(fileName);
|
||||
assertModifications.accept(outgoingModificationsCommand.getModifications(revision));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReadRemovedFiles() throws Exception {
|
||||
String fileName = "a.txt";
|
||||
writeNewFile(outgoing, outgoingDirectory, fileName, "bal bla");
|
||||
commit(outgoing, "added a.txt");
|
||||
File file = new File(outgoingDirectory, fileName);
|
||||
file.delete();
|
||||
RemoveCommand.on(outgoing).execute(file);
|
||||
Changeset changeset = commit(outgoing, "removed a.txt");
|
||||
String revision = String.valueOf(changeset.getRevision());
|
||||
Consumer<Modifications> assertModifications = assertRemovedFiles(fileName);
|
||||
assertModifications.accept(outgoingModificationsCommand.getModifications(revision));
|
||||
}
|
||||
|
||||
|
||||
Consumer<Modifications> assertRemovedFiles(String fileName) {
|
||||
return (modifications) -> {
|
||||
assertThat(modifications).isNotNull();
|
||||
assertThat(modifications.getAdded())
|
||||
.as("added files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getModified())
|
||||
.as("modified files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getRemoved())
|
||||
.as("removed files modifications")
|
||||
.hasSize(1)
|
||||
.containsOnly(fileName);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Consumer<Modifications> assertModifiedFiles(String file) {
|
||||
return (modifications) -> {
|
||||
assertThat(modifications).isNotNull();
|
||||
assertThat(modifications.getAdded())
|
||||
.as("added files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getModified())
|
||||
.as("modified files modifications")
|
||||
.hasSize(1)
|
||||
.containsOnly(file);
|
||||
assertThat(modifications.getRemoved())
|
||||
.as("removed files modifications")
|
||||
.hasSize(0);
|
||||
};
|
||||
}
|
||||
|
||||
Consumer<Modifications> assertAddedFile(String addedFile) {
|
||||
return (modifications) -> {
|
||||
assertThat(modifications).isNotNull();
|
||||
assertThat(modifications.getAdded())
|
||||
.as("added files modifications")
|
||||
.hasSize(1)
|
||||
.containsOnly(addedFile);
|
||||
assertThat(modifications.getModified())
|
||||
.as("modified files modifications")
|
||||
.hasSize(0);
|
||||
assertThat(modifications.getRemoved())
|
||||
.as("removed files modifications")
|
||||
.hasSize(0);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,88 +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.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.admin.ISVNChangeEntryHandler;
|
||||
import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class SvnModificationHandler implements ISVNChangeEntryHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param changeset
|
||||
*/
|
||||
public SvnModificationHandler(Changeset changeset)
|
||||
{
|
||||
this.changeset = changeset;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param entry
|
||||
*
|
||||
* @throws SVNException
|
||||
*/
|
||||
@Override
|
||||
public void handleEntry(SVNChangeEntry entry) throws SVNException
|
||||
{
|
||||
Modifications modification = changeset.getModifications();
|
||||
|
||||
if (modification == null)
|
||||
{
|
||||
modification = new Modifications();
|
||||
changeset.setModifications(modification);
|
||||
}
|
||||
|
||||
SvnUtil.appendModification(modification, entry);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private Changeset changeset;
|
||||
}
|
||||
@@ -49,7 +49,6 @@ import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNXMLUtil;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||
import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
@@ -103,30 +102,37 @@ public final class SvnUtil
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* TODO: type replaced
|
||||
*
|
||||
*
|
||||
* @param modifications
|
||||
* @param entry
|
||||
*/
|
||||
public static void appendModification(Modifications modifications,
|
||||
SVNLogEntryPath entry)
|
||||
{
|
||||
appendModification(modifications, entry.getType(), entry.getPath());
|
||||
public static long parseRevision(String v) throws RevisionNotFoundException {
|
||||
long result = -1l;
|
||||
|
||||
if (!Strings.isNullOrEmpty(v))
|
||||
{
|
||||
try
|
||||
{
|
||||
result = Long.parseLong(v);
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new RevisionNotFoundException(v);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param modifications
|
||||
* @param entry
|
||||
*/
|
||||
public static void appendModification(Modifications modifications,
|
||||
SVNChangeEntry entry)
|
||||
{
|
||||
appendModification(modifications, entry.getType(), entry.getPath());
|
||||
|
||||
public static Modifications createModifications(SVNLogEntry entry, String revision) {
|
||||
Modifications modifications = new Modifications();
|
||||
modifications.setRevision(revision);
|
||||
Map<String, SVNLogEntryPath> changeMap = entry.getChangedPaths();
|
||||
|
||||
if (Util.isNotEmpty(changeMap)) {
|
||||
|
||||
for (SVNLogEntryPath e : changeMap.values()) {
|
||||
appendModification(modifications, e.getType(), e.getPath());
|
||||
}
|
||||
}
|
||||
return modifications;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,19 +216,6 @@ public final class SvnUtil
|
||||
{
|
||||
changeset.getParents().add(String.valueOf(revision - 1));
|
||||
}
|
||||
|
||||
Map<String, SVNLogEntryPath> changeMap = entry.getChangedPaths();
|
||||
|
||||
if (Util.isNotEmpty(changeMap))
|
||||
{
|
||||
Modifications modifications = changeset.getModifications();
|
||||
|
||||
for (SVNLogEntryPath e : changeMap.values())
|
||||
{
|
||||
appendModification(modifications, e);
|
||||
}
|
||||
}
|
||||
|
||||
return changeset;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ import sonia.scm.util.Util;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static sonia.scm.repository.SvnUtil.parseRevision;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
@@ -144,25 +146,6 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
return changesets;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
private long parseRevision(String v) throws RevisionNotFoundException {
|
||||
long result = -1l;
|
||||
|
||||
if (!Strings.isNullOrEmpty(v))
|
||||
{
|
||||
try
|
||||
{
|
||||
result = Long.parseLong(v);
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new RevisionNotFoundException(v);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
@Slf4j
|
||||
public class SvnModificationsCommand extends AbstractSvnCommand implements ModificationsCommand {
|
||||
|
||||
SvnModificationsCommand(SvnContext context, Repository repository) {
|
||||
super(context, repository);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Modifications getModifications(String revision) throws IOException, RevisionNotFoundException {
|
||||
Modifications modifications = null;
|
||||
log.debug("get modifications {}", revision);
|
||||
try {
|
||||
long revisionNumber = SvnUtil.parseRevision(revision);
|
||||
SVNRepository repo = open();
|
||||
Collection<SVNLogEntry> entries = repo.log(null, null, revisionNumber,
|
||||
revisionNumber, true, true);
|
||||
if (Util.isNotEmpty(entries)) {
|
||||
modifications = SvnUtil.createModifications(entries.iterator().next(), revision);
|
||||
}
|
||||
} catch (SVNException ex) {
|
||||
throw new InternalRepositoryException("could not open repository", ex);
|
||||
}
|
||||
return modifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifications getModifications(ModificationsCommandRequest request) throws IOException, RevisionNotFoundException {
|
||||
return getModifications(request.getRevision());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -37,22 +37,19 @@ package sonia.scm.repository.spi;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.wc.ISVNOptions;
|
||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCUtil;
|
||||
import org.tmatesoft.svn.core.wc.admin.SVNLookClient;
|
||||
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.SvnModificationHandler;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.File;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -123,10 +120,6 @@ public class SvnPreReceiveHookChangesetProvier
|
||||
{
|
||||
changeset = SvnUtil.createChangeset(entry);
|
||||
changeset.setId(SvnUtil.createTransactionEntryId(transaction));
|
||||
|
||||
clientManager.doGetChanged(repositoryDirectory, transaction,
|
||||
new SvnModificationHandler(changeset), true);
|
||||
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
|
||||
@@ -40,6 +40,8 @@ import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -128,7 +130,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommit() throws RevisionNotFoundException {
|
||||
public void testGetCommit() throws RevisionNotFoundException, IOException {
|
||||
Changeset c = createCommand().getChangeset("3");
|
||||
|
||||
assertNotNull(c);
|
||||
@@ -137,15 +139,15 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
checkDate(c.getDate());
|
||||
assertEquals("perfect", c.getAuthor().getName());
|
||||
assertNull("douglas.adams@hitchhiker.com", c.getAuthor().getMail());
|
||||
SvnModificationsCommand modificationsCommand = new SvnModificationsCommand(createContext(), repository);
|
||||
Modifications modifications = modificationsCommand.getModifications("3");
|
||||
|
||||
Modifications mods = c.getModifications();
|
||||
|
||||
assertNotNull(mods);
|
||||
assertEquals(1, mods.getModified().size());
|
||||
assertEquals(1, mods.getRemoved().size());
|
||||
assertTrue("added list should be empty", mods.getAdded().isEmpty());
|
||||
assertEquals("a.txt", mods.getModified().get(0));
|
||||
assertEquals("b.txt", mods.getRemoved().get(0));
|
||||
assertNotNull(modifications);
|
||||
assertEquals(1, modifications.getModified().size());
|
||||
assertEquals(1, modifications.getRemoved().size());
|
||||
assertTrue("added list should be empty", modifications.getAdded().isEmpty());
|
||||
assertEquals("a.txt", modifications.getModified().get(0));
|
||||
assertEquals("b.txt", modifications.getRemoved().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user