diff --git a/CHANGELOG.md b/CHANGELOG.md index dd06aa41ed..dabacc9d8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Include messages from scm protocol in modification or merge errors ([#1420](https://github.com/scm-manager/scm-manager/pull/1420)) ### Fixed +- Missing close of hg diff command ([#1417](https://github.com/scm-manager/scm-manager/pull/1417)) - Error on repository initialization with least-privilege user ([#1414](https://github.com/scm-manager/scm-manager/pull/1414)) - Adhere to git quiet flag ([#1421](https://github.com/scm-manager/scm-manager/pull/1421)) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java index 605ce5555a..08c42a023e 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java @@ -24,71 +24,65 @@ package sonia.scm.repository.spi; -//~--- non-JDK imports -------------------------------------------------------- - +import com.aragost.javahg.Repository; import com.google.common.base.Strings; import com.google.common.io.ByteStreams; -import com.google.common.io.Closeables; import sonia.scm.repository.api.DiffCommandBuilder; import sonia.scm.repository.api.DiffFormat; import sonia.scm.repository.spi.javahg.HgDiffInternalCommand; import sonia.scm.web.HgUtil; +import javax.annotation.Nonnull; +import java.io.IOException; import java.io.InputStream; - -//~--- JDK imports ------------------------------------------------------------ +import java.io.OutputStream; /** * * @author Sebastian Sdorra */ -public class HgDiffCommand extends AbstractCommand implements DiffCommand -{ +public class HgDiffCommand extends AbstractCommand implements DiffCommand { - /** - * Constructs ... - * - * @param context - * - */ - HgDiffCommand(HgCommandContext context) - { + HgDiffCommand(HgCommandContext context) { super(context); } - //~--- get methods ---------------------------------------------------------- - @Override - public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) - { + public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) { return output -> { - com.aragost.javahg.Repository hgRepo = open(); - - HgDiffInternalCommand cmd = HgDiffInternalCommand.on(hgRepo); - DiffFormat format = request.getFormat(); - - if (format == DiffFormat.GIT) - { - cmd.git(); - } - - cmd.change(HgUtil.getRevision(request.getRevision())); - - InputStream inputStream = null; - + Repository hgRepo = open(); try { - - if (!Strings.isNullOrEmpty(request.getPath())) { - inputStream = cmd.stream(hgRepo.file(request.getPath())); - } else { - inputStream = cmd.stream(); - } - - ByteStreams.copy(inputStream, output); - + diff(hgRepo, request, output); } finally { - Closeables.close(inputStream, true); + getContext().close(); } }; } + + @SuppressWarnings("UnstableApiUsage") + private void diff(Repository hgRepo, DiffCommandRequest request, OutputStream output) throws IOException { + HgDiffInternalCommand cmd = createDiffCommand(hgRepo, request); + try (InputStream inputStream = streamDiff(hgRepo, cmd, request.getPath())) { + ByteStreams.copy(inputStream, output); + } + } + + @Nonnull + private HgDiffInternalCommand createDiffCommand(Repository hgRepo, DiffCommandRequest request) { + HgDiffInternalCommand cmd = HgDiffInternalCommand.on(hgRepo); + DiffFormat format = request.getFormat(); + if (format == DiffFormat.GIT) { + cmd.git(); + } + cmd.change(HgUtil.getRevision(request.getRevision())); + return cmd; + } + + private InputStream streamDiff(Repository hgRepo, HgDiffInternalCommand cmd, String path) { + if (!Strings.isNullOrEmpty(path)) { + return cmd.stream(hgRepo.file(path)); + } else { + return cmd.stream(); + } + } } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgDiffCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgDiffCommandTest.java new file mode 100644 index 0000000000..9775a5cd42 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgDiffCommandTest.java @@ -0,0 +1,78 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import org.junit.Test; +import sonia.scm.repository.api.DiffCommandBuilder; +import sonia.scm.repository.api.DiffFormat; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +public class HgDiffCommandTest extends AbstractHgCommandTestBase { + + @Test + public void shouldCreateDiff() throws IOException { + String content = diff(cmdContext, "3049df33fdbbded08b707bac3eccd0f7b453c58b"); + assertThat(content).contains("+e"); + } + + @Test + public void shouldCreateGitDiff() throws IOException { + DiffCommandRequest request = new DiffCommandRequest(); + request.setRevision("3049df33fdbbded08b707bac3eccd0f7b453c58b"); + request.setFormat(DiffFormat.GIT); + + String content = diff(cmdContext, request); + assertThat(content).contains("git"); + } + + @Test + public void shouldCloseContent() throws IOException { + HgCommandContext context = spy(cmdContext); + String content = diff(context, "a9bacaf1b7fa0cebfca71fed4e59ed69a6319427"); + assertThat(content).contains("+b"); + verify(context).close(); + } + + private String diff(HgCommandContext context, String revision) throws IOException { + DiffCommandRequest request = new DiffCommandRequest(); + request.setRevision(revision); + return diff(context, request); + } + + private String diff(HgCommandContext context, DiffCommandRequest request) throws IOException { + HgDiffCommand diff = new HgDiffCommand(context); + DiffCommandBuilder.OutputStreamConsumer consumer = diff.getDiffResult(request); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + consumer.accept(baos); + return baos.toString("UTF-8"); + } + +}