init reads its configuration from the repository root, and says so when it cannot #22

Closed
mi wants to merge 3 commits from mi/init-config-root AGit into main
2 changed files with 40 additions and 5 deletions
Showing only changes of commit 7fd473b88b - Show all commits
@@ -48,6 +48,7 @@ class InitCommand(
internal var javaExecutableResolver: () -> Path = { Paths.get(System.getProperty("java.home"), "bin", "java") } internal var javaExecutableResolver: () -> Path = { Paths.get(System.getProperty("java.home"), "bin", "java") }
override fun run() { override fun run() {
cachedServerConfig = null
val normalizedWorkingDir = workingDir.toAbsolutePath().normalize() val normalizedWorkingDir = workingDir.toAbsolutePath().normalize()
val root = val root =
try { try {
@@ -298,12 +299,24 @@ class InitCommand(
*/ */
private fun loadedSystemdConfig(): de.hoennig.werkator.config.SystemdConfig = loadedServerConfig().systemd private fun loadedSystemdConfig(): de.hoennig.werkator.config.SystemdConfig = loadedServerConfig().systemd
/** Loaded once per run, so a broken configuration is reported once and not per caller. */
private var cachedServerConfig: de.hoennig.werkator.config.ServerConfig? = null
/**
* A configuration error here is not fatal — the units are still generated with defaults —
* but it must not pass for "nothing configured": without the warning a broken `.werkator.yml`
* looks exactly like an unset `publicBaseUrl` and the host integration is skipped silently.
*/
private fun loadedServerConfig(): de.hoennig.werkator.config.ServerConfig = private fun loadedServerConfig(): de.hoennig.werkator.config.ServerConfig =
cachedServerConfig ?: run {
try { try {
configLoader.load(Paths.get(".")).server configLoader.load(Paths.get(".")).server
} catch (_: Exception) { } catch (e: Exception) {
println("Warning: the effective configuration could not be loaded (${e.message})")
println(" continuing with default server settings — check the generated unit and host files")
de.hoennig.werkator.config de.hoennig.werkator.config
.ServerConfig() .ServerConfig()
}.also { cachedServerConfig = it }
} }
private fun createSystemdFiles( private fun createSystemdFiles(
@@ -252,5 +252,27 @@ class InitCommandTest : FunSpec() {
// This should not throw IllegalArgumentException // This should not throw IllegalArgumentException
initCommand.run() initCommand.run()
} }
test("--systemd warns once when the effective configuration cannot be loaded") {
val tempDir = Files.createTempDirectory("werkator-init-test")
val brokenLoader = mockk<de.hoennig.werkator.config.ConfigLoader>()
every { brokenLoader.load(any()) } throws IllegalStateException("gitea.owner is required")
val command = InitCommand(gitService, brokenLoader)
command.workingDir = tempDir
command.systemd = true
command.jarPathResolver = { Paths.get("/home/ci/bin/werkator.jar") }
command.javaExecutableResolver = { Paths.get("/usr/bin/java") }
every { gitService.getTopLevel(tempDir) } returns tempDir
every { gitService.getOriginUrl(tempDir) } returns "https://git.example.org/my-org/my-repo.git"
val console = captureConsole { command.run() }
console.stdout shouldContain "gitea.owner is required"
// the three readers of the configuration must not repeat the warning
console.stdout.windowed("Warning:".length).count { it == "Warning:" } shouldBe 1
// the units are still written with the defaults
tempDir.resolve(".git/werkator/${SystemdServiceFiles.unitName(tempDir)}").toFile().shouldExist()
}
} }
} }