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

View File

@ -39,12 +39,12 @@ object UpdateLogging extends Enumeration
object IvyActions object IvyActions
{ {
/** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ /** 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) for(dependency <- md.getDependencies)
{ {
module.logger.info("Installing " + dependency) log.info("Installing " + dependency)
val options = new InstallOptions val options = new InstallOptions
options.setValidate(module.moduleSettings.validate) options.setValidate(module.moduleSettings.validate)
options.setTransitive(dependency.isTransitive) options.setTransitive(dependency.isTransitive)
@ -54,26 +54,26 @@ object IvyActions
} }
/** Clears the Ivy cache, as configured by 'config'. */ /** 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.getResolutionCacheManager.clean()
iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) iv.getSettings.getRepositoryCacheManagers.foreach(_.clean())
} }
/** Creates a Maven pom from the given Ivy configuration*/ /** 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} 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) (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 configuration._
import patterns._ 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 resolve(logging)(ivy, md, default) // todo: set download = false for resolve
val revID = md.getModuleRevisionId val revID = md.getModuleRevisionId
val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) 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")) def getDeliverIvyPattern(patterns: PublishPatterns) = patterns.deliverIvyPattern.getOrElse(error("No Ivy pattern specified"))
// todo: map configurations, extra dependencies // todo: map configurations, extra dependencies
def publish(module: IvySbt#Module, configuration: PublishConfiguration) def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger)
{ {
import configuration._ import configuration._
import patterns._ import patterns._
module.withModule { case (ivy, md, default) => module.withModule(log) { case (ivy, md, default) =>
val revID = md.getModuleRevisionId val revID = md.getModuleRevisionId
val patterns = new java.util.ArrayList[String] val patterns = new java.util.ArrayList[String]
srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) 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. /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration.
* 'updateConfig' configures the actual resolution and retrieval process. */ * 'updateConfig' configures the actual resolution and retrieval process. */
def update(module: IvySbt#Module, configuration: UpdateConfiguration): UpdateReport = def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport =
module.withModule { case (ivy, md, default) => module.withModule(log) { case (ivy, md, default) =>
val (report, err) = resolve(configuration.logging)(ivy, md, default) val (report, err) = resolve(configuration.logging)(ivy, md, default)
err match 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 base = id.copy(name = id.name + "$" + label)
val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala))
val report = update(module, c) val report = update(module, c, log)
transitive(ivySbt, id, report, classifiers, c, ivyScala) 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 = 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) 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]): UpdateReport = 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") assert(!classifiers.isEmpty, "classifiers cannot be empty")
val baseModules = modules map { m => ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) } 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 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 base = id.copy(name = id.name + classifiers.mkString("$","_",""))
val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) 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]) = 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 = def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T =
{ {
val (ivy, local) = basicLocalIvy(lock, log) val (ivy, local) = basicLocalIvy(lock, log)
ivy.withIvy { ivy => ivy.withIvy(log) { ivy =>
val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager]
cache.setUseOrigin(false) cache.setUseOrigin(false)
f(cache) f(cache)