24 * |
24 * |
25 */ |
25 */ |
26 |
26 |
27 package de.uapcore.lightpit.vcs |
27 package de.uapcore.lightpit.vcs |
28 |
28 |
29 import java.util.concurrent.TimeUnit |
29 import java.nio.file.Files |
|
30 import java.nio.file.Path |
|
31 import kotlin.io.path.ExperimentalPathApi |
|
32 import kotlin.io.path.deleteRecursively |
30 |
33 |
31 /** |
34 /** |
32 * A connector for Mercurial repositories. |
35 * A connector for Mercurial repositories. |
33 * |
36 * |
34 * @param path the path to the Mercurial binary |
37 * @param path the path to the Mercurial binary |
35 */ |
38 */ |
36 class HgConnector(private val path: String) { |
39 class HgConnector(path: String) : VcsConnector(path) { |
37 |
40 |
38 /** |
41 /** |
39 * Checks, if the specified binary is available and executable. |
42 * Checks, if the specified binary is available and executable. |
40 */ |
43 */ |
41 fun checkAvailability(): Boolean { |
44 fun checkAvailability(): Boolean { |
42 return try { |
45 return when (val versionInfo = invokeCommand(Path.of("."), "--version")) { |
43 val process = ProcessBuilder(path, "--version").start() |
46 is VcsConnectorResult.Success -> versionInfo.content.contains("Mercurial") |
44 val versionInfo = String(process.inputStream.readAllBytes(), Charsets.UTF_8) |
47 else -> false |
45 if (process.waitFor(10, TimeUnit.SECONDS)) { |
|
46 versionInfo.contains("Mercurial") |
|
47 } else { |
|
48 false |
|
49 } |
|
50 } catch (_: Throwable) { |
|
51 false |
|
52 } |
48 } |
53 } |
49 } |
|
50 |
|
51 /** |
|
52 * Reads the commit log and parses every reference to an issue. |
|
53 * |
|
54 * The [pathOrUrl] must be a valid path or URL recognized by the VCS binary. |
|
55 * Currently, no authentication is supported and the repository must therefore be publicly readable. |
|
56 */ |
|
57 @OptIn(ExperimentalPathApi::class) |
|
58 fun readCommitLog(pathOrUrl: String): VcsConnectorResult<List<CommitRef>> { |
|
59 val tmpDir = try { |
|
60 Files.createTempDirectory("lightpit-vcs-") |
|
61 } catch (e: Throwable) { |
|
62 return VcsConnectorResult.Error("Creating temporary directory for VCS connection failed: " + e.message) |
|
63 } |
|
64 val init = invokeCommand(tmpDir, "init") |
|
65 if (init is VcsConnectorResult.Error) { |
|
66 return init |
|
67 } |
|
68 |
|
69 val commitLogContent = when (val result = invokeCommand( |
|
70 tmpDir, "incoming", pathOrUrl, "-n", "--template", "::lpitref::{node}:{desc}\\n" |
|
71 )) { |
|
72 is VcsConnectorResult.Error -> return result |
|
73 is VcsConnectorResult.Success -> result.content |
|
74 } |
|
75 |
|
76 val commitRefs = parseCommitRefs(commitLogContent) |
|
77 |
|
78 tmpDir.deleteRecursively() |
|
79 return VcsConnectorResult.Success(commitRefs) |
|
80 } |
54 } |
81 } |