* Improved Ivy-related code to not load unnecessary default settings

* Moved repository order to be local, user repositories, Maven Central, and then Scala Tools



git-svn-id: https://simple-build-tool.googlecode.com/svn/trunk@951 d89573ee-9141-11dd-94d4-bdf5e562f29c
This commit is contained in:
dmharrah 2009-08-13 02:50:00 +00:00
parent b79de8d788
commit fb2aabadd7
4 changed files with 237 additions and 206 deletions

View File

@ -23,14 +23,12 @@ import core.resolve.ResolveOptions
import core.retrieve.RetrieveOptions import core.retrieve.RetrieveOptions
import core.settings.IvySettings import core.settings.IvySettings
import plugins.matcher.{ExactPatternMatcher, PatternMatcher} import plugins.matcher.{ExactPatternMatcher, PatternMatcher}
import plugins.parser.ModuleDescriptorParser
import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter}
import plugins.parser.xml.XmlModuleDescriptorParser import plugins.parser.xml.XmlModuleDescriptorParser
import plugins.repository.{BasicResource, Resource} import plugins.repository.{BasicResource, Resource}
import plugins.repository.url.URLResource import plugins.repository.url.URLResource
import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} import plugins.resolver.ChainResolver
import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} import util.Message
import util.{Message, MessageLogger}
final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) extends NotNull final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) extends NotNull
final class IvyPaths(val projectDirectory: Path, val managedLibDirectory: Path, val cacheDirectory: Option[Path]) extends NotNull final class IvyPaths(val projectDirectory: Path, val managedLibDirectory: Path, val cacheDirectory: Option[Path]) extends NotNull
@ -60,21 +58,25 @@ object ManageDependencies
private def withIvyValue[T](config: IvyConfiguration)(doWithIvy: (Ivy, ModuleDescriptor, String) => Either[String, T]) = private def withIvyValue[T](config: IvyConfiguration)(doWithIvy: (Ivy, ModuleDescriptor, String) => Either[String, T]) =
{ {
import config._ import config._
log.debug("\nwithIvyValue...\n")
val logger = new IvyLogger(log) val logger = new IvyLogger(log)
val originalLogger = Message.getDefaultLogger
Message.setDefaultLogger(logger) Message.setDefaultLogger(logger)
val ivy = Ivy.newInstance() log.debug("\nSet default logger...\n")
ivy.getLoggerEngine.pushLogger(logger) val settings = new IvySettings
settings.setBaseDir(paths.projectDirectory.asFile)
log.debug("\nCreated settings...\n")
/** Parses the given Maven pom 'pomFile'.*/ /** Parses the given Maven pom 'pomFile'.*/
def readPom(pomFile: File) = def readPom(pomFile: File) =
Control.trap("Could not read pom: ", log) Control.trap("Could not read pom: ", log)
{ Right((PomModuleDescriptorParser.getInstance.parseDescriptor(ivy.getSettings, toURL(pomFile), flags.validate)), "compile") } { Right((PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pomFile), flags.validate)), "compile") }
/** Parses the given Ivy file 'ivyFile'.*/ /** Parses the given Ivy file 'ivyFile'.*/
def readIvyFile(ivyFile: File) = def readIvyFile(ivyFile: File) =
Control.trap("Could not read Ivy file: ", log) Control.trap("Could not read Ivy file: ", log)
{ {
val url = toURL(ivyFile) val url = toURL(ivyFile)
val parser = new CustomXmlParser.CustomParser(ivy.getSettings) val parser = new CustomXmlParser.CustomParser(settings)
parser.setValidate(flags.validate) parser.setValidate(flags.validate)
parser.setSource(url) parser.setSource(url)
parser.parse() parser.parse()
@ -87,7 +89,7 @@ object ManageDependencies
def parseDependencies(xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String): Either[String, CustomXmlParser.CustomParser] = def parseDependencies(xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String): Either[String, CustomXmlParser.CustomParser] =
Control.trap("Could not read dependencies: ", log) Control.trap("Could not read dependencies: ", log)
{ {
val parser = new CustomXmlParser.CustomParser(ivy.getSettings) val parser = new CustomXmlParser.CustomParser(settings)
parser.setMd(moduleID) parser.setMd(moduleID)
parser.setDefaultConf(defaultConfiguration) parser.setDefaultConf(defaultConfiguration)
parser.setValidate(flags.validate) parser.setValidate(flags.validate)
@ -98,34 +100,27 @@ object ManageDependencies
Right(parser) Right(parser)
} }
/** Configures Ivy using the specified Ivy configuration file. This method is used when the manager is explicitly requested to be MavenManager or /** Configures Ivy using the specified Ivy configuration file. This method is used when the manager is explicitly requested to be MavenManager or
* IvyManager. If a file is not specified, Ivy is configured with defaults and scala-tools releases is added as a repository.*/ * IvyManager. If a file is not specified, Ivy is configured with defaults.*/
def configure(configFile: Option[Path]) def configure(configFile: Option[Path])
{ {
configFile match configFile match
{ {
case Some(path) => ivy.configure(path.asFile) case Some(path) => settings.load(path.asFile)
case None => case None => configureDefaults(defaultResolvers)
configureDefaults()
scalaTools()
}
}
/** Adds the scala-tools.org releases maven repository to the list of resolvers if configured to do so in IvyFlags.*/
def scalaTools()
{
if(flags.addScalaTools)
{
log.debug("Added Scala Tools Releases repository.")
addResolvers(ivy.getSettings, ScalaToolsReleases :: Nil, log)
} }
} }
def defaultResolvers: Seq[Resolver] = withDefaultResolvers(Nil)
def withDefaultResolvers(user: Seq[Resolver]): Seq[Resolver] =
Seq(Resolver.defaultLocal) ++
user ++
Seq(DefaultMavenRepository) ++
(if(flags.addScalaTools) Seq(ScalaToolsReleases) else Nil)
/** Configures Ivy using defaults. This is done when no ivy-settings.xml exists. */ /** Configures Ivy using defaults. This is done when no ivy-settings.xml exists. */
def configureDefaults() def configureDefaults(resolvers: Seq[Resolver])
{ {
ivy.configureDefault configureCache(settings, paths.cacheDirectory)
val settings = ivy.getSettings setResolvers(settings, resolvers, log)
for(dir <- paths.cacheDirectory) settings.setDefaultCache(dir.asFile)
settings.setBaseDir(paths.projectDirectory.asFile)
configureCache(settings)
} }
/** Called to configure Ivy when the configured dependency manager is SbtManager and inline configuration is specified or if the manager /** Called to configure Ivy when the configured dependency manager is SbtManager and inline configuration is specified or if the manager
* is AutodetectManager. It will configure Ivy with an 'ivy-settings.xml' file if there is one, or configure the defaults and add scala-tools as * is AutodetectManager. It will configure Ivy with an 'ivy-settings.xml' file if there is one, or configure the defaults and add scala-tools as
@ -135,12 +130,9 @@ object ManageDependencies
log.debug("Autodetecting configuration.") log.debug("Autodetecting configuration.")
val defaultIvyConfigFile = defaultIvyConfiguration(paths.projectDirectory).asFile val defaultIvyConfigFile = defaultIvyConfiguration(paths.projectDirectory).asFile
if(defaultIvyConfigFile.canRead) if(defaultIvyConfigFile.canRead)
ivy.configure(defaultIvyConfigFile) settings.load(defaultIvyConfigFile)
else else
{ configureDefaults(defaultResolvers)
configureDefaults()
scalaTools()
}
} }
/** Called to determine dependencies when the dependency manager is SbtManager and no inline dependencies (Scala or XML) are defined /** Called to determine dependencies when the dependency manager is SbtManager and no inline dependencies (Scala or XML) are defined
* or if the manager is AutodetectManager. It will try to read from pom.xml first and then ivy.xml if pom.xml is not found. If neither is found, * or if the manager is AutodetectManager. It will try to read from pom.xml first and then ivy.xml if pom.xml is not found. If neither is found,
@ -200,9 +192,7 @@ object ManageDependencies
else else
{ {
log.debug("Using inline repositories.") log.debug("Using inline repositories.")
configureDefaults() configureDefaults(withDefaultResolvers(resolvers))
val extra = if(flags.addScalaTools) resolvers ++ List(ScalaToolsReleases) else resolvers // user resolvers come before scala-tools
addResolvers(ivy.getSettings, extra, log)
} }
if(autodetect) if(autodetect)
autodetectDependencies(toID(module)) autodetectDependencies(toID(module))
@ -265,6 +255,8 @@ object ManageDependencies
this.synchronized // Ivy is not thread-safe. In particular, it uses a static DocumentBuilder, which is not thread-safe this.synchronized // Ivy is not thread-safe. In particular, it uses a static DocumentBuilder, which is not thread-safe
{ {
val ivy = Ivy.newInstance(settings)
ivy.getLoggerEngine.pushLogger(logger)
ivy.pushContext() ivy.pushContext()
try try
{ {
@ -273,7 +265,11 @@ object ManageDependencies
doWithIvy(ivy, md, conf) doWithIvy(ivy, md, conf)
} }
} }
finally { ivy.popContext() } finally
{
ivy.popContext()
Message.setDefaultLogger(originalLogger)
}
} }
} }
private def addExtraNamespaces(md: DefaultModuleDescriptor): Unit = private def addExtraNamespaces(md: DefaultModuleDescriptor): Unit =
@ -317,16 +313,14 @@ object ManageDependencies
excludeScalaJar(ScalaArtifacts.LibraryID) excludeScalaJar(ScalaArtifacts.LibraryID)
excludeScalaJar(ScalaArtifacts.CompilerID) excludeScalaJar(ScalaArtifacts.CompilerID)
} }
private def configureCache(settings: IvySettings) private def configureCache(settings: IvySettings, dir: Option[Path])
{ {
settings.getDefaultRepositoryCacheManager match val cacheDir = dir.map(_.asFile).getOrElse(settings.getDefaultRepositoryCacheBasedir())
{ val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir)
case manager: DefaultRepositoryCacheManager =>
manager.setUseOrigin(true) manager.setUseOrigin(true)
manager.setChangingMatcher(PatternMatcher.REGEXP); manager.setChangingMatcher(PatternMatcher.REGEXP);
manager.setChangingPattern(".*-SNAPSHOT"); manager.setChangingPattern(".*-SNAPSHOT");
case _ => () settings.setDefaultRepositoryCacheManager(manager)
}
} }
/** Creates an ExcludeRule that excludes artifacts with the given module organization and name for /** Creates an ExcludeRule that excludes artifacts with the given module organization and name for
* the given configurations. */ * the given configurations. */
@ -528,17 +522,18 @@ object ManageDependencies
moduleID.check() moduleID.check()
} }
/** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */ /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */
private def addResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: Logger) private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: Logger)
{ {
val newDefault = new ChainResolver val newDefault = new ChainResolver
newDefault.setName("redefined-public") newDefault.setName("sbt-chain")
newDefault.add(settings.getDefaultResolver) // put local, shared, and public(Maven Central) repositories before user repositories newDefault.setReturnFirst(true)
newDefault.setCheckmodified(true)
resolvers.foreach(r => newDefault.add(ConvertResolver(r))) resolvers.foreach(r => newDefault.add(ConvertResolver(r)))
settings.addResolver(newDefault) settings.addResolver(newDefault)
settings.setDefaultResolver(newDefault.getName) settings.setDefaultResolver(newDefault.getName)
if(log.atLevel(Level.Debug)) if(log.atLevel(Level.Debug))
{ {
log.debug("Using extra repositories:") log.debug("Using repositories:")
resolvers.foreach(r => log.debug("\t" + r.toString)) resolvers.foreach(r => log.debug("\t" + r.toString))
} }
} }
@ -596,157 +591,3 @@ object ManageDependencies
case _ => error("Unknown ModuleDescriptor type.") case _ => error("Unknown ModuleDescriptor type.")
} }
} }
private object ConvertResolver
{
/** Converts the given sbt resolver into an Ivy resolver..*/
def apply(r: Resolver) =
{
r match
{
case repo: MavenRepository =>
{
val resolver = new IBiblioResolver
initializeMavenStyle(resolver, repo.name, repo.root)
resolver
}
case JavaNet1Repository =>
{
// Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy:
// http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html
val resolver = new IBiblioResolver { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid }
initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/")
resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]")
resolver
}
case repo: SshRepository =>
{
val resolver = new SshResolver
initializeSSHResolver(resolver, repo)
repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm))
resolver
}
case repo: SftpRepository =>
{
val resolver = new SFTPResolver
initializeSSHResolver(resolver, repo)
resolver
}
case repo: FileRepository =>
{
val resolver = new FileSystemResolver
resolver.setName(repo.name)
initializePatterns(resolver, repo.patterns)
import repo.configuration.{isLocal, isTransactional}
resolver.setLocal(isLocal)
isTransactional.foreach(value => resolver.setTransactional(value.toString))
resolver
}
case repo: URLRepository =>
{
val resolver = new URLResolver
resolver.setName(repo.name)
initializePatterns(resolver, repo.patterns)
resolver
}
}
}
private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String)
{
resolver.setName(name)
resolver.setM2compatible(true)
resolver.setRoot(root)
}
private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository)
{
resolver.setName(repo.name)
resolver.setPassfile(null)
initializePatterns(resolver, repo.patterns)
initializeConnection(resolver, repo.connection)
}
private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection)
{
import resolver._
import connection._
hostname.foreach(setHost)
port.foreach(setPort)
authentication foreach
{
case RepositoryHelpers.PasswordAuthentication(user, password) =>
setUser(user)
setUserPassword(password)
case RepositoryHelpers.KeyFileAuthentication(file, password) =>
setKeyFile(file)
setKeyFilePassword(password)
}
}
private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: RepositoryHelpers.Patterns)
{
resolver.setM2compatible(patterns.isMavenCompatible)
patterns.ivyPatterns.foreach(resolver.addIvyPattern)
patterns.artifactPatterns.foreach(resolver.addArtifactPattern)
}
}
private object DefaultConfigurationMapping extends PomModuleDescriptorWriter.ConfigurationScopeMapping(new java.util.HashMap)
{
override def getScope(confs: Array[String]) =
{
Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match
{
case Some(conf) => conf.name
case None =>
if(confs.isEmpty || confs(0) == Configurations.Default.name)
null
else
confs(0)
}
}
override def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name)
}
/** Interface between Ivy logging and sbt logging. */
private final class IvyLogger(log: Logger) extends MessageLogger
{
private var progressEnabled = false
def log(msg: String, level: Int)
{
import Message.{MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR}
level match
{
case MSG_DEBUG | MSG_VERBOSE => debug(msg)
case MSG_INFO => info(msg)
case MSG_WARN => warn(msg)
case MSG_ERR => error(msg)
}
}
def rawlog(msg: String, level: Int)
{
log(msg, level)
}
import Level.{Debug, Info, Warn, Error}
def debug(msg: String) = logImpl(msg, Debug)
def verbose(msg: String) = debug(msg)
def deprecated(msg: String) = warn(msg)
def info(msg: String) = logImpl(msg, Info)
def rawinfo(msg: String) = info(msg)
def warn(msg: String) = logImpl(msg, Warn)
def error(msg: String) = logImpl(msg, Error)
private def logImpl(msg: String, level: Level.Value) = log.log(level, msg)
private def emptyList = java.util.Collections.emptyList[T forSome { type T}]
def getProblems = emptyList
def getWarns = emptyList
def getErrors = emptyList
def clearProblems = ()
def sumupProblems = ()
def progress = ()
def endProgress = ()
def endProgress(msg: String) = info(msg)
def isShowProgress = false
def setShowProgress(progress: Boolean) {}
}

View File

@ -173,7 +173,7 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern
import Resolver._ import Resolver._
object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot)
object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot)
object DefaultMavenRepository extends MavenRepository("Maven2 Repository", IBiblioResolver.DEFAULT_M2_ROOT) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT)
object JavaNet1Repository extends Resolver object JavaNet1Repository extends Resolver
{ {
def name = "java.net Maven1 Repository" def name = "java.net Maven1 Repository"
@ -275,6 +275,20 @@ object Resolver
def defaultPatterns = mavenStylePatterns def defaultPatterns = mavenStylePatterns
def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"
def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
def userRoot = System.getProperty("user.home")
def userMavenRoot = userRoot + "/.m2/repository/"
def userIvyRoot = userRoot + "/.ivy2/"
def defaultLocal = defaultUserFileRepository("local")
def defaultShared = defaultUserFileRepository("shared")
def defaultUserFileRepository(id: String) = file(id, new File(userIvyRoot, id))(defaultIvyPatterns)
def defaultIvyPatterns =
{
val pList = List(localBasePattern)
Patterns(pList, pList, false)
}
} }
object Configurations object Configurations

View File

@ -0,0 +1,100 @@
/* sbt -- Simple Build Tool
* Copyright 2008, 2009 Mark Harrah
*/
package sbt
import org.apache.ivy.{core,plugins}
import core.module.id.ModuleRevisionId
import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver}
import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver}
private object ConvertResolver
{
/** Converts the given sbt resolver into an Ivy resolver..*/
def apply(r: Resolver) =
{
r match
{
case repo: MavenRepository =>
{
val resolver = new IBiblioResolver
initializeMavenStyle(resolver, repo.name, repo.root)
resolver
}
case JavaNet1Repository =>
{
// Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy:
// http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html
val resolver = new IBiblioResolver { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid }
initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/")
resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]")
resolver
}
case repo: SshRepository =>
{
val resolver = new SshResolver
initializeSSHResolver(resolver, repo)
repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm))
resolver
}
case repo: SftpRepository =>
{
val resolver = new SFTPResolver
initializeSSHResolver(resolver, repo)
resolver
}
case repo: FileRepository =>
{
val resolver = new FileSystemResolver
resolver.setName(repo.name)
initializePatterns(resolver, repo.patterns)
import repo.configuration.{isLocal, isTransactional}
resolver.setLocal(isLocal)
isTransactional.foreach(value => resolver.setTransactional(value.toString))
resolver
}
case repo: URLRepository =>
{
val resolver = new URLResolver
resolver.setName(repo.name)
initializePatterns(resolver, repo.patterns)
resolver
}
}
}
private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String)
{
resolver.setName(name)
resolver.setM2compatible(true)
resolver.setRoot(root)
}
private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository)
{
resolver.setName(repo.name)
resolver.setPassfile(null)
initializePatterns(resolver, repo.patterns)
initializeConnection(resolver, repo.connection)
}
private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection)
{
import resolver._
import connection._
hostname.foreach(setHost)
port.foreach(setPort)
authentication foreach
{
case RepositoryHelpers.PasswordAuthentication(user, password) =>
setUser(user)
setUserPassword(password)
case RepositoryHelpers.KeyFileAuthentication(file, password) =>
setKeyFile(file)
setKeyFilePassword(password)
}
}
private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: RepositoryHelpers.Patterns)
{
resolver.setM2compatible(patterns.isMavenCompatible)
patterns.ivyPatterns.foreach(resolver.addIvyPattern)
patterns.artifactPatterns.foreach(resolver.addArtifactPattern)
}
}

View File

@ -0,0 +1,76 @@
/* sbt -- Simple Build Tool
* Copyright 2008, 2009 Mark Harrah
*/
package sbt
import org.apache.ivy.{plugins, util}
import plugins.parser.m2.PomModuleDescriptorWriter
import util.{Message, MessageLogger}
private object DefaultConfigurationMapping extends PomModuleDescriptorWriter.ConfigurationScopeMapping(new java.util.HashMap)
{
override def getScope(confs: Array[String]) =
{
Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match
{
case Some(conf) => conf.name
case None =>
if(confs.isEmpty || confs(0) == Configurations.Default.name)
null
else
confs(0)
}
}
override def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name)
}
/** Interface between Ivy logging and sbt logging. */
private final class IvyLogger(log: Logger) extends MessageLogger
{
private var progressEnabled = false
def log(msg: String, level: Int)
{
import Message.{MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR}
level match
{
case MSG_DEBUG | MSG_VERBOSE => debug(msg)
case MSG_INFO => info(msg)
case MSG_WARN => warn(msg)
case MSG_ERR => error(msg)
}
}
def rawlog(msg: String, level: Int)
{
log(msg, level)
}
import Level.{Debug, Info, Warn, Error}
def debug(msg: String) = logImpl(msg, Debug)
def verbose(msg: String) = debug(msg)
def deprecated(msg: String) = warn(msg)
def info(msg: String) =
{
if(msg contains ":: loading settings :: url =")
Thread.dumpStack
logImpl(msg, Info)
}
def rawinfo(msg: String) = info(msg)
def warn(msg: String) = logImpl(msg, Warn)
def error(msg: String) = logImpl(msg, Error)
private def logImpl(msg: String, level: Level.Value) = log.log(level, msg)
private def emptyList = java.util.Collections.emptyList[T forSome { type T}]
def getProblems = emptyList
def getWarns = emptyList
def getErrors = emptyList
def clearProblems = ()
def sumupProblems = ()
def progress = ()
def endProgress = ()
def endProgress(msg: String) = info(msg)
def isShowProgress = false
def setShowProgress(progress: Boolean) {}
}