diff --git a/CHANGELOG.md b/CHANGELOG.md index 42dc158a24..58c4483f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Tags can now be added and deleted through the ui ([#1456](https://github.com/scm-manager/scm-manager/pull/1456)) - The ui now displays tag signatures ([#1456](https://github.com/scm-manager/scm-manager/pull/1456)) - Repository import via URL for git ([#1460](https://github.com/scm-manager/scm-manager/pull/1460)) +- Repository import via URL for hg ([#1463](https://github.com/scm-manager/scm-manager/pull/1463)) ### Changed - Send mercurial hook callbacks over separate tcp socket instead of http ([#1416](https://github.com/scm-manager/scm-manager/pull/1416)) 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 index 5169d3c389..2679a3473d 100644 --- 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 @@ -33,6 +33,7 @@ import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.RepositoryProvider; import java.io.Closeable; +import java.io.File; //~--- JDK imports ------------------------------------------------------------ @@ -71,6 +72,10 @@ public class HgCommandContext implements Closeable, RepositoryProvider { return handler.getConfig(); } + public File getDirectory() { + return handler.getDirectory(scmRepository.getId()); + } + public sonia.scm.repository.Repository getScmRepository() { return scmRepository; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java index e5cdbd957b..8974fb88ed 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java @@ -24,69 +24,89 @@ package sonia.scm.repository.spi; -//~--- non-JDK imports -------------------------------------------------------- - import com.aragost.javahg.Changeset; import com.aragost.javahg.commands.ExecutionException; +import com.google.common.base.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.ContextEntry; +import sonia.scm.io.INIConfiguration; +import sonia.scm.io.INIConfigurationReader; +import sonia.scm.io.INIConfigurationWriter; +import sonia.scm.io.INISection; import sonia.scm.repository.HgRepositoryHandler; -import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.api.ImportFailedException; import sonia.scm.repository.api.PullResponse; +import java.io.File; import java.io.IOException; -import java.util.Collections; +import java.net.URI; import java.util.List; -//~--- JDK imports ------------------------------------------------------------ +public class HgPullCommand extends AbstractHgPushOrPullCommand implements PullCommand { -/** - * - * @author Sebastian Sdorra - */ -public class HgPullCommand extends AbstractHgPushOrPullCommand - implements PullCommand -{ + private static final Logger LOG = LoggerFactory.getLogger(HgPullCommand.class); + private static final String AUTH_SECTION = "auth"; - /** Field description */ - private static final Logger logger = - LoggerFactory.getLogger(HgPullCommand.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * @param handler - * @param context - */ - public HgPullCommand(HgRepositoryHandler handler, HgCommandContext context) - { + public HgPullCommand(HgRepositoryHandler handler, HgCommandContext context) { super(handler, context); } - //~--- methods -------------------------------------------------------------- - @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"java:S3252"}) public PullResponse pull(PullCommandRequest request) - throws IOException - { + throws IOException { String url = getRemoteUrl(request); - logger.debug("pull changes from {} to {}", url, getRepository().getId()); + LOG.debug("pull changes from {} to {}", url, getContext().getScmRepository().getId()); - List result = Collections.EMPTY_LIST; + List result; - try - { - result = com.aragost.javahg.commands.PullCommand.on(open()).execute(url); + if (!Strings.isNullOrEmpty(request.getUsername()) && !Strings.isNullOrEmpty(request.getPassword())) { + addAuthenticationConfig(request, url); } - catch (ExecutionException ex) - { - throw new InternalRepositoryException(getRepository(), "could not execute push command", ex); + + try { + result = com.aragost.javahg.commands.PullCommand.on(open()).execute(url); + } catch (ExecutionException ex) { + throw new ImportFailedException(ContextEntry.ContextBuilder.entity(getRepository()).build(), "could not execute pull command", ex); + } finally { + removeAuthenticationConfig(); } return new PullResponse(result.size()); } + + public void addAuthenticationConfig(PullCommandRequest request, String url) throws IOException { + INIConfiguration ini = readIniConfiguration(); + INISection authSection = ini.getSection(AUTH_SECTION); + if (authSection == null) { + authSection = new INISection(AUTH_SECTION); + ini.addSection(authSection); + } + URI parsedUrl = URI.create(url); + authSection.setParameter("import.prefix", parsedUrl.getHost()); + authSection.setParameter("import.schemes", parsedUrl.getScheme()); + authSection.setParameter("import.username", request.getUsername()); + authSection.setParameter("import.password", request.getPassword()); + writeIniConfiguration(ini); + } + + public void removeAuthenticationConfig() throws IOException { + INIConfiguration ini = readIniConfiguration(); + ini.removeSection(AUTH_SECTION); + writeIniConfiguration(ini); + } + + public INIConfiguration readIniConfiguration() throws IOException { + return new INIConfigurationReader().read(getHgrcFile()); + } + + public void writeIniConfiguration(INIConfiguration ini) throws IOException { + new INIConfigurationWriter().write(ini, getHgrcFile()); + } + + public File getHgrcFile() { + return new File(getContext().getDirectory(), HgRepositoryHandler.PATH_HGRC); + } }