Permalink
Browse files

Pluggable loggers for sbt-coursier (#872)

  • Loading branch information...
teozkr authored and alexarchambault committed Jun 29, 2018
1 parent bc346d3 commit 0b187efd96ee7d8e2fc9fa5a4b2acdf0353bf045
@@ -1165,7 +1165,20 @@ object Cache {
def gettingLength(url: String): Unit = {}
def gettingLengthResult(url: String, length: Option[Long]): Unit = {}
def removedCorruptFile(url: String, file: File, reason: Option[FileError]): Unit
def removedCorruptFile(url: String, file: File, reason: Option[FileError]): Unit = {}
/***
*
* @param beforeOutput: called before any output is printed, iff something else is outputed.
* (That is, if that `Logger` doesn't print any progress,
* `initialMessage` won't be printed either.)
*/
def init(beforeOutput: => Unit): Unit = {}
/**
*
* @return whether any message was printed by `Logger`
*/
def stopDidPrintSomething(): Boolean = false
}
var bufferSize = 1024*1024
@@ -410,13 +410,7 @@ class TermDisplay(
else
1000L / 60
/***
*
* @param beforeOutput: called before any output is printed, iff something else is outputed.
* (That is, if that `TermDisplay` doesn't print any progress,
* `initialMessage` won't be printed either.)
*/
def init(beforeOutput: => Unit): Unit = {
override def init(beforeOutput: => Unit): Unit = {
updateRunnableOpt = Some(new UpdateDisplayRunnable(beforeOutput, out, width, fallbackMode0))
updateRunnable.init()
@@ -426,11 +420,7 @@ class TermDisplay(
def init(): Unit =
init(())
/**
*
* @return whether any message was printed by this `TermDisplay`
*/
def stopDidPrintSomething(): Boolean = {
override def stopDidPrintSomething(): Boolean = {
scheduler.shutdown()
scheduler.awaitTermination(2 * refreshInterval, TimeUnit.MILLISECONDS)
updateRunnable.stop()
@@ -1,5 +1,6 @@
package coursier
import java.io.OutputStreamWriter
import sbt.librarymanagement._
import sbt.{ Configuration, Resolver, _ }
import sbt.Keys._
@@ -52,6 +53,8 @@ object CoursierPlugin extends AutoPlugin {
val coursierClassifiersArtifacts = Keys.coursierClassifiersArtifacts
val coursierSbtClassifiersArtifacts = Keys.coursierSbtClassifiersArtifacts
val coursierLoggerFactory = Keys.coursierLoggerFactory
val coursierVersion = coursier.util.Properties.version
val addSbtCoursier = {
addSbtPlugin("io.get-coursier" % "sbt-coursier" % coursierVersion)
@@ -306,7 +309,8 @@ object CoursierPlugin extends AutoPlugin {
coursierCredentials := Map.empty,
coursierCache := Cache.default,
coursierReorderResolvers := true,
coursierKeepPreloaded := false
coursierKeepPreloaded := false,
coursierLoggerFactory := { () => new TermDisplay(new OutputStreamWriter(System.err)) }
)
override lazy val projectSettings = coursierSettings(None, Seq(Compile, Test).map(c => c -> c.name)) ++
@@ -17,6 +17,7 @@ object Keys {
val coursierCachePolicies = SettingKey[Seq[CachePolicy]]("coursier-cache-policies")
val coursierTtl = SettingKey[Option[Duration]]("coursier-ttl")
val coursierKeepPreloaded = SettingKey[Boolean]("coursier-keep-preloaded", "Whether to take into account sbt preloaded repositories or not")
val coursierLoggerFactory = SettingKey[() => Cache.Logger]("coursier-logger-factory")
val coursierVerbosity = SettingKey[Int]("coursier-verbosity")
@@ -431,8 +431,6 @@ object Tasks {
Module(scalaOrganization, "scalap") -> scalaVersion
)
private def createLogger() = new TermDisplay(new OutputStreamWriter(System.err))
private[coursier] def exceptionPatternParser(): String => coursier.ivy.Pattern = {
val props = sys.props.toMap
@@ -571,7 +569,6 @@ object Tasks {
def resolutionsTask(
sbtClassifiers: Boolean = false
): Def.Initialize[sbt.Task[Map[Set[String], coursier.Resolution]]] = Def.taskDyn {
val projectName = thisProjectRef.value.project
val sv = scalaVersion.value
@@ -605,6 +602,7 @@ object Tasks {
val cachePolicies = coursierCachePolicies.value
val ttl = coursierTtl.value
val cache = coursierCache.value
val createLogger = coursierLoggerFactory.value
val log = streams.value.log
@@ -692,7 +690,7 @@ object Tasks {
def resolution(startRes: Resolution) = {
var pool: ExecutorService = null
var resLogger: TermDisplay = null
var resLogger: Cache.Logger = null
val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1
@@ -954,14 +952,14 @@ object Tasks {
ignoreArtifactErrors: Boolean = false,
includeSignatures: Boolean = false
) = Def.taskDyn {
val projectName = thisProjectRef.value.project
val parallelDownloads = coursierParallelDownloads.value
val artifactsChecksums = coursierArtifactsChecksums.value
val cachePolicies = coursierCachePolicies.value
val ttl = coursierTtl.value
val cache = coursierCache.value
val createLogger = coursierLoggerFactory.value
val log = streams.value.log
@@ -1007,7 +1005,7 @@ object Tasks {
synchronized {
var pool: ExecutorService = null
var artifactsLogger: TermDisplay = null
var artifactsLogger: Cache.Logger = null
val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1
@@ -0,0 +1,68 @@
val logFile = settingKey[File]("")
// Arbitrary dependency with no transitive dependencies
libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.25"
// We want to control when the cache gets a hit
coursierCache := baseDirectory.value / "cache"
logFile := baseDirectory.value / "log"
coursierLoggerFactory := {
val logStream = new java.io.PrintStream(logFile.value)
def log(msg: String): Unit = {
println(msg)
logStream.println(msg)
}
val cacheFile = coursierCache.value
;{ () =>
new coursier.Cache.Logger {
override def init(beforeOutput: => Unit): Unit = {
beforeOutput
log("init")
}
override def foundLocally(url: String, file: File): Unit = {
log(s"found $url at ${IO.relativize(cacheFile, file).getOrElse(file)}")
}
override def downloadingArtifact(url: String, file: File): Unit = {
log(s"downloading $url to ${IO.relativize(cacheFile, file).getOrElse(file)}")
}
override def downloadedArtifact(url: String, success: Boolean): Unit = {
log(s"downloaded $url: $success")
}
override def stopDidPrintSomething(): Boolean = {
log("stop")
true
}
}
}
}
TaskKey[Unit]("checkDownloaded") := {
val log = IO.readLines(logFile.value)
if (log.head != "init") {
sys.error(s"log started with '${log.head}', not init")
}
if (log.last != "stop") {
sys.error(s"log ended with '${log.last}', not stop")
}
val url = "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar"
val downloadedMsg = s"downloaded $url: true"
val downloadingMsgStart = s"downloading $url to "
if (!log.contains(downloadedMsg))
sys.error(s"log doesn't contain '$downloadedMsg'")
if (!log.exists(_.startsWith(downloadingMsgStart)))
sys.error(s"log doesn't contain line starting with '$downloadingMsgStart'")
}
TaskKey[Unit]("checkFound") := {
val log = IO.readLines(logFile.value)
if (log.head != "init") {
sys.error(s"log started with '${log.head}', not init")
}
if (log.last != "stop") {
sys.error(s"log ended with '${log.last}', not stop")
}
val url = "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar"
val msg = s"found $url at "
if (!log.exists(_.startsWith(msg)))
sys.error(s"log doesn't contain line starting with '$msg'")
}
@@ -0,0 +1,11 @@
{
val pluginVersion = sys.props.getOrElse(
"plugin.version",
throw new RuntimeException(
"""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
)
)
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
}
@@ -0,0 +1,6 @@
$ delete cache
> update
> checkDownloaded
> reload
> update
> checkFound

0 comments on commit 0b187ef

Please sign in to comment.