sbt/ivy/IvyActions.scala

139 lines
6.1 KiB
Scala
Raw Normal View History

package sbt
2009-08-16 20:29:08 +02:00
import java.io.File
import scala.xml.NodeSeq
2009-08-16 20:29:08 +02:00
import org.apache.ivy.{core, plugins, util, Ivy}
import core.cache.DefaultRepositoryCacheManager
import core.LogOptions
import core.deliver.DeliverOptions
import core.install.InstallOptions
2009-08-16 20:29:08 +02:00
import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact}
import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor}
import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId}
import core.publish.PublishOptions
import core.resolve.ResolveOptions
import core.retrieve.RetrieveOptions
import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter}
final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean, val quiet: Boolean) extends NotNull
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)
2009-08-18 06:51:08 +02:00
{
module.withModule { (ivy, md, default) =>
for(dependency <- md.getDependencies)
{
module.logger.info("Installing " + dependency)
val options = new InstallOptions
options.setValidate(module.moduleSettings.validate)
options.setTransitive(dependency.isTransitive)
ivy.install(dependency.getDependencyRevisionId, from, to, options)
}
}
2009-08-18 06:51:08 +02:00
}
2009-08-16 20:29:08 +02:00
/** Clears the Ivy cache, as configured by 'config'. */
def cleanCache(ivy: IvySbt) = ivy.withIvy { iv =>
iv.getSettings.getResolutionCacheManager.clean()
iv.getSettings.getRepositoryCacheManagers.foreach(_.clean())
}
2009-08-16 20:29:08 +02:00
/** Creates a Maven pom from the given Ivy configuration*/
def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File)
2009-08-16 20:29:08 +02:00
{
module.withModule { (ivy, md, default) =>
addLateDependencies(ivy, md, default, extraDependencies)
val pomModule = keepConfigurations(md, configurations)
(new PomWriter).write(pomModule, extra, output)
2009-08-16 20:29:08 +02:00
module.logger.info("Wrote " + output.getAbsolutePath)
}
}
// todo: correct default configuration for extra dependencies
private def addLateDependencies(ivy: Ivy, module: DefaultModuleDescriptor, defaultConfiguration: String, extraDependencies: Iterable[ModuleID])
{
val parser = new CustomXmlParser.CustomParser(ivy.getSettings, Some(defaultConfiguration))
2009-08-16 20:29:08 +02:00
parser.setMd(module)
IvySbt.addDependencies(module, extraDependencies, parser)
}
private def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) =
configurations match
{
case Some(confs) => confs.map(_.name).toList.toArray
case None => module.getPublicConfigurationsNames
}
/** Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None.
* This currently only preserves the information required by makePom*/
private def keepConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): ModuleDescriptor =
{
val keepConfigurations = getConfigurations(module, configurations)
val keepSet = Set(keepConfigurations.toSeq : _*)
def translate(dependency: DependencyDescriptor) =
{
val keep = dependency.getModuleConfigurations.filter(keepSet.contains)
if(keep.isEmpty)
None
else // TODO: translate the dependency to contain only configurations to keep
Some(dependency)
}
val newModule = new DefaultModuleDescriptor(module.getModuleRevisionId, "", null)
newModule.setHomePage(module.getHomePage)
for(dependency <- module.getDependencies; translated <- translate(dependency))
newModule.addDependency(translated)
newModule
}
2009-08-16 20:29:08 +02:00
def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], quiet: Boolean)
{
module.withModule { case (ivy, md, default) =>
addLateDependencies(ivy, md, default, extraDependencies)
resolve(quiet)(ivy, md, default) // todo: set download = false for resolve
val revID = md.getModuleRevisionId
val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status)
options.setConfs(getConfigurations(md, configurations))
ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options)
}
}
// todo: map configurations, extra dependencies
def publish(module: IvySbt#Module, resolverName: String, srcArtifactPatterns: Iterable[String], deliveredIvyPattern: Option[String], configurations: Option[Iterable[Configuration]])
{
module.withModule { case (ivy, md, default) =>
val revID = md.getModuleRevisionId
val patterns = new java.util.ArrayList[String]
srcArtifactPatterns.foreach(pattern => patterns.add(pattern))
val options = (new PublishOptions).setOverwrite(true)
deliveredIvyPattern.foreach(options.setSrcIvyPattern)
options.setConfs(getConfigurations(md, configurations))
ivy.publish(revID, patterns, resolverName, options)
}
}
/** 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)
{
module.withModule { case (ivy, md, default) =>
import configuration._
resolve(quiet)(ivy, md, default)
val retrieveOptions = new RetrieveOptions
retrieveOptions.setSync(synchronize)
val patternBase = retrieveDirectory.getAbsolutePath
val pattern =
if(patternBase.endsWith(File.separator))
patternBase + outputPattern
else
patternBase + File.separatorChar + outputPattern
ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions)
}
}
private def resolve(quiet: Boolean)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String) =
{
val resolveOptions = new ResolveOptions
if(quiet)
resolveOptions.setLog(LogOptions.LOG_DOWNLOAD_ONLY)
val resolveReport = ivy.resolve(module, resolveOptions)
if(resolveReport.hasError)
error(Set(resolveReport.getAllProblemMessages.toArray: _*).mkString("\n"))
}
}