diff --git a/src/main/kotlin/de/hoennig/werkator/commands/InitCommand.kt b/src/main/kotlin/de/hoennig/werkator/commands/InitCommand.kt index a824341..f3c86f7 100644 --- a/src/main/kotlin/de/hoennig/werkator/commands/InitCommand.kt +++ b/src/main/kotlin/de/hoennig/werkator/commands/InitCommand.kt @@ -297,20 +297,25 @@ class InitCommand( * already loadable (re-running `init --systemd` on an installed instance); during * the very first bootstrap they stay unset and the defaults (no directives) apply. */ - private fun loadedSystemdConfig(): de.hoennig.werkator.config.SystemdConfig = loadedServerConfig().systemd + private fun loadedSystemdConfig(root: Path): de.hoennig.werkator.config.SystemdConfig = loadedServerConfig(root).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 /** + * Read from the repository root like every other file this command touches — the + * layers sit there, not in whatever directory the process happens to run in, and + * an applied fragment must reach the generated unit even when `init` is invoked + * from a subdirectory. + * * 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(root: Path): de.hoennig.werkator.config.ServerConfig = cachedServerConfig ?: run { try { - configLoader.load(Paths.get(".")).server + configLoader.load(root).server } 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") @@ -340,8 +345,8 @@ class InitCommand( javaExecutable = javaExecutableResolver(), jarPath = jarPath, envFile = envFile, - memoryMax = loadedSystemdConfig().memoryMax, - tasksMax = loadedSystemdConfig().tasksMax, + memoryMax = loadedSystemdConfig(root).memoryMax, + tasksMax = loadedSystemdConfig(root).tasksMax, ), ) println("created ${unitFile.toFile().relativeTo(normalizedWorkingDir.toFile())}") @@ -364,7 +369,7 @@ class InitCommand( // generated host integration like the units: only meaningful behind a web // frontend, so it needs a public base URL; unused elsewhere and harmless - val server = loadedServerConfig() + val server = loadedServerConfig(root) if (server.publicBaseUrl.isNotBlank()) { val htaccessFile = werkatorDir.resolve(SystemdServiceFiles.HTACCESS_NAME) htaccessFile.toFile().writeText(SystemdServiceFiles.htaccessContent(server.port)) diff --git a/src/test/kotlin/de/hoennig/werkator/commands/InitCommandTest.kt b/src/test/kotlin/de/hoennig/werkator/commands/InitCommandTest.kt index 2d16448..a2f289f 100644 --- a/src/test/kotlin/de/hoennig/werkator/commands/InitCommandTest.kt +++ b/src/test/kotlin/de/hoennig/werkator/commands/InitCommandTest.kt @@ -253,6 +253,29 @@ class InitCommandTest : FunSpec() { initCommand.run() } + test("--systemd reads the configuration from the repository root, not the current directory") { + val tempDir = Files.createTempDirectory("werkator-init-test") + // written before the run, so `init` keeps it instead of creating a template + tempDir.resolve(".werkator.yml").toFile().writeText( + "server:\n publicBaseUrl: \"https://werkator.example.org/\"\n port: 18099\n", + ) + initCommand.workingDir = tempDir + initCommand.systemd = true + initCommand.jarPathResolver = { Paths.get("/home/ci/bin/werkator.jar") } + initCommand.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" + + initCommand.run() + + // the host integration is generated only when the root's config has a public base URL + val htaccess = tempDir.resolve(".git/werkator/${SystemdServiceFiles.HTACCESS_NAME}") + htaccess.toFile().shouldExist() + htaccess.toFile().readText() shouldContain "18099" + tempDir.resolve(".git/werkator/${SystemdServiceFiles.MAINTENANCE_PAGE_NAME}").toFile().shouldExist() + } + test("--systemd warns once when the effective configuration cannot be loaded") { val tempDir = Files.createTempDirectory("werkator-init-test") val brokenLoader = mockk()