diff -r d73537b925af -r 12b898531d1a src/main/kotlin/de/uapcore/lightpit/vcs/HgConnector.kt --- a/src/main/kotlin/de/uapcore/lightpit/vcs/HgConnector.kt Mon Jul 17 14:45:42 2023 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/vcs/HgConnector.kt Tue Jul 18 18:05:49 2023 +0200 @@ -26,29 +26,56 @@ package de.uapcore.lightpit.vcs -import java.util.concurrent.TimeUnit +import java.nio.file.Files +import java.nio.file.Path +import kotlin.io.path.ExperimentalPathApi +import kotlin.io.path.deleteRecursively /** * A connector for Mercurial repositories. * * @param path the path to the Mercurial binary */ -class HgConnector(private val path: String) { +class HgConnector(path: String) : VcsConnector(path) { /** * Checks, if the specified binary is available and executable. */ fun checkAvailability(): Boolean { - return try { - val process = ProcessBuilder(path, "--version").start() - val versionInfo = String(process.inputStream.readAllBytes(), Charsets.UTF_8) - if (process.waitFor(10, TimeUnit.SECONDS)) { - versionInfo.contains("Mercurial") - } else { - false - } - } catch (_: Throwable) { - false + return when (val versionInfo = invokeCommand(Path.of("."), "--version")) { + is VcsConnectorResult.Success -> versionInfo.content.contains("Mercurial") + else -> false } } + + /** + * Reads the commit log and parses every reference to an issue. + * + * The [pathOrUrl] must be a valid path or URL recognized by the VCS binary. + * Currently, no authentication is supported and the repository must therefore be publicly readable. + */ + @OptIn(ExperimentalPathApi::class) + fun readCommitLog(pathOrUrl: String): VcsConnectorResult> { + val tmpDir = try { + Files.createTempDirectory("lightpit-vcs-") + } catch (e: Throwable) { + return VcsConnectorResult.Error("Creating temporary directory for VCS connection failed: " + e.message) + } + val init = invokeCommand(tmpDir, "init") + if (init is VcsConnectorResult.Error) { + return init + } + + val commitLogContent = when (val result = invokeCommand( + tmpDir, "incoming", pathOrUrl, "-n", "--template", "::lpitref::{node}:{desc}\\n" + )) { + is VcsConnectorResult.Error -> return result + is VcsConnectorResult.Success -> result.content + } + + val commitRefs = parseCommitRefs(commitLogContent) + + tmpDir.deleteRecursively() + return VcsConnectorResult.Success(commitRefs) + } } \ No newline at end of file