clean up Ivy-related logging

This commit is contained in:
Mark Harrah 2011-03-22 18:19:48 -04:00
parent 2a4805ac41
commit f10012df87
3 changed files with 45 additions and 39 deletions

View File

@ -22,20 +22,20 @@ import plugins.latest.LatestRevisionStrategy
import plugins.matcher.PatternMatcher
import plugins.parser.m2.PomModuleDescriptorParser
import plugins.resolver.ChainResolver
import util.Message
import util.{Message, MessageLogger}
import scala.xml.NodeSeq
final class IvySbt(val configuration: IvyConfiguration)
{
import configuration.{log, baseDirectory}
import configuration.baseDirectory
/** ========== Configuration/Setup ============
* This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance.
* These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded,
* saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...).
*/
private lazy val logger = new IvyLoggerInterface(log)
private def withDefaultLogger[T](f: => T): T =
private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T =
{
def action() =
IvySbt.synchronized
@ -55,7 +55,7 @@ final class IvySbt(val configuration: IvyConfiguration)
case None => action()
}
}
private lazy val settings =
private lazy val settings: IvySettings =
{
val is = new IvySettings
is.setBaseDir(baseDirectory)
@ -65,17 +65,17 @@ final class IvySbt(val configuration: IvyConfiguration)
case e: ExternalIvyConfiguration => is.load(e.file)
case i: InlineIvyConfiguration =>
IvySbt.configureCache(is, i.paths.cacheDirectory, i.localOnly)
IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, log)
IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log)
IvySbt.setModuleConfigurations(is, i.moduleConfigurations)
}
is
}
private lazy val ivy =
private lazy val ivy: Ivy =
{
val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine; override def getLoggerEngine = loggerEngine }
i.setSettings(settings)
i.bind()
i.getLoggerEngine.pushLogger(logger)
i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log))
i
}
// Must be the same file as is used in Update in the launcher
@ -83,24 +83,30 @@ final class IvySbt(val configuration: IvyConfiguration)
/** ========== End Configuration/Setup ============*/
/** Uses the configured Ivy instance within a safe context.*/
def withIvy[T](f: Ivy => T): T =
withDefaultLogger
def withIvy[T](log: Logger)(f: Ivy => T): T =
withIvy(new IvyLoggerInterface(log))(f)
def withIvy[T](log: MessageLogger)(f: Ivy => T): T =
withDefaultLogger(log)
{
ivy.pushContext()
ivy.getLoggerEngine.pushLogger(log)
try { f(ivy) }
finally { ivy.popContext() }
finally {
ivy.getLoggerEngine.popLogger()
ivy.popContext()
}
}
final class Module(rawModuleSettings: ModuleSettings)
{
val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings)
def owner = IvySbt.this
def logger = configuration.log
def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T =
withIvy[T] { ivy => f(ivy, moduleDescriptor0, defaultConfig0) }
def withModule[T](log: Logger)(f: (Ivy,DefaultModuleDescriptor,String) => T): T =
withIvy[T](log) { ivy => f(ivy, moduleDescriptor0, defaultConfig0) }
def moduleDescriptor = withModule((_,md,_) => md)
def defaultConfig = withModule( (_,_,dc) => dc)
def moduleDescriptor(log: Logger): DefaultModuleDescriptor = withModule(log)((_,md,_) => md)
def defaultConfig(log: Logger): String = withModule(log)( (_,_,dc) => dc)
// these should only be referenced by withModule because lazy vals synchronize on this object
// withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock
private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) =
@ -108,7 +114,7 @@ final class IvySbt(val configuration: IvyConfiguration)
val (baseModule, baseConfiguration) =
moduleSettings match
{
case ic: InlineConfiguration => configureInline(ic)
case ic: InlineConfiguration => configureInline(ic, configuration.log)
case ec: EmptyConfiguration => configureEmpty(ec.module)
case pc: PomConfiguration => readPom(pc.file, pc.validate)
case ifc: IvyFileConfiguration => readIvyFile(ifc.file, ifc.validate)
@ -117,7 +123,7 @@ final class IvySbt(val configuration: IvyConfiguration)
baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra")
(baseModule, baseConfiguration)
}
private def configureInline(ic: InlineConfiguration) =
private def configureInline(ic: InlineConfiguration, log: Logger) =
{
import ic._
val moduleID = newConfiguredModuleID(module, configurations)

View File

@ -39,12 +39,12 @@ object UpdateLogging extends Enumeration
object IvyActions
{
/** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/
def install(module: IvySbt#Module, from: String, to: String)
def install(module: IvySbt#Module, from: String, to: String, log: Logger)
{
module.withModule { (ivy, md, default) =>
module.withModule(log) { (ivy, md, default) =>
for(dependency <- md.getDependencies)
{
module.logger.info("Installing " + dependency)
log.info("Installing " + dependency)
val options = new InstallOptions
options.setValidate(module.moduleSettings.validate)
options.setTransitive(dependency.isTransitive)
@ -54,26 +54,26 @@ object IvyActions
}
/** Clears the Ivy cache, as configured by 'config'. */
def cleanCache(ivy: IvySbt) = ivy.withIvy { iv =>
def cleanCache(ivy: IvySbt, log: Logger) = ivy.withIvy(log) { iv =>
iv.getSettings.getResolutionCacheManager.clean()
iv.getSettings.getRepositoryCacheManagers.foreach(_.clean())
}
/** Creates a Maven pom from the given Ivy configuration*/
def makePom(module: IvySbt#Module, configuration: MakePomConfiguration)
def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger)
{
import configuration.{configurations, extra, file, filterRepositories, process}
module.withModule { (ivy, md, default) =>
module.withModule(log) { (ivy, md, default) =>
(new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, file)
module.logger.info("Wrote " + file.getAbsolutePath)
log.info("Wrote " + file.getAbsolutePath)
}
}
def deliver(module: IvySbt#Module, configuration: PublishConfiguration)
def deliver(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger)
{
import configuration._
import patterns._
module.withModule { case (ivy, md, default) =>
module.withModule(log) { case (ivy, md, default) =>
resolve(logging)(ivy, md, default) // todo: set download = false for resolve
val revID = md.getModuleRevisionId
val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status)
@ -85,11 +85,11 @@ object IvyActions
def getDeliverIvyPattern(patterns: PublishPatterns) = patterns.deliverIvyPattern.getOrElse(error("No Ivy pattern specified"))
// todo: map configurations, extra dependencies
def publish(module: IvySbt#Module, configuration: PublishConfiguration)
def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger)
{
import configuration._
import patterns._
module.withModule { case (ivy, md, default) =>
module.withModule(log) { case (ivy, md, default) =>
val revID = md.getModuleRevisionId
val patterns = new java.util.ArrayList[String]
srcArtifactPatterns.foreach(pattern => patterns.add(pattern))
@ -101,8 +101,8 @@ object IvyActions
}
/** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration.
* 'updateConfig' configures the actual resolution and retrieval process. */
def update(module: IvySbt#Module, configuration: UpdateConfiguration): UpdateReport =
module.withModule { case (ivy, md, default) =>
def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport =
module.withModule(log) { case (ivy, md, default) =>
val (report, err) = resolve(configuration.logging)(ivy, md, default)
err match
{
@ -117,23 +117,23 @@ object IvyActions
}
}
def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport =
def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport =
{
val base = id.copy(name = id.name + "$" + label)
val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala))
val report = update(module, c)
transitive(ivySbt, id, report, classifiers, c, ivyScala)
val report = update(module, c, log)
transitive(ivySbt, id, report, classifiers, c, ivyScala, log)
}
def transitive(ivySbt: IvySbt, module: ModuleID, report: UpdateReport, classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport =
updateClassifiers(ivySbt, module, report.allModules, classifiers, new UpdateConfiguration(c.retrieve, true, c.logging), ivyScala)
def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport =
def transitive(ivySbt: IvySbt, module: ModuleID, report: UpdateReport, classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport =
updateClassifiers(ivySbt, module, report.allModules, classifiers, new UpdateConfiguration(c.retrieve, true, c.logging), ivyScala, log)
def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport =
{
assert(!classifiers.isEmpty, "classifiers cannot be empty")
val baseModules = modules map { m => ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) }
val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact(m.name, c) }) }
val base = id.copy(name = id.name + classifiers.mkString("$","_",""))
val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala))
update(module, configuration)
update(module, configuration, log)
}
private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) =
{

View File

@ -74,7 +74,7 @@ object IvyCache
def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T =
{
val (ivy, local) = basicLocalIvy(lock, log)
ivy.withIvy { ivy =>
ivy.withIvy(log) { ivy =>
val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager]
cache.setUseOrigin(false)
f(cache)