11package io .github .olegych .sbt
22
33import java .time .Instant
4-
5- import sbt .Keys ._
4+ import sbt .Keys .*
65import sbt .Tags .Tag
7- import sbt ._
6+ import sbt .*
87import sbt .plugins .JvmPlugin
98
10- import scala .concurrent .duration ._
9+ import java .io .FileNotFoundException
10+ import scala .concurrent .duration .*
1111
1212object CachedCiPlugin extends AutoPlugin {
1313 override def trigger = allRequirements
14+
1415 override def requires = JvmPlugin
1516
1617 object autoImport {
1718 lazy val cachedCiTestFull = taskKey[Unit ](" Full test." )
19+ lazy val cachedCiTestFullToken = taskKey[String ](" Run full tests if this changed." )
1820 lazy val cachedCiTestFullPeriod = settingKey[FiniteDuration ](" Period between full tests." )
1921 lazy val cachedCiTestQuick = taskKey[Unit ](" Quick test." )
2022 lazy val cachedCiTest = taskKey[Unit ](" Runs clean and full test if last full test was more than cachedCiTestFullPeriod ago, otherwise runs quick test." )
2123 }
2224
2325 import autoImport ._
2426
25- private case class Token (path : File ) {
27+ private case class Token (path : File , value : String ) {
2628 val lastModified = Instant .ofEpochMilli(path.lastModified())
27- def valid (period : FiniteDuration ) = path.exists() && lastModified.isAfter(Instant .now.minusMillis(period.toMillis))
29+ val lastValue = try IO .read(path) catch {
30+ case e : FileNotFoundException => " "
31+ }
32+ val valueChanged = path.exists() && lastValue != value
33+
34+ def valid (period : FiniteDuration ) = ! valueChanged && lastModified.isAfter(Instant .now.minusMillis(period.toMillis))
35+
2836 def refresh () = {
2937 path.getParentFile.mkdirs()
3038 path.delete()
31- path.createNewFile( )
39+ IO .write(path, value )
3240 }
3341 }
42+
3443 val CachedCiTest = Tag (" CachedCiTest" )
3544 override lazy val projectSettings = Seq (
3645 cachedCiTestFull := (Test / test).value,
3746 cachedCiTestQuick := (Test / testQuick).toTask(" " ).value,
47+ cachedCiTestFullToken := (Runtime / fullClasspath).value.mkString,
3848 cachedCiTestFullPeriod := 24 .hours,
3949 concurrentRestrictions += Tags .exclusive(CachedCiTest ),
4050 cachedCiTest := Def .task {
@@ -47,12 +57,13 @@ object CachedCiPlugin extends AutoPlugin {
4757 runTask(thisProjectRef.value / t, s)
4858 }
4959
50- val testFullToken = Token ((if (crossPaths.value) crossTarget.value else target.value) / " .lastCachedCiTestFull" )
51- s.log.info(s " Last ${thisProjectRef.value.project} / ${cachedCiTest.key.label} was at ${testFullToken.lastModified}" )
60+ val cachedCiTestFullTokenValue = cachedCiTestFullToken.value
61+ val testFullToken = Token ((if (crossPaths.value) crossTarget.value else target.value) / " .lastCachedCiTestFull" , cachedCiTestFullTokenValue)
62+ s.log.info(s " Last ${thisProjectRef.value.project} / ${cachedCiTest.key.label} was at ${testFullToken.lastModified}, token value changed: ${testFullToken.valueChanged}" )
5263 if (testFullToken.valid(cachedCiTestFullPeriod.value)) {
5364 run(cachedCiTestQuick)
5465 } else {
55- val cleanToken = Token (target.value / " .lastCachedCiTestClean" )
66+ val cleanToken = Token (target.value / " .lastCachedCiTestClean" , " " )
5667 if (! cleanToken.valid(cachedCiTestFullPeriod.value)) {
5768 run(clean)
5869 cleanToken.refresh()
0 commit comments