Merge pull request #8101 from eed3si9n/wip/scalacoptions

[2.x] Scala compiler plugin support
This commit is contained in:
eugene yokota 2025-05-04 01:25:35 -04:00 committed by GitHub
commit 4c0ab346a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 113 additions and 37 deletions

View File

@ -995,7 +995,7 @@ object Defaults extends BuildCommon {
Vector(
"-Ypickle-java",
"-Ypickle-write",
converter.toPath(earlyOutput.value).toString
earlyOutput.value.toString
) ++ old
else old
},
@ -4221,18 +4221,19 @@ object Classpaths {
given FileConverter = converter
(base * (filter -- excl) +++ (base / config.name).descendantsExcept(filter, excl)).classpath
def autoPlugins(
private def autoPlugins(
report: UpdateReport,
internalPluginClasspath: Seq[NioPath],
isDotty: Boolean
): Seq[String] =
)(using conv: FileConverter): Seq[String] =
import sbt.internal.inc.classpath.ClasspathUtil.compilerPlugins
val pluginClasspath =
report
.matching(configurationFilter(CompilerPlugin.name))
.map(_.toPath) ++ internalPluginClasspath
val plugins = compilerPlugins(pluginClasspath, isDotty)
plugins.map("-Xplugin:" + _.toAbsolutePath.toString).toSeq
plugins.toVector.map: p =>
"-Xplugin:" + conv.toVirtualFile(p).toString()
private lazy val internalCompilerPluginClasspath: Initialize[Task[Classpath]] =
(Def

View File

@ -118,7 +118,7 @@ object Aggregation {
val transform = nodeView(s, str, roots, extra)
runTask(toRun, s, str, structure.index.triggers, config)(using transform)
val stop = System.currentTimeMillis
val cacheSummary = Def.cacheEventLog.summary
val cacheSummary = Def.cacheEventLog.summary.toString()
Complete(start, stop, result, cacheSummary, newS)
def runTasks[A1](

View File

@ -12,7 +12,7 @@ object Dependencies {
// sbt modules
private val ioVersion = nightlyVersion.getOrElse("1.10.4")
val zincVersion = nightlyVersion.getOrElse("2.0.0-M3")
val zincVersion = nightlyVersion.getOrElse("2.0.0-M4")
private val sbtIO = "org.scala-sbt" %% "io" % ioVersion

View File

@ -1,9 +1,10 @@
import sbt.internal.util.StringVirtualFile1
import sbt.internal.util.{ CacheEventSummary, StringVirtualFile1 }
import sjsonnew.BasicJsonProtocol.*
val pure1 = taskKey[Unit]("")
val map1 = taskKey[String]("")
val mapN1 = taskKey[Unit]("")
val checkMapN1 = taskKey[Unit]("")
Global / localCacheDirectory := baseDirectory.value / "diskcache"
@ -29,3 +30,11 @@ mapN1 := (Def.cachedTask {
Def.declareOutput(output)
()
}).value
checkMapN1 := {
val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s
case s => sys.error(s"empty event log")
assert(prev.hitCount == 2, s"prev.hitCount = ${prev.hitCount}")
}

View File

@ -16,3 +16,4 @@ $ exists target/out/b2.txt
$ exists target/out/a.txt
$ exists target/out/b1.txt
$ exists target/out/c.txt
> checkMapN1

View File

@ -0,0 +1,21 @@
import sbt.internal.util.CacheEventSummary
val check = taskKey[Unit]("")
Global / localCacheDirectory := baseDirectory.value / "diskcache"
scalaVersion := "2.13.16"
addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.3").cross(CrossVersion.full))
check := {
val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s
case s => sys.error(s"empty event log")
assert(prev.hitCount == 1, s"prev.hitCount = ${prev.hitCount}")
}
lazy val foo = (project in file("foo"))
.settings(
name := "foo"
)

View File

@ -0,0 +1,5 @@
package example
class A {
def foo = 1
}

View File

@ -0,0 +1,4 @@
> foo/compile
> clean
> foo/compile
> check

View File

@ -13,8 +13,45 @@ end ActionCacheEvent
case class ActionCacheError(outputFiles: Seq[VirtualFileRef])
enum CacheEventSummary:
case Empty
case Data(
hits: Seq[(String, Long)],
hitCount: Long,
missCount: Long,
hitRate: Double,
onsiteCount: Option[Long],
errorCount: Option[Long]
)
override def toString(): String = this match
case Empty => ""
case Data(
hits,
hitCount,
missCount,
hitRate,
onsiteCount,
errorCount
) =>
val hitDescs = hits.map {
case (id, 1) => s"1 $id cache hit"
case (id, v) => s"$v $id cache hits"
}.sorted
val missDesc = onsiteCount.map:
case 1 => s"1 onsite task"
case _ => s"$missCount onsite tasks"
val errorDesc = errorCount.map:
case 1 => s"1 error"
case errors => s"$errors errors"
val descs = hitDescs ++ missDesc ++ errorDesc
val descsSummary = descs.mkString(", ")
val hitRateStr = (hitRate * 100.0).floor.toInt
s"cache $hitRateStr%, $descsSummary"
end CacheEventSummary
class CacheEventLog:
private val acEvents = TrieMap.empty[ActionCacheEvent, Long]
private val previousEvents = TrieMap.empty[ActionCacheEvent, Long]
def append(event: ActionCacheEvent): Unit =
acEvents.updateWith(event) {
@ -23,31 +60,29 @@ class CacheEventLog:
}
def clear(): Unit =
previousEvents.clear()
previousEvents ++= acEvents
acEvents.clear()
def summary: String =
if acEvents.isEmpty then ""
def summary: CacheEventSummary = toSummary(acEvents)
def previous: CacheEventSummary = toSummary(previousEvents)
def toSummary(events: TrieMap[ActionCacheEvent, Long]): CacheEventSummary =
if events.isEmpty then CacheEventSummary.Empty
else
val total = acEvents.values.sum
val hits = acEvents.view.collect { case (ActionCacheEvent.Found(id), v) => (id, v) }.toMap
val total = events.values.sum
val hits = events.view.collect { case (ActionCacheEvent.Found(id), v) => (id, v) }.toMap
val hitCount = hits.values.sum
val missCount = total - hitCount
val hitRate = (hitCount.toDouble / total.toDouble * 100.0).floor.toInt
val hitDescs = hits.toSeq.map {
case (id, 1) => s"1 $id cache hit"
case (id, v) => s"$v $id cache hits"
}.sorted
val missDesc = acEvents
.get(ActionCacheEvent.OnsiteTask)
.map:
case 1 => s"1 onsite task"
case _ => s"$missCount onsite tasks"
val errorDesc = acEvents
.get(ActionCacheEvent.Error)
.map:
case 1 => s"1 error"
case errors => s"$errors errors"
val descs = hitDescs ++ missDesc ++ errorDesc
val descsSummary = descs.mkString(", ")
s"cache $hitRate%, $descsSummary"
val hitRate = (hitCount.toDouble / total.toDouble)
val onsiteCount = events.get(ActionCacheEvent.OnsiteTask)
val errorCount = events.get(ActionCacheEvent.Error)
CacheEventSummary.Data(
hits.toSeq,
hitCount,
missCount,
hitRate,
onsiteCount,
errorCount
)
end CacheEventLog

View File

@ -7,14 +7,14 @@ object CacheEventLogTest extends BasicTestSuite:
test("summary of 0 events") {
val logger = CacheEventLog()
val expectedSummary = ""
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 1 disk event") {
val logger = CacheEventLog()
logger.append(ActionCacheEvent.Found("disk"))
val expectedSummary = "cache 100%, 1 disk cache hit"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 2 disk events") {
@ -22,7 +22,7 @@ object CacheEventLogTest extends BasicTestSuite:
logger.append(ActionCacheEvent.Found("disk"))
logger.append(ActionCacheEvent.Found("disk"))
val expectedSummary = "cache 100%, 2 disk cache hits"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 1 disk, 1 onsite task") {
@ -30,7 +30,7 @@ object CacheEventLogTest extends BasicTestSuite:
logger.append(ActionCacheEvent.Found("disk"))
logger.append(ActionCacheEvent.OnsiteTask)
val expectedSummary = "cache 50%, 1 disk cache hit, 1 onsite task"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 1 disk, 1 onsite task, 1 error") {
@ -39,7 +39,7 @@ object CacheEventLogTest extends BasicTestSuite:
logger.append(ActionCacheEvent.OnsiteTask)
logger.append(ActionCacheEvent.Error)
val expectedSummary = "cache 33%, 1 disk cache hit, 1 onsite task, 1 error"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 1 disk, 2 errors") {
@ -48,7 +48,7 @@ object CacheEventLogTest extends BasicTestSuite:
logger.append(ActionCacheEvent.Error)
logger.append(ActionCacheEvent.Error)
val expectedSummary = "cache 33%, 1 disk cache hit, 2 errors"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 1 disk, 2 remote, 1 onsite task") {
@ -58,7 +58,7 @@ object CacheEventLogTest extends BasicTestSuite:
logger.append(ActionCacheEvent.Found("remote"))
logger.append(ActionCacheEvent.OnsiteTask)
val expectedSummary = "cache 75%, 1 disk cache hit, 2 remote cache hits, 1 onsite task"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
test("summary of 1 disk event after clear") {
@ -67,6 +67,6 @@ object CacheEventLogTest extends BasicTestSuite:
logger.clear()
logger.append(ActionCacheEvent.Found("disk"))
val expectedSummary = "cache 100%, 1 disk cache hit"
assertEquals(logger.summary, expectedSummary)
assertEquals(logger.summary.toString(), expectedSummary)
}
end CacheEventLogTest