diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java new file mode 100644 index 0000000000..cfbe1bbf9d --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java @@ -0,0 +1,102 @@ +/** + * 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.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.Repository; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractCommand +{ + + /** + * Constructs ... + * + * + * @param context + * @param repository + */ + public AbstractCommand(HgCommandContext context, Repository repository) + { + this.context = context; + this.repository = repository; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public com.aragost.javahg.Repository open() + { + return context.open(); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public HgCommandContext getContext() + { + return context; + } + + /** + * Method description + * + * + * @return + */ + public Repository getRepository() + { + return repository; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private HgCommandContext context; + + /** Field description */ + private Repository repository; +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java index 4c9d3f7f06..03ff3ec797 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java @@ -30,32 +30,38 @@ */ + package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- +import com.aragost.javahg.Changeset; +import com.aragost.javahg.commands.AnnotateCommand; +import com.aragost.javahg.commands.AnnotateLine; + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.repository.BlameLine; import sonia.scm.repository.BlameResult; -import sonia.scm.repository.HgContext; -import sonia.scm.repository.HgPythonScript; -import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Person; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; //~--- JDK imports ------------------------------------------------------------ -import java.io.File; import java.io.IOException; -import java.util.Map; +import java.util.List; /** * * @author Sebastian Sdorra */ -public class HgBlameCommand extends AbstractHgCommand implements BlameCommand +public class HgBlameCommand extends AbstractCommand implements BlameCommand { /** @@ -70,15 +76,12 @@ public class HgBlameCommand extends AbstractHgCommand implements BlameCommand * Constructs ... * * - * @param handler * @param context * @param repository - * @param repositoryDirectory */ - public HgBlameCommand(HgRepositoryHandler handler, HgContext context, - Repository repository, File repositoryDirectory) + public HgBlameCommand(HgCommandContext context, Repository repository) { - super(handler, context, repository, repositoryDirectory); + super(context, repository); } //~--- get methods ---------------------------------------------------------- @@ -103,8 +106,56 @@ public class HgBlameCommand extends AbstractHgCommand implements BlameCommand logger.debug("get blame result for {}", request); } - Map env = createEnvironment(request); + AnnotateCommand cmd = AnnotateCommand.on(open()); - return getResultFromScript(BlameResult.class, HgPythonScript.BLAME, env); + if (!Strings.isNullOrEmpty(request.getRevision())) + { + cmd.rev(request.getRevision()); + } + + List blameLines = Lists.newArrayList(); + List lines = cmd.execute(request.getPath()); + int counter = 0; + + for (AnnotateLine line : lines) + { + blameLines.add(convert(line, ++counter)); + } + + return new BlameResult(blameLines); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param line + * @param counter + * + * @return + */ + private BlameLine convert(AnnotateLine line, int counter) + { + BlameLine blameLine = new BlameLine(); + + blameLine.setLineNumber(counter); + blameLine.setCode(line.getLine()); + + Changeset c = line.getChangeset(); + + blameLine.setDescription(c.getMessage()); + blameLine.setWhen(c.getTimestamp().getDate().getTime()); + blameLine.setRevision(c.getNode()); + + String user = c.getUser(); + + if (!Strings.isNullOrEmpty(user)) + { + blameLine.setAuthor(Person.toPerson(user)); + } + + return blameLine; } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCommandContext.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCommandContext.java new file mode 100644 index 0000000000..be9dffc4d6 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCommandContext.java @@ -0,0 +1,114 @@ +/** + * 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.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.aragost.javahg.Repository; +import com.aragost.javahg.RepositoryConfiguration; + +import sonia.scm.repository.HgConfig; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class HgCommandContext implements Closeable +{ + + /** + * Constructs ... + * + * + * @param config + * @param directory + */ + public HgCommandContext(HgConfig config, File directory) + { + this.config = config; + this.directory = directory; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + if (repository != null) + { + repository.close(); + } + } + + /** + * Method description + * + * + * @return + */ + public Repository open() + { + if (repository == null) + { + RepositoryConfiguration repoConfiguration = + RepositoryConfiguration.DEFAULT; + + repoConfiguration.setHgBin(config.getHgBinary()); + repository = Repository.open(repoConfiguration, directory); + } + + return repository; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private HgConfig config; + + /** Field description */ + private File directory; + + /** Field description */ + private Repository repository; +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java index ffcc0fe776..ea15f74c1f 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java @@ -30,11 +30,13 @@ */ + package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.collect.ImmutableSet; +import com.google.common.io.Closeables; import com.google.inject.Provider; import sonia.scm.repository.HgContext; @@ -45,6 +47,7 @@ import sonia.scm.repository.api.Command; //~--- JDK imports ------------------------------------------------------------ import java.io.File; +import java.io.IOException; import java.util.Set; @@ -79,6 +82,21 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider this.handler = handler; this.repository = repository; this.repositoryDirectory = handler.getDirectory(repository); + this.context = new HgCommandContext(handler.getConfig(), repositoryDirectory); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + Closeables.closeQuietly(context); } //~--- get methods ---------------------------------------------------------- @@ -92,8 +110,7 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider @Override public HgBlameCommand getBlameCommand() { - return new HgBlameCommand(handler, hgContextProvider.get(), repository, - repositoryDirectory); + return new HgBlameCommand(context, repository); } /** @@ -162,6 +179,9 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider //~--- fields --------------------------------------------------------------- + /** Field description */ + private HgCommandContext context; + /** Field description */ private HgRepositoryHandler handler; diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java index d55f6d6fce..29184c2e35 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java @@ -30,6 +30,7 @@ */ + package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- @@ -68,9 +69,7 @@ public class HgBlameCommandTest extends AbstractHgCommandTestBase request.setPath("a.txt"); - BlameResult result = new HgBlameCommand(handler, new HgContext(), - repository, - repositoryDirectory).getBlameResult(request); + BlameResult result = createCommand().getBlameResult(request); assertNotNull(result); assertEquals(2, result.getTotal()); @@ -80,7 +79,7 @@ public class HgBlameCommandTest extends AbstractHgCommandTestBase checkFirstLine(line); line = result.getLine(1); assertEquals(2, line.getLineNumber()); - assertEquals("4:2baab8e80280", line.getRevision()); + assertEquals("2baab8e80280ef05a9aa76c49c76feca2872afb7", line.getRevision()); checkDate(line.getWhen()); assertEquals("line for blame", line.getCode()); assertEquals("added new line for blame", line.getDescription()); @@ -103,11 +102,9 @@ public class HgBlameCommandTest extends AbstractHgCommandTestBase BlameCommandRequest request = new BlameCommandRequest(); request.setPath("a.txt"); - request.setRevision("a9bacaf1b7fa"); + request.setRevision("a9bacaf1b7fa0cebfca71fed4e59ed69a6319427"); - BlameResult result = new HgBlameCommand(handler, new HgContext(), - repository, - repositoryDirectory).getBlameResult(request); + BlameResult result = createCommand().getBlameResult(request); assertNotNull(result); assertEquals(1, result.getTotal()); @@ -126,11 +123,23 @@ public class HgBlameCommandTest extends AbstractHgCommandTestBase private void checkFirstLine(BlameLine line) { assertEquals(1, line.getLineNumber()); - assertEquals("0:a9bacaf1b7fa", line.getRevision()); + assertEquals("a9bacaf1b7fa0cebfca71fed4e59ed69a6319427", line.getRevision()); checkDate(line.getWhen()); assertEquals("a", line.getCode()); assertEquals("added a and b files", line.getDescription()); assertEquals("Douglas Adams", line.getAuthor().getName()); assertEquals("douglas.adams@hitchhiker.com", line.getAuthor().getMail()); } + + /** + * Method description + * + * + * @return + */ + private BlameCommand createCommand() + { + return new HgBlameCommand(new HgCommandContext(handler.getConfig(), + repositoryDirectory), repository); + } }