diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 93ab5e94b..20d3fd5e5 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -13,7 +13,7 @@ import CS.singleton import org.apache.ivy.{core, plugins, util, Ivy} import core.{IvyPatternHelper, LogOptions} -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} +import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ResolutionCacheManager} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.descriptor.{OverrideDependencyDescriptorMediator} @@ -72,7 +72,7 @@ final class IvySbt(val configuration: IvyConfiguration) case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach is.setDefaultIvyUserDir - IvySbt.configureCache(is, i.localOnly) + IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) } @@ -277,8 +277,17 @@ private object IvySbt settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } } - private def configureCache(settings: IvySettings, localOnly: Boolean) + private[sbt] def cleanResolutionCache(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) { + val files = + Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: + Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: + Option(manager.getConfigurationResolveReportsInCache(resolveId)).toList.flatten + IO.delete(files) + } + private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) + { + resCacheDir foreach { dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath) } val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a2d040a97..8bb952d06 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -201,7 +201,10 @@ object IvyActions private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions + val resolveId = ResolveOptions.getDefaultResolveId(module) + resolveOptions.setResolveId(resolveId) resolveOptions.setLog(ivyLogLevel(logging)) + IvySbt.cleanResolutionCache(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) val resolveReport = ivy.resolve(module, resolveOptions) val err = if(resolveReport.hasError) diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index ff4b57bac..1a22a9977 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -86,7 +86,7 @@ class IvyCache(val ivyHome: Option[File]) { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index d2a5c958c..4d93d8722 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -21,12 +21,18 @@ sealed trait IvyConfiguration } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val checksums: Seq[String], val log: Logger) extends IvyConfiguration + val checksums: Seq[String], val resolutionCacheDir: Option[File], val log: Logger) extends IvyConfiguration { + @deprecated("Use the variant that accepts the resolution cache location.", "0.13.0") + def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], + moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], + checksums: Seq[String], log: Logger) = + this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, log) + type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) - def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) + def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val log: Logger) extends IvyConfiguration { @@ -50,7 +56,7 @@ object IvyConfiguration if(defaultIvyConfigFile.canRead) ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, log) + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, None, log) } } diff --git a/main/Defaults.scala b/main/Defaults.scala index dc7e95af8..82a97d5f0 100755 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -900,8 +900,9 @@ object Classpaths val explicit = struct.units(ref.build).unit.plugins.pluginData.resolvers explicit orElse bootRepositories(ac) getOrElse defaultRs }, - ivyConfiguration <<= (externalResolvers, ivyPaths, offline, checksums, appConfiguration, streams) map { (rs, paths, off, check, app, s) => - new InlineIvyConfiguration(paths, rs, Nil, Nil, off, Option(lock(app)), check, s.log) + ivyConfiguration <<= (externalResolvers, ivyPaths, offline, checksums, appConfiguration, target, streams) map { (rs, paths, off, check, app, t, s) => + val resCacheDir = t / "resolution-cache" + new InlineIvyConfiguration(paths, rs, Nil, Nil, off, Option(lock(app)), check, Some(resCacheDir), s.log) }, ivySbt <<= ivySbt0, classifiersModule <<= (projectID, sbtDependency, transitiveClassifiers, loadedBuild, thisProjectRef) map { ( pid, sbtDep, classifiers, lb, ref) => @@ -1042,9 +1043,10 @@ object Classpaths def unmanagedDependencies: Initialize[Task[Classpath]] = (thisProjectRef, configuration, settings, buildDependencies) flatMap unmanagedDependencies0 def mkIvyConfiguration: Initialize[Task[IvyConfiguration]] = - (fullResolvers, ivyPaths, otherResolvers, moduleConfigurations, offline, checksums in update, appConfiguration, streams) map { (rs, paths, other, moduleConfs, off, check, app, s) => + (fullResolvers, ivyPaths, otherResolvers, moduleConfigurations, offline, checksums in update, appConfiguration, target, streams) map { (rs, paths, other, moduleConfs, off, check, app, t, s) => warnResolversConflict(rs ++: other, s.log) - new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, Some(lock(app)), check, s.log) + val resCacheDir = t / "resolution-cache" + new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, Some(lock(app)), check, Some(resCacheDir), s.log) } import java.util.LinkedHashSet