diff --git a/pom.xml b/pom.xml
index 4169ad1..a1d4228 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
alfred
web
- 0.0.1-SNAPSHOT
+ 0.0.2-SNAPSHOT
web
Alfred CI
diff --git a/src/main/kotlin/alfred/web/WebApplication.kt b/src/main/kotlin/alfred/web/WebApplication.kt
index d5c276e..f2e88dd 100644
--- a/src/main/kotlin/alfred/web/WebApplication.kt
+++ b/src/main/kotlin/alfred/web/WebApplication.kt
@@ -2,8 +2,10 @@ package alfred.web
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
+import org.springframework.scheduling.annotation.EnableScheduling
@SpringBootApplication
+@EnableScheduling
open class WebApplication
fun main(args: Array) {
diff --git a/src/main/kotlin/alfred/web/core/AlfredHome.kt b/src/main/kotlin/alfred/web/core/AlfredHome.kt
index 6b77174..8b4a3bb 100644
--- a/src/main/kotlin/alfred/web/core/AlfredHome.kt
+++ b/src/main/kotlin/alfred/web/core/AlfredHome.kt
@@ -1,9 +1,22 @@
package alfred.web.core
import alfred.web.core.build.BuildId
+import alfred.web.core.build.LogFile
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
+import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
+import java.nio.file.Files
+import java.nio.file.Files.createFile
import java.nio.file.Paths
+import java.time.Instant
+import java.time.LocalDateTime
+import java.time.format.DateTimeFormatter
+import java.time.temporal.ChronoUnit
+import java.util.concurrent.TimeUnit
+import kotlin.io.path.deleteIfExists
+import kotlin.io.path.getLastModifiedTime
@Service
class AlfredHome(
@@ -13,10 +26,33 @@ class AlfredHome(
val homePath = Paths.get(home)
- fun logsDir() =
- homePath.resolve("logs")
+ val logsDir = homePath.resolve("logs")
fun buildConfig(buildId: BuildId) =
homePath.resolve("builds/${buildId}.properties")
+ fun newLogFile(build: BuildId): LogFile {
+ val nowStr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
+ val fileName = "$build.$nowStr.log"
+
+ logsDir.toFile().mkdir()
+
+ val logFilePath = logsDir.resolve(fileName)
+ return LogFile(createFile(logFilePath).toFile())
+ }
+
+ @Scheduled(fixedRate = 1, initialDelay = 1, timeUnit = TimeUnit.HOURS)
+ fun cleanup() {
+ val maxAge = Instant.now().minus(7L, ChronoUnit.DAYS)
+
+ Files.list(logsDir)
+ .filter { it.getLastModifiedTime().toInstant().isBefore(maxAge) }
+ .forEach {
+ logger.info("log file $it gets old, deleting")
+ it.deleteIfExists()
+ }
+ }
+
+ val logger: Logger = LoggerFactory.getLogger(this::class.java)
+
}
diff --git a/src/main/kotlin/alfred/web/core/Handles.kt b/src/main/kotlin/alfred/web/core/Handles.kt
index 96c3a7a..b5f3acb 100644
--- a/src/main/kotlin/alfred/web/core/Handles.kt
+++ b/src/main/kotlin/alfred/web/core/Handles.kt
@@ -1,9 +1,12 @@
package alfred.web.core
import alfred.web.core.build.BuildId
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
import java.time.Instant
+import java.util.concurrent.TimeUnit
@Service
class Handles {
@@ -25,11 +28,18 @@ class Handles {
)
}
- @Scheduled(fixedDelay = 60_000)
+ @Scheduled(fixedRate = 1, initialDelay = 1, timeUnit = TimeUnit.MINUTES)
fun cleanup() {
- handles.removeIf { !it.handle.isAlive }
+ handles
+ .filter { !it.handle.isAlive }
+ .forEach {
+ logger.info("handle for command '${it.command}' is not alive and too old, removing")
+ }
+ handles
+ .removeIf { !it.handle.isAlive }
}
+ val logger: Logger = LoggerFactory.getLogger(this::class.java)
}
data class Handle(
diff --git a/src/main/kotlin/alfred/web/core/build/Builds.kt b/src/main/kotlin/alfred/web/core/build/Builds.kt
index 082eedb..6a2856b 100644
--- a/src/main/kotlin/alfred/web/core/build/Builds.kt
+++ b/src/main/kotlin/alfred/web/core/build/Builds.kt
@@ -7,9 +7,6 @@ import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import org.springframework.web.bind.annotation.ResponseStatus
-import java.nio.file.Files.createFile
-import java.time.LocalDateTime
-import java.time.format.DateTimeFormatter
import java.util.*
@Service
@@ -41,17 +38,6 @@ class Builds(
return props.toBuildConfig(env)
}
- fun createLogFile(build: BuildId): LogFile {
- val nowStr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
- val fileName = "$build.$nowStr.log"
-
- val logsDir = alfredHome.logsDir()
- logsDir.toFile().mkdir()
-
- val logFilePath = logsDir.resolve(fileName)
- return LogFile(createFile(logFilePath).toFile())
- }
-
}
private fun Properties.toBuildConfig(env: Map) =
diff --git a/src/main/kotlin/alfred/web/core/build/LogFile.kt b/src/main/kotlin/alfred/web/core/build/LogFile.kt
index 97e55b9..34ac3d9 100644
--- a/src/main/kotlin/alfred/web/core/build/LogFile.kt
+++ b/src/main/kotlin/alfred/web/core/build/LogFile.kt
@@ -11,7 +11,7 @@ import kotlin.text.lines
import kotlin.text.trim
class LogFile(
- val backingFile: File
+ val backingFile: File,
) {
val logger: Logger = LoggerFactory.getLogger(this::class.java)
diff --git a/src/main/kotlin/alfred/web/core/runner/GitRunner.kt b/src/main/kotlin/alfred/web/core/runner/GitRunner.kt
index 4401a5a..497ea26 100644
--- a/src/main/kotlin/alfred/web/core/runner/GitRunner.kt
+++ b/src/main/kotlin/alfred/web/core/runner/GitRunner.kt
@@ -1,5 +1,6 @@
package alfred.web.core.runner
+import alfred.web.core.AlfredHome
import alfred.web.core.build.BuildContext
import alfred.web.core.build.BuildId
import alfred.web.core.build.Builds
@@ -23,7 +24,8 @@ class GitRunner(
val workspaces: Workspaces,
val eventPublisher: ApplicationEventPublisher,
val git: Git,
- val script: Script
+ val script: Script,
+ val alfredHome: AlfredHome
) {
val scriptsDir = ".alfred"
@@ -32,7 +34,7 @@ class GitRunner(
fun run(buildId: BuildId, rev: String): ProcessInfo {
val config = builds.buildConfig(buildId)
- val logFile = builds.createLogFile(buildId)
+ val logFile = alfredHome.newLogFile(buildId)
logger.info("preparing process for build $buildId")
logger.info("log file: ${logFile.backingFile.absolutePath}")
diff --git a/src/main/kotlin/alfred/web/core/runner/ScriptRunner.kt b/src/main/kotlin/alfred/web/core/runner/ScriptRunner.kt
index 8d2beba..c0f43e4 100644
--- a/src/main/kotlin/alfred/web/core/runner/ScriptRunner.kt
+++ b/src/main/kotlin/alfred/web/core/runner/ScriptRunner.kt
@@ -1,5 +1,6 @@
package alfred.web.core.runner
+import alfred.web.core.AlfredHome
import alfred.web.core.build.*
import alfred.web.core.event.BuildFinished
import alfred.web.core.process.Script
@@ -14,12 +15,13 @@ class ScriptRunner(
val builds: Builds,
val workspaces: Workspaces,
val eventPublisher: ApplicationEventPublisher,
- val script: Script
+ val script: Script,
+ val alfredHome: AlfredHome
) {
fun run(buildId: BuildId, rev: String?): ProcessInfo {
val config = builds.buildConfig(buildId)
- val logFile = builds.createLogFile(buildId)
+ val logFile = alfredHome.newLogFile(buildId)
logger.info("preparing process for build $buildId")
logger.info("log file: ${logFile.backingFile.absolutePath}")
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index ef539f0..47cf918 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -14,3 +14,5 @@ spring.mail.password=${ALFRED_MAIL_PASSWORD}
spring.mail.properties.mail.smtp.auth=${ALFRED_MAIL_SMTP_AUTH : true}
spring.mail.properties.mail.smtp.starttls.enable=${ALFRED_MAIL_STARTTLS : true}
ALFRED_MAIL_FROM=alfred@your.service
+
+management.endpoints.web.exposure.include=scheduledtasks,health
diff --git a/src/test/kotlin/alfred/web/core/runner/GitRunnerTest.kt b/src/test/kotlin/alfred/web/core/runner/GitRunnerTest.kt
index c6eeeef..4d9a696 100644
--- a/src/test/kotlin/alfred/web/core/runner/GitRunnerTest.kt
+++ b/src/test/kotlin/alfred/web/core/runner/GitRunnerTest.kt
@@ -17,7 +17,6 @@ import io.mockk.verify
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
-import java.nio.file.Paths
class GitRunnerTest {
@@ -36,12 +35,10 @@ class GitRunnerTest {
val workspacesSpy = spyk(Workspaces())
- val home = mockk()
- every { home.buildConfig(any()) } returns homeDir.resolve("simple-git.properties")
- every { home.logsDir() } returns homeDir.resolve("logs")
- every { home.homePath } returns homeDir
+ val home = AlfredHome(homeDir.toString())
+ homeDir.resolve("builds").toFile().mkdir()
homeDir
- .resolve("simple-git.properties")
+ .resolve("builds/simple-git.properties")
.toFile()
.writeText(buildProperties())
@@ -51,7 +48,8 @@ class GitRunnerTest {
workspaces = workspacesSpy,
eventPublisher = eventPublisher,
git = git,
- script = script
+ script = script,
+ alfredHome = home
)
// When
diff --git a/src/test/kotlin/alfred/web/core/runner/ScriptRunnerTest.kt b/src/test/kotlin/alfred/web/core/runner/ScriptRunnerTest.kt
index 4833c3d..f0e7cb3 100644
--- a/src/test/kotlin/alfred/web/core/runner/ScriptRunnerTest.kt
+++ b/src/test/kotlin/alfred/web/core/runner/ScriptRunnerTest.kt
@@ -17,12 +17,10 @@ class ScriptRunnerTest {
@Test
fun runs(@TempDir homeDir: Path) {
// Given
- val home = mockk()
- every { home.buildConfig(any()) } returns homeDir.resolve("simple-script.properties")
- every { home.logsDir() } returns homeDir.resolve("logs")
- every { home.homePath } returns homeDir
+ val home = AlfredHome(homeDir.toString())
+ homeDir.resolve("builds").toFile().mkdir()
homeDir
- .resolve("simple-script.properties")
+ .resolve("builds/simple-script.properties")
.toFile()
.writeText(buildProperties())
@@ -39,7 +37,8 @@ class ScriptRunnerTest {
builds = Builds(home),
workspaces = workspaces,
eventPublisher = eventPublisher,
- script = script
+ script = script,
+ alfredHome = home
)
// When