From 7f3fa1b5e26dbeaa0680b64473c2ca93bc49d09b Mon Sep 17 00:00:00 2001 From: Steven van den Broek <30909373+Yvee1@users.noreply.github.com> Date: Thu, 16 Sep 2021 20:15:35 +0200 Subject: [PATCH] Use native git in GitArchiver if possible (#193) --- .../src/main/kotlin/GitArchiver.kt | 46 ++++------------- .../src/main/kotlin/JavaGit.kt | 36 ++++++++++++++ .../src/main/kotlin/NativeGit.kt | 49 +++++++++++++++++++ 3 files changed, 94 insertions(+), 37 deletions(-) create mode 100644 orx-jvm/orx-git-archiver/src/main/kotlin/JavaGit.kt create mode 100644 orx-jvm/orx-git-archiver/src/main/kotlin/NativeGit.kt diff --git a/orx-jvm/orx-git-archiver/src/main/kotlin/GitArchiver.kt b/orx-jvm/orx-git-archiver/src/main/kotlin/GitArchiver.kt index 74d13238..e11915bd 100644 --- a/orx-jvm/orx-git-archiver/src/main/kotlin/GitArchiver.kt +++ b/orx-jvm/orx-git-archiver/src/main/kotlin/GitArchiver.kt @@ -1,15 +1,14 @@ package org.openrndr.extra.gitarchiver import mu.KotlinLogging -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.api.errors.EmptyCommitException -import org.eclipse.jgit.lib.Constants -import org.eclipse.jgit.lib.Repository -import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.openrndr.AssetMetadata import org.openrndr.Extension import org.openrndr.Program -import java.io.File + +internal interface GitProvider { + fun commitChanges(commitMessage: String) + fun headReference() : String +} val logger = KotlinLogging.logger { } @@ -21,39 +20,13 @@ class GitArchiver : Extension { var autoCommitMessage = "auto commit" - private val repo = FileRepositoryBuilder().setGitDir(File("./.git")).build() - private val git = Git(repo) - - fun commitChanges() { - try { - git.commit().setAll(true).setAllowEmpty(false).setMessage(autoCommitMessage).call() - logger.info { "git repository is now at ${commitHash.take(7)}" } - } catch (e: EmptyCommitException) { - logger.info { "no changes" } - } - } - - fun tag(name: String): Boolean { - val existing = git.tagList().call().find { it.name == name } - if (existing != null) { - git.tag().setName(name).call() - } else { - logger.warn { "tag $name exists" } - } - return existing != null - } - - val commitHash: String - get() { - val id = repo.resolve(Constants.HEAD) - return id.name - } + private val git: GitProvider = if (nativeGitInstalled()) NativeGit() else JavaGit() override fun setup(program: Program) { val oldMetadataFunction = program.assetMetadata program.assetMetadata = { val oldMetadata = oldMetadataFunction() - val commitHash = this.commitHash.take(7) + val commitHash = git.headReference() program.assetProperties["git-commit-hash"] = commitHash AssetMetadata( oldMetadata.programName, @@ -63,13 +36,12 @@ class GitArchiver : Extension { program.requestAssets.listeners.add(0, { if (commitOnRequestAssets) { - commitChanges() + git.commitChanges(autoCommitMessage) } }) - if (commitOnRun) { - commitChanges() + git.commitChanges(autoCommitMessage) } } } \ No newline at end of file diff --git a/orx-jvm/orx-git-archiver/src/main/kotlin/JavaGit.kt b/orx-jvm/orx-git-archiver/src/main/kotlin/JavaGit.kt new file mode 100644 index 00000000..9123d6d8 --- /dev/null +++ b/orx-jvm/orx-git-archiver/src/main/kotlin/JavaGit.kt @@ -0,0 +1,36 @@ +package org.openrndr.extra.gitarchiver + +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.api.errors.EmptyCommitException +import org.eclipse.jgit.lib.Constants +import org.eclipse.jgit.storage.file.FileRepositoryBuilder +import java.io.File + +class JavaGit : GitProvider { + private val repo = FileRepositoryBuilder().setGitDir(File("./.git")).build() + private val git = Git(repo) + + override fun commitChanges(commitMessage: String) { + try { + git.commit().setAll(true).setAllowEmpty(false).setMessage(commitMessage).call() + logger.info { "git repository is now at ${headReference()}" } + } catch (e: EmptyCommitException) { + logger.info { "no changes" } + } + } + + override fun headReference() : String { + val id = repo.resolve(Constants.HEAD) + return id.name.take(7) + } + +// fun tag(name: String): Boolean { +// val existing = git.tagList().call().find { it.name == name } +// if (existing != null) { +// git.tag().setName(name).call() +// } else { +// logger.warn { "tag $name exists" } +// } +// return existing != null +// } +} \ No newline at end of file diff --git a/orx-jvm/orx-git-archiver/src/main/kotlin/NativeGit.kt b/orx-jvm/orx-git-archiver/src/main/kotlin/NativeGit.kt new file mode 100644 index 00000000..5de96e2e --- /dev/null +++ b/orx-jvm/orx-git-archiver/src/main/kotlin/NativeGit.kt @@ -0,0 +1,49 @@ +package org.openrndr.extra.gitarchiver + +import java.io.File +import java.io.IOException +import java.util.concurrent.TimeUnit + +private val dir = File(".") + +class NativeGit : GitProvider { + override fun commitChanges(commitMessage: String) { + val gitStatus = "git status --porcelain".runCommand(dir)!! + if (gitStatus.first.isNotBlank()){ + if (gitStatus.first.contains("Not a git repository")){ + logger.error { "Can't commit changes because the working directory is not a git repository" } + } else { + "git add .".runCommand(dir) + "git commit -m \"${commitMessage}\"".runCommand(dir) + logger.info { "git repository is now at ${headReference()}" } + } + } else { + logger.info { "no changes" } + } + } + + override fun headReference(): String { + return "git rev-parse --short HEAD".runCommand(dir)!!.first + } +} + +internal fun nativeGitInstalled(): Boolean { + return "git --version".runCommand(dir) != null +} + +// Adapted from https://stackoverflow.com/questions/35421699/how-to-invoke-external-command-from-within-kotlin-code +private fun String.runCommand(workingDir: File): Pair? { + try { + val parts = this.split("\\s".toRegex()) + val proc = ProcessBuilder(*parts.toTypedArray()) + .directory(workingDir) + .redirectOutput(ProcessBuilder.Redirect.PIPE) + .redirectError(ProcessBuilder.Redirect.PIPE) + .start() + + proc.waitFor(60, TimeUnit.MINUTES) + return Pair(proc.inputStream.bufferedReader().readText(), proc.errorStream.bufferedReader().readText()) + } catch(e: IOException) { + return null + } +} \ No newline at end of file