From 65b06119a8d493448cb9731db8f958c77c42c7ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wawrzyk?= Date: Fri, 12 May 2023 17:05:34 +0200 Subject: [PATCH] Do not fail if nothing to commit in shutdown hook - just warn --- .../bazelsteward/app/PullRequestManager.kt | 2 +- .../bazelsteward/core/common/CommandRunner.kt | 28 ++++++++++++------- .../bazelsteward/core/common/GitClient.kt | 8 ++++-- .../bazelsteward/core/common/GitOperations.kt | 7 ++++- .../bazelsteward/e2e/PostUpdateHookTest.kt | 4 +-- .../bazel/rules/BazelRulesExtractor.kt | 4 +-- .../bazelsteward/maven/MavenDataExtractor.kt | 2 +- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/app/src/main/kotlin/org/virtuslab/bazelsteward/app/PullRequestManager.kt b/app/src/main/kotlin/org/virtuslab/bazelsteward/app/PullRequestManager.kt index 8c855a77..1fe5e3e4 100644 --- a/app/src/main/kotlin/org/virtuslab/bazelsteward/app/PullRequestManager.kt +++ b/app/src/main/kotlin/org/virtuslab/bazelsteward/app/PullRequestManager.kt @@ -75,7 +75,7 @@ data class PullRequestManager( if (hook.commands.isNotEmpty()) { hook.commands.forEach { Thread.sleep(1000) - CommandRunner.run(listOf("sh", "-c", it), workspaceRoot) + CommandRunner.runForOutput(listOf("sh", "-c", it), workspaceRoot) } git.commitSelectedFiles(hook.filesToCommit, hook.commitMessage) if (hook.runFor == HookRunFor.Commit) { diff --git a/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/CommandRunner.kt b/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/CommandRunner.kt index 0ad8d71c..f5821d2d 100644 --- a/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/CommandRunner.kt +++ b/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/CommandRunner.kt @@ -9,13 +9,27 @@ import java.nio.file.Path private val logger = KotlinLogging.logger {} class CommandRunner { + data class Result(val exitCode: Int, val stdout: String, val stderr: String) { + val isSuccess: Boolean + get() = exitCode == 0 + } companion object { - suspend fun run(directory: Path, vararg command: String): String { - return run(command.toList(), directory) + suspend fun runForOutput(directory: Path, vararg command: String): String { + return runForOutput(command.toList(), directory) + } + + suspend fun runForOutput(command: List, directory: Path): String { + val result = run(command, directory) + if (result.isSuccess) { + return result.stdout + } else { + val message = "${command.joinToString(" ")}\n${result.stdout}\n${result.stderr}" + throw RuntimeException(message) + } } - suspend fun run(command: List, directory: Path): String { + suspend fun run(command: List, directory: Path): Result { logger.info { command.joinToString(" ") { if (it.contains(" ")) """"$it"""" else it } } return withContext(Dispatchers.IO) { val process = ProcessBuilder(command).directory(directory.toFile()).start() @@ -23,13 +37,7 @@ class CommandRunner { val stdout = process.inputStream.bufferedReader().use { it.readText() } val stderr = process.errorStream.bufferedReader().use { it.readText() } - if (process.exitValue() == 0) { - stdout - } else { - throw RuntimeException( - "${command.joinToString(" ")}\n$stdout\n$stderr", - ) - } + Result(process.exitValue(), stdout, stderr) } } } diff --git a/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitClient.kt b/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitClient.kt index 19a5efe7..59f2115b 100644 --- a/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitClient.kt +++ b/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitClient.kt @@ -5,7 +5,7 @@ import java.nio.file.Path class GitClient(private val repositoryRoot: Path) { private val quiet = "--quiet" - private val git = runBlocking { CommandRunner.run(listOf("sh", "-c", "which git"), repositoryRoot).trim() } + private val git = runBlocking { CommandRunner.runForOutput(listOf("sh", "-c", "which git"), repositoryRoot).trim() } suspend fun checkout(target: String, newBranch: Boolean = false) { val b = if (newBranch) "-b" else null @@ -76,7 +76,11 @@ class GitClient(private val repositoryRoot: Path) { suspend fun run(vararg gitArgs: String?): String = run(gitArgs.toList()) suspend fun run(gitArgs: List): String { - return CommandRunner.run(listOf(git) + gitArgs.filterNotNull(), repositoryRoot) + return CommandRunner.runForOutput(listOf(git) + gitArgs.filterNotNull(), repositoryRoot) + } + + suspend fun runForResult(vararg args: String): CommandRunner.Result { + return CommandRunner.run(listOf(git) + args, repositoryRoot) } data class GitAuthor(val name: String, val email: String) diff --git a/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitOperations.kt b/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitOperations.kt index 4d350342..fcb1ff40 100644 --- a/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitOperations.kt +++ b/core/src/main/kotlin/org/virtuslab/bazelsteward/core/common/GitOperations.kt @@ -77,7 +77,12 @@ class GitOperations(workspaceRoot: Path, private val baseBranch: String) { suspend fun commitSelectedFiles(filesToCommit: List, commitMessage: String) { git.add(filesToCommit) - git.commit(commitMessage) + val noChanges = git.runForResult("git", "diff", "--quiet", "--exit-code", "--cached").isSuccess + if (noChanges) { + logger.warn { "No changes to commit" } + } else { + git.commit(commitMessage) + } } suspend fun squashLastTwoCommits() { diff --git a/e2e/src/test/kotlin/org/virtuslab/bazelsteward/e2e/PostUpdateHookTest.kt b/e2e/src/test/kotlin/org/virtuslab/bazelsteward/e2e/PostUpdateHookTest.kt index cd14d6e4..6f103206 100644 --- a/e2e/src/test/kotlin/org/virtuslab/bazelsteward/e2e/PostUpdateHookTest.kt +++ b/e2e/src/test/kotlin/org/virtuslab/bazelsteward/e2e/PostUpdateHookTest.kt @@ -23,7 +23,7 @@ class PostUpdateHookTest : E2EBase() { val git = GitClient(localRoot) runBlocking { git.checkout("bazel-steward/io.arrow-kt/arrow-core/1.1.5") - val validationCommandOutput = CommandRunner.run( + val validationCommandOutput = CommandRunner.runForOutput( localRoot, "sh", "-c", @@ -52,7 +52,7 @@ class PostUpdateHookTest : E2EBase() { val git = GitClient(localRoot) runBlocking { git.checkout("bazel-steward/io.arrow-kt/arrow-core/1.1.5") - val validationCommandOutput = CommandRunner.run( + val validationCommandOutput = CommandRunner.runForOutput( localRoot, "sh", "-c", diff --git a/kinds/bazel/rules/src/main/kotlin/org/virtuslab/bazelsteward/bazel/rules/BazelRulesExtractor.kt b/kinds/bazel/rules/src/main/kotlin/org/virtuslab/bazelsteward/bazel/rules/BazelRulesExtractor.kt index 54be0195..4c2b08a2 100644 --- a/kinds/bazel/rules/src/main/kotlin/org/virtuslab/bazelsteward/bazel/rules/BazelRulesExtractor.kt +++ b/kinds/bazel/rules/src/main/kotlin/org/virtuslab/bazelsteward/bazel/rules/BazelRulesExtractor.kt @@ -69,10 +69,10 @@ class BazelRulesExtractor { """.trimMargin(), ) // solution from https://github.com/bazelbuild/bazel/issues/6377#issuecomment-1237791008 - CommandRunner.run(workspaceRoot, "bazel", "build", "@all_external_repositories//:result.json") + CommandRunner.runForOutput(workspaceRoot, "bazel", "build", "@all_external_repositories//:result.json") workspaceFilePath.writeText(originalContent) deleteFile(tempFileForBzl) - val bazelPath = CommandRunner.run(workspaceRoot, "bazel", "info", "output_base").trim() + val bazelPath = CommandRunner.runForOutput(workspaceRoot, "bazel", "info", "output_base").trim() val resultFilePath = Path(bazelPath).resolve("external/all_external_repositories/result.json") if (!resultFilePath.exists()) { throw RuntimeException("Failed to find a file: $resultFilePath") diff --git a/kinds/maven/src/main/kotlin/org/virtuslab/bazelsteward/maven/MavenDataExtractor.kt b/kinds/maven/src/main/kotlin/org/virtuslab/bazelsteward/maven/MavenDataExtractor.kt index e3661397..3555b1b0 100644 --- a/kinds/maven/src/main/kotlin/org/virtuslab/bazelsteward/maven/MavenDataExtractor.kt +++ b/kinds/maven/src/main/kotlin/org/virtuslab/bazelsteward/maven/MavenDataExtractor.kt @@ -18,7 +18,7 @@ class MavenDataExtractor(private val workspaceRoot: Path) { } private suspend fun extractFromFile(fileName: String): List = withContext(Dispatchers.IO) { - val xml = CommandRunner.run( + val xml = CommandRunner.runForOutput( workspaceRoot, "bazel", "query",