-
Notifications
You must be signed in to change notification settings - Fork 20
/
ReleaseChecker.scala
96 lines (84 loc) · 3.38 KB
/
ReleaseChecker.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package io.pager.lookup
import io.pager.PagerError
import io.pager.client.github.GitHubClient
import io.pager.client.telegram.TelegramClient
import io.pager.logging._
import io.pager.subscription.Repository.{ Name, Version }
import io.pager.subscription.{ Repository, SubscriptionLogic }
import zio.macros.annotation.accessible
import zio.{ IO, RIO, Task, ZIO }
import scala.util.Try
@accessible(">")
trait ReleaseChecker {
val releaseChecker: ReleaseChecker.Service[Any]
}
object ReleaseChecker {
trait Service[R] {
def scheduleRefresh: RIO[R, Unit]
}
trait Live extends ReleaseChecker {
def logger: Logger.Service
def gitHubClient: GitHubClient.Service[Any]
def telegramClient: TelegramClient.Service[Any]
def subscriptionLogic: SubscriptionLogic.Service[Any]
override val releaseChecker: Service[Any] = new Service[Any] {
override def scheduleRefresh: Task[Unit] =
for {
_ <- logger.info("Getting latest repository versions")
repos <- subscriptionLogic.listRepositories
latestVersions <- latestRepositoryVersions(repos.keySet)
updatedVersions = newVersions(repos, latestVersions)
_ <- subscriptionLogic.updateVersions(updatedVersions)
statuses <- repositoryStates(updatedVersions)
_ <- broadcastUpdates(statuses)
_ <- logger.info("Finished repository refresh")
} yield ()
}
private def repositoryStates(updatedVersions: Map[Name, Version]): Task[List[Repository]] =
ZIO.foreach(updatedVersions) {
case (name, version) =>
subscriptionLogic
.listSubscribers(name)
.map(subscribers => Repository(name, version, subscribers))
}
private def latestRepositoryVersions(repos: Set[Name]): IO[PagerError, Map[Name, Option[Version]]] =
ZIO
.traverse(repos) { name =>
gitHubClient
.releases(name)
.map(releases => name -> Try(releases.maxBy(_.published_at).name).toOption)
}
.map(_.toMap)
private def newVersions(
latestKnownReleases: Map[Name, Option[Version]],
latestReleases: Map[Name, Option[Version]]
): Map[Name, Version] =
latestKnownReleases.flatMap {
case (name, latestKnownVersion) =>
latestReleases
.get(name)
.collect { case Some(latestVersion) if !latestKnownVersion.contains(latestVersion) => name -> latestVersion }
}
private def broadcastUpdates(repos: List[Repository]): Task[Unit] =
ZIO
.foreach(repos) { repo =>
val message = s"There is a new version of ${repo.name.value} available: ${repo.version.value}"
telegramClient.broadcastMessage(repo.subscribers, message)
}
.unit
}
object Live {
def make(
logger: Logger.Service,
gc: GitHubClient,
tc: TelegramClient,
sl: SubscriptionLogic
): ReleaseChecker.Service[Any] =
new ReleaseChecker.Live {
override def logger: Logger.Service = Logger.Test
override def gitHubClient: GitHubClient.Service[Any] = gc.gitHubClient
override def telegramClient: TelegramClient.Service[Any] = tc.telegramClient
override def subscriptionLogic: SubscriptionLogic.Service[Any] = sl.subscriptionLogic
}.releaseChecker
}
}