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

changeset 280
12b898531d1a
child 281
c15b9555ecf3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/kotlin/de/uapcore/lightpit/vcs/VcsConnector.kt	Tue Jul 18 18:05:49 2023 +0200
@@ -0,0 +1,63 @@
+package de.uapcore.lightpit.vcs
+
+import java.nio.file.Path
+import java.util.concurrent.TimeUnit
+
+abstract class VcsConnector(protected val path: String) {
+    /**
+     * Invokes the VCS binary with the given [args] and returns the output on stdout.
+     */
+    protected fun invokeCommand(workingDir: Path, vararg args : String): VcsConnectorResult<String> {
+        return try {
+            val command = mutableListOf(path)
+            command.addAll(args)
+            val process = ProcessBuilder(command).directory(workingDir.toFile()).start()
+            val stdout = String(process.inputStream.readAllBytes(), Charsets.UTF_8)
+            if (process.waitFor(30, TimeUnit.SECONDS)) {
+                if (process.exitValue() == 0) {
+                    VcsConnectorResult.Success(stdout)
+                } else {
+                    VcsConnectorResult.Error("VCS process did not return successfully.")
+                }
+            } else {
+                VcsConnectorResult.Error("VCS process did not return in time.")
+            }
+        } catch (e: Throwable) {
+            VcsConnectorResult.Error("Error during process invocation: "+e.message)
+        }
+    }
+
+    /**
+     * Takes a [commitLog] in format `::lpitref::{node}:{desc}` and parses commit references.
+     * Supported references are (in this example, 47 is the issue ID):
+     *  - fixes #47
+     *  - fix #47
+     *  - closes #47
+     *  - close #47
+     *  - relates to #47
+     */
+    protected fun parseCommitRefs(commitLog: String): List<CommitRef> = buildList {
+        val marker = "::lpitref::"
+        var currentHash = ""
+        var currentDesc = ""
+        for (line in commitLog.split("\n")) {
+            // see if current line contains a new log entry
+            if (line.startsWith(marker)) {
+                val head = line.substring(marker.length).split(':', limit = 2)
+                currentHash = head[0]
+                currentDesc = head[1]
+            }
+
+            // skip possible preamble output
+            if (currentHash.isEmpty()) continue
+
+            // scan the lines for commit references
+            Regex("""(?:relates to|fix(?:es)?|close(?:es)?) #(\d+)""")
+                .findAll(line)
+                .map { it.groupValues[1] }
+                .map { it.toIntOrNull() }
+                .filterNotNull()
+                .forEach { commitId -> add(CommitRef(currentHash, commitId, currentDesc)) }
+        }
+    }
+}
\ No newline at end of file

mercurial