Skip to content

Commit f9a126a

Browse files
committed
Use a common implementation for JSON repositories
The purpose of this PR is to remove duplicated code. It should also make it easier to improve or replace concrete repository implementations later.
1 parent e70a1c0 commit f9a126a

File tree

7 files changed

+81
-168
lines changed

7 files changed

+81
-168
lines changed

modules/core/src/main/scala/org/scalasteward/core/nurture/json/JsonPullRequestRepo.scala

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,68 +16,51 @@
1616

1717
package org.scalasteward.core.nurture.json
1818

19-
import better.files.File
2019
import cats.implicits._
21-
import io.circe.parser.decode
22-
import io.circe.syntax._
2320
import org.http4s.Uri
2421
import org.scalasteward.core.data.{Dependency, Update}
2522
import org.scalasteward.core.git.Sha1
2623
import org.scalasteward.core.io.{FileAlg, WorkspaceAlg}
2724
import org.scalasteward.core.nurture.PullRequestRepository
2825
import org.scalasteward.core.update.UpdateService
29-
import org.scalasteward.core.util.MonadThrowable
26+
import org.scalasteward.core.util.{JsonKeyValueStore, MonadThrowable}
3027
import org.scalasteward.core.vcs.data.{PullRequestState, Repo}
3128

32-
class JsonPullRequestRepo[F[_]](
29+
final class JsonPullRequestRepo[F[_]](
3330
implicit
3431
fileAlg: FileAlg[F],
3532
workspaceAlg: WorkspaceAlg[F],
3633
F: MonadThrowable[F]
3734
) extends PullRequestRepository[F] {
35+
private val kvStore = new JsonKeyValueStore[F, Repo, Map[String, PullRequestData]]("prs", "3")
36+
3837
override def createOrUpdate(
3938
repo: Repo,
4039
url: Uri,
4140
baseSha1: Sha1,
4241
update: Update,
4342
state: PullRequestState
4443
): F[Unit] =
45-
readJson.flatMap { store =>
46-
val updated = store.store.get(repo) match {
44+
kvStore.read.flatMap { store =>
45+
val updated = store.get(repo) match {
4746
case Some(prs) => prs.updated(url.toString(), PullRequestData(baseSha1, update, state))
4847
case None => Map(url.toString() -> PullRequestData(baseSha1, update, state))
4948
}
50-
writeJson(PullRequestStore(store.store.updated(repo, updated)))
49+
kvStore.write(store.updated(repo, updated))
5150
}
5251

5352
override def findPullRequest(
5453
repo: Repo,
5554
dependency: Dependency,
5655
newVersion: String
5756
): F[Option[(Uri, Sha1, PullRequestState)]] =
58-
readJson.map { store =>
59-
val pullRequests = store.store.get(repo).fold(List.empty[(String, PullRequestData)])(_.toList)
57+
kvStore.read.map { store =>
58+
val pullRequests = store.get(repo).fold(List.empty[(String, PullRequestData)])(_.toList)
6059
pullRequests
6160
.find {
6261
case (_, data) =>
6362
UpdateService.isUpdateFor(data.update, dependency) && data.update.nextVersion === newVersion
6463
}
6564
.map { case (url, data) => (Uri.unsafeFromString(url), data.baseSha1, data.state) }
6665
}
67-
68-
def jsonFile: F[File] =
69-
workspaceAlg.rootDir.map(_ / "prs_v02.json")
70-
71-
def readJson: F[PullRequestStore] =
72-
jsonFile.flatMap { file =>
73-
fileAlg.readFile(file).flatMap {
74-
case Some(content) => F.fromEither(decode[PullRequestStore](content))
75-
case None => F.pure(PullRequestStore(Map.empty))
76-
}
77-
}
78-
79-
def writeJson(store: PullRequestStore): F[Unit] =
80-
jsonFile.flatMap { file =>
81-
fileAlg.writeFile(file, store.asJson.toString)
82-
}
8366
}

modules/core/src/main/scala/org/scalasteward/core/nurture/json/PullRequestStore.scala

Lines changed: 0 additions & 31 deletions
This file was deleted.

modules/core/src/main/scala/org/scalasteward/core/repocache/json/JsonRepoCacheRepository.scala

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@
1616

1717
package org.scalasteward.core.repocache.json
1818

19-
import better.files.File
2019
import cats.implicits._
21-
import io.circe.parser.decode
22-
import io.circe.syntax._
2320
import org.scalasteward.core.data.Dependency
2421
import org.scalasteward.core.io.{FileAlg, WorkspaceAlg}
2522
import org.scalasteward.core.repocache.{RepoCache, RepoCacheRepository}
26-
import org.scalasteward.core.util.MonadThrowable
23+
import org.scalasteward.core.util.{JsonKeyValueStore, MonadThrowable}
2724
import org.scalasteward.core.vcs.data.Repo
2825

2926
final class JsonRepoCacheRepository[F[_]](
@@ -32,30 +29,16 @@ final class JsonRepoCacheRepository[F[_]](
3229
workspaceAlg: WorkspaceAlg[F],
3330
F: MonadThrowable[F]
3431
) extends RepoCacheRepository[F] {
32+
private val kvStore = new JsonKeyValueStore[F, Repo, RepoCache]("repos", "6")
33+
3534
override def findCache(repo: Repo): F[Option[RepoCache]] =
36-
readJson.map(_.store.get(repo))
35+
kvStore.get(repo)
3736

3837
override def updateCache(repo: Repo, repoCache: RepoCache): F[Unit] =
39-
readJson.flatMap { store =>
40-
writeJson(RepoStore(store.store.updated(repo, repoCache)))
41-
}
38+
kvStore.put(repo, repoCache)
4239

4340
override def getDependencies(repos: List[Repo]): F[List[Dependency]] =
44-
readJson.map(_.store.filterKeys(repos.contains).values.flatMap(_.dependencies).toList.distinct)
45-
46-
def jsonFile: F[File] =
47-
workspaceAlg.rootDir.map(_ / "repos_v05.json")
48-
49-
def readJson: F[RepoStore] =
50-
jsonFile.flatMap { file =>
51-
fileAlg.readFile(file).flatMap {
52-
case Some(content) => F.fromEither(decode[RepoStore](content))
53-
case None => F.pure(RepoStore(Map.empty))
54-
}
55-
}
56-
57-
def writeJson(store: RepoStore): F[Unit] =
58-
jsonFile.flatMap { file =>
59-
fileAlg.writeFile(file, store.asJson.toString)
41+
kvStore.read.map {
42+
_.filterKeys(repos.contains).values.flatMap(_.dependencies).toList.distinct
6043
}
6144
}

modules/core/src/main/scala/org/scalasteward/core/repocache/json/RepoStore.scala

Lines changed: 0 additions & 32 deletions
This file was deleted.

modules/core/src/main/scala/org/scalasteward/core/update/json/JsonUpdateRepository.scala

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,27 @@
1616

1717
package org.scalasteward.core.update.json
1818

19-
import better.files.File
2019
import cats.implicits._
21-
import io.circe.parser.decode
22-
import io.circe.syntax._
2320
import org.scalasteward.core.data.Update
2421
import org.scalasteward.core.io.{FileAlg, WorkspaceAlg}
2522
import org.scalasteward.core.update.UpdateRepository
26-
import org.scalasteward.core.util.MonadThrowable
23+
import org.scalasteward.core.util.{JsonKeyValueStore, MonadThrowable}
2724

28-
// WIP
29-
class JsonUpdateRepository[F[_]](
25+
final class JsonUpdateRepository[F[_]](
3026
implicit
3127
fileAlg: FileAlg[F],
3228
workspaceAlg: WorkspaceAlg[F],
3329
F: MonadThrowable[F]
3430
) extends UpdateRepository[F] {
31+
private val kvStore = new JsonKeyValueStore[F, String, List[Update.Single]]("updates", "3")
32+
private val key = "updates"
3533

3634
override def deleteAll: F[Unit] =
37-
writeJson(UpdateStore(Set.empty))
35+
kvStore.write(Map.empty)
3836

3937
override def saveMany(updates: List[Update.Single]): F[Unit] =
40-
readJson.map(s => UpdateStore(s.store ++ updates)).flatMap(writeJson)
41-
42-
def jsonFile: F[File] =
43-
workspaceAlg.rootDir.map(_ / "updates_v02.json")
44-
45-
def readJson: F[UpdateStore] =
46-
jsonFile.flatMap { file =>
47-
fileAlg.readFile(file).flatMap {
48-
case Some(content) => F.fromEither(decode[UpdateStore](content))
49-
case None => F.pure(UpdateStore(Set.empty))
50-
}
51-
}
52-
53-
def writeJson(store: UpdateStore): F[Unit] =
54-
jsonFile.flatMap { file =>
55-
fileAlg.writeFile(file, store.asJson.toString)
56-
}
38+
kvStore
39+
.getOrElse(key, List.empty)
40+
.map(_ ++ updates)
41+
.flatMap(list => kvStore.write(Map(key -> list)))
5742
}

modules/core/src/main/scala/org/scalasteward/core/update/json/UpdateStore.scala

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2018-2019 Scala Steward contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.scalasteward.core.util
18+
19+
import better.files.File
20+
import cats.implicits._
21+
import io.circe.parser.decode
22+
import io.circe.syntax._
23+
import io.circe.{Decoder, Encoder, KeyDecoder, KeyEncoder}
24+
import org.scalasteward.core.io.{FileAlg, WorkspaceAlg}
25+
26+
final class JsonKeyValueStore[F[_], K, V](name: String, schemaVersion: String)(
27+
implicit
28+
fileAlg: FileAlg[F],
29+
workspaceAlg: WorkspaceAlg[F],
30+
F: MonadThrowable[F],
31+
keyDecoder: KeyDecoder[K],
32+
keyEncoder: KeyEncoder[K],
33+
valueDecoder: Decoder[V],
34+
valueEncoder: Encoder[V]
35+
) {
36+
private val jsonFile: F[File] =
37+
workspaceAlg.rootDir.map(_ / s"${name}_v${schemaVersion}.json")
38+
39+
def get(key: K): F[Option[V]] =
40+
read.map(_.get(key))
41+
42+
def getOrElse(key: K, default: => V): F[V] =
43+
get(key).map(_.getOrElse(default))
44+
45+
def put(key: K, value: V): F[Unit] =
46+
read.map(_.updated(key, value)).flatMap(write)
47+
48+
def read: F[Map[K, V]] =
49+
jsonFile.flatMap(fileAlg.readFile).flatMap {
50+
case Some(content) => F.fromEither(decode[Map[K, V]](content))
51+
case None => F.pure(Map.empty[K, V])
52+
}
53+
54+
def write(store: Map[K, V]): F[Unit] =
55+
jsonFile.flatMap(fileAlg.writeFile(_, store.asJson.toString))
56+
}

0 commit comments

Comments
 (0)