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

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

mercurial