src/main/kotlin/de/uapcore/lightpit/vcs/VcsConnector.kt

Sat, 22 Jul 2023 11:32:27 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 22 Jul 2023 11:32:27 +0200
changeset 281
c15b9555ecf3
parent 280
12b898531d1a
permissions
-rw-r--r--

make vcs command timeout configurable

relates to #274

universe@280 1 package de.uapcore.lightpit.vcs
universe@280 2
universe@280 3 import java.nio.file.Path
universe@280 4 import java.util.concurrent.TimeUnit
universe@280 5
universe@280 6 abstract class VcsConnector(protected val path: String) {
universe@280 7 /**
universe@280 8 * Invokes the VCS binary with the given [args] and returns the output on stdout.
universe@280 9 */
universe@281 10 protected fun invokeCommand(
universe@281 11 vararg args: String,
universe@281 12 workingDir: Path = Path.of("."),
universe@281 13 timeout: Long = 30L
universe@281 14 ): VcsConnectorResult<String> {
universe@280 15 return try {
universe@280 16 val command = mutableListOf(path)
universe@280 17 command.addAll(args)
universe@280 18 val process = ProcessBuilder(command).directory(workingDir.toFile()).start()
universe@280 19 val stdout = String(process.inputStream.readAllBytes(), Charsets.UTF_8)
universe@281 20 if (process.waitFor(timeout, TimeUnit.SECONDS)) {
universe@280 21 if (process.exitValue() == 0) {
universe@280 22 VcsConnectorResult.Success(stdout)
universe@280 23 } else {
universe@280 24 VcsConnectorResult.Error("VCS process did not return successfully.")
universe@280 25 }
universe@280 26 } else {
universe@280 27 VcsConnectorResult.Error("VCS process did not return in time.")
universe@280 28 }
universe@280 29 } catch (e: Throwable) {
universe@280 30 VcsConnectorResult.Error("Error during process invocation: "+e.message)
universe@280 31 }
universe@280 32 }
universe@280 33
universe@280 34 /**
universe@280 35 * Takes a [commitLog] in format `::lpitref::{node}:{desc}` and parses commit references.
universe@280 36 * Supported references are (in this example, 47 is the issue ID):
universe@280 37 * - fixes #47
universe@280 38 * - fix #47
universe@280 39 * - closes #47
universe@280 40 * - close #47
universe@280 41 * - relates to #47
universe@280 42 */
universe@280 43 protected fun parseCommitRefs(commitLog: String): List<CommitRef> = buildList {
universe@280 44 val marker = "::lpitref::"
universe@280 45 var currentHash = ""
universe@280 46 var currentDesc = ""
universe@280 47 for (line in commitLog.split("\n")) {
universe@280 48 // see if current line contains a new log entry
universe@280 49 if (line.startsWith(marker)) {
universe@280 50 val head = line.substring(marker.length).split(':', limit = 2)
universe@280 51 currentHash = head[0]
universe@280 52 currentDesc = head[1]
universe@280 53 }
universe@280 54
universe@280 55 // skip possible preamble output
universe@280 56 if (currentHash.isEmpty()) continue
universe@280 57
universe@280 58 // scan the lines for commit references
universe@280 59 Regex("""(?:relates to|fix(?:es)?|close(?:es)?) #(\d+)""")
universe@280 60 .findAll(line)
universe@280 61 .map { it.groupValues[1] }
universe@280 62 .map { it.toIntOrNull() }
universe@280 63 .filterNotNull()
universe@280 64 .forEach { commitId -> add(CommitRef(currentHash, commitId, currentDesc)) }
universe@280 65 }
universe@280 66 }
universe@280 67 }

mercurial