implement modification api in git, svn and hg. implement the endpoint

This commit is contained in:
Mohamed Karray
2018-09-13 11:57:10 +02:00
parent 6b6b558823
commit 4697c55f96
52 changed files with 1231 additions and 426 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 ----------------------------------------------------------

View File

@@ -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());
}
}

View File

@@ -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())
{

View File

@@ -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