diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index b566258a5..9b90d007b 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import scala.xml.{Node,NodeSeq} -import org.apache.ivy.{core, plugins, util, Ivy} +import org.apache.ivy.{core, plugins, Ivy} import core.cache.DefaultRepositoryCacheManager import core.LogOptions import core.deliver.DeliverOptions @@ -15,6 +15,7 @@ import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescrip import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.publish.PublishOptions +import core.report.ResolveReport import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} @@ -103,12 +104,18 @@ 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) + def update(module: IvySbt#Module, configuration: UpdateConfiguration) = { module.withModule { case (ivy, md, default) => import configuration._ - resolve(logging)(ivy, md, default) - val retrieveOptions = new RetrieveOptions + val report = resolve(logging)(ivy, md, default) + import IvyRetrieve._ + /*if(synchronize) + IO delete retrieveDirectory + IO createDirectory retrieveDirectory + retrieve( cachePaths(report), , retrieveDirectory)*/ + cachePaths(report) + /*val retrieveOptions = new RetrieveOptions retrieveOptions.setSync(synchronize) val patternBase = retrieveDirectory.getAbsolutePath val pattern = @@ -116,16 +123,17 @@ object IvyActions patternBase + outputPattern else patternBase + File.separatorChar + outputPattern - ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions) + ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions)*/ } } - private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String) = + private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): ResolveReport = { val resolveOptions = new ResolveOptions resolveOptions.setLog(ivyLogLevel(logging)) val resolveReport = ivy.resolve(module, resolveOptions) if(resolveReport.hasError) throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct) + resolveReport } import UpdateLogging.{Quiet, Full, DownloadOnly} diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala new file mode 100644 index 000000000..cfa384f7a --- /dev/null +++ b/ivy/IvyRetrieve.scala @@ -0,0 +1,46 @@ +/* sbt -- Simple Build Tool + * Copyright 2010 Mark Harrah + */ +package sbt + +import java.io.File + +import org.apache.ivy.core.{module, report} +import module.id.ModuleRevisionId +import report.{ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport} + +object IvyRetrieve +{ + def reports(report: ResolveReport): Map[String, ConfigurationResolveReport] = + ( for( conf <- report.getConfigurations) yield (conf, report.getConfigurationReport(conf)) ).toMap + + def artifactReports(confReport: ConfigurationResolveReport): Seq[ArtifactDownloadReport] = + { + val all = new scala.collection.mutable.HashSet[ArtifactDownloadReport] + for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) + all ++= confReport.getDownloadReports(revId) + all.toSeq + } + + def cachePath(reports: Seq[ArtifactDownloadReport]): Seq[File] = + reports map( _.getLocalFile ) + + def cachePaths(report: ResolveReport): Map[String, Seq[File]] = + reports(report).mapValues(confReport => cachePath(artifactReports(confReport))) + + def copy(files: Set[File], cacheBase: File, to: File): Map[File, File] = + { + import Path._ + val copyDef = files x rebase(cacheBase, to) + IO.copy( copyDef, overwrite = true, preserveLastModified = true ) + copyDef.toMap + } + + // TODO: not a sufficient way to do it: cacheBase is not necessarily common to all files + def retrieve(result: Map[String, Seq[File]], cacheBase: File, to: File): Map[String, Seq[File]] = + { + val all = result.values.flatten.toSet + val copyMap = copy(all, cacheBase, to) + result mapValues (_ map copyMap) + } +} \ No newline at end of file diff --git a/project/build/XSbt.scala b/project/build/XSbt.scala index 934c44eca..f84a8e821 100644 --- a/project/build/XSbt.scala +++ b/project/build/XSbt.scala @@ -26,7 +26,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths val envSub= baseProject(utilPath / "env", "Properties", ioSub, logSub, classpathSub) // intermediate-level modules - val ivySub = project("ivy", "Ivy", new IvyProject(_), interfaceSub, launchInterfaceSub, logSub) + val ivySub = project("ivy", "Ivy", new IvyProject(_), interfaceSub, launchInterfaceSub, logSub, ioSub) val testingSub = project("testing", "Testing", new TestingProject(_), ioSub, classpathSub, logSub) val taskSub = testedBase(tasksPath, "Tasks", controlSub, collectionSub) val cacheSub = project(cachePath, "Cache", new CacheProject(_), ioSub, collectionSub)