@@ -19,14 +19,13 @@ package org.scalasteward.core.coursier
1919import cats .implicits .*
2020import cats .{MonadThrow , Parallel }
2121import io .circe .generic .semiauto .{deriveCodec , deriveDecoder , deriveEncoder }
22- import io .circe .{Codec , KeyEncoder }
23- import org .scalasteward .core .coursier .VersionsCache .{Key , Value }
22+ import io .circe .{Codec , Decoder , Encoder , KeyEncoder }
23+ import org .scalasteward .core .coursier .VersionsCache .{Key , Value , VersionWithFirstSeen }
2424import org .scalasteward .core .data .{Dependency , Resolver , Scope , Version }
2525import org .scalasteward .core .persistence .KeyValueStore
2626import org .scalasteward .core .util .{DateTimeAlg , Timestamp }
27+
2728import scala .concurrent .duration .FiniteDuration
28- import io .circe .Encoder
29- import io .circe .Decoder
3029
3130final class VersionsCache [F [_]](
3231 cacheTtl : FiniteDuration ,
@@ -40,30 +39,39 @@ final class VersionsCache[F[_]](
4039 def getVersions (dependency : Scope .Dependency , maxAge : Option [FiniteDuration ]): F [List [Version ]] =
4140 dependency.resolvers
4241 .parFlatTraverse(getVersionsImpl(dependency.value, _, maxAge.getOrElse(cacheTtl)))
43- .map(_.distinct.sorted)
42+ .map(_.map(_.version). distinct.sorted) // TODO - remove `.map(_.version)`
4443
4544 private def getVersionsImpl (
4645 dependency : Dependency ,
4746 resolver : Resolver ,
4847 maxAge : FiniteDuration
49- ): F [List [Version ]] =
48+ ): F [List [VersionWithFirstSeen ]] =
5049 dateTimeAlg.currentTimestamp.flatMap { now =>
5150 val key = Key (dependency, resolver)
5251 store.get(key).flatMap {
5352 case Some (value) if value.updatedAt.until(now) <= (maxAge * value.maxAgeFactor) =>
54- F .pure(value.versions.map(_.version) )
53+ F .pure(value.versions)
5554 case maybeValue =>
5655 coursierAlg.getVersions(dependency, resolver).attempt.flatMap {
5756 case Right (versions) =>
58- store.put(key, Value (now, versions.map(addCurrentTime), None )).as(versions)
57+ val existingFirstSeenByVersion : Map [Version , Timestamp ] =
58+ maybeValue
59+ .map(_.versions.flatMap(vwfs => vwfs.firstSeen.map(vwfs.version -> _)).toMap)
60+ .getOrElse(Map .empty)
61+ val updatedVersionsWithFirstSeen =
62+ versions.map(v =>
63+ VersionWithFirstSeen (v, Some (existingFirstSeenByVersion.getOrElse(v, now)))
64+ )
65+
66+ store
67+ .put(key, Value (now, updatedVersionsWithFirstSeen, None ))
68+ .as(updatedVersionsWithFirstSeen)
5969 case Left (throwable) =>
6070 val versions = maybeValue.map(_.versions).getOrElse(List .empty)
6171 store.put(key, Value (now, versions, Some (throwable.toString))).as(versions)
6272 }
6373 }
6474 }
65-
66- private def addCurrentTime (version : Version ): VersionWithFirstSeen = {}
6775}
6876
6977object VersionsCache {
@@ -102,10 +110,10 @@ object VersionsCache {
102110
103111 object VersionWithFirstSeen {
104112 implicit val valueEncoder : Encoder [VersionWithFirstSeen ] = deriveEncoder
105- implicit val valueDecoder : Decoder [VersionWithFirstSeen ] =
106- deriveDecoder[ VersionWithFirstSeen ]
107- .or(
108- Decoder [ Version ].map(v => VersionWithFirstSeen (v, None ) )
109- )
113+ implicit val valueDecoder : Decoder [VersionWithFirstSeen ] = {
114+ val legacyVersionStringDecoder = Decoder [ Version ].map( VersionWithFirstSeen (_, None ))
115+
116+ deriveDecoder[ VersionWithFirstSeen ].or(legacyVersionStringDecoder )
117+ }
110118 }
111119}
0 commit comments