Invalidate artifacts not recorded in the original metadata when a module marked as changing changes. Fixes #637, #641.

This commit is contained in:
Mark Harrah 2013-01-15 08:21:53 -05:00
parent dd008e4dc5
commit 0f28164b53
7 changed files with 63 additions and 3 deletions

View File

@ -7,6 +7,7 @@ import Resolver.PluginPattern
import java.io.File
import java.net.URI
import java.text.ParseException
import java.util.concurrent.Callable
import java.util.{Collection, Collections => CS}
import CS.singleton
@ -23,7 +24,9 @@ import core.settings.IvySettings
import plugins.latest.LatestRevisionStrategy
import plugins.matcher.PatternMatcher
import plugins.parser.m2.PomModuleDescriptorParser
import plugins.repository.ResourceDownloader
import plugins.resolver.{ChainResolver, DependencyResolver}
import plugins.resolver.util.ResolvedResource
import util.{Message, MessageLogger}
import util.extendable.ExtendableItem
@ -327,17 +330,42 @@ private object IvySbt
}
}
}
/** This is overridden to delete outofdate artifacts of changing modules that are not listed in the metadata.
* This occurs for artifacts with classifiers, for example. */
@throws(classOf[ParseException])
override def cacheModuleDescriptor(resolver: DependencyResolver, mdRef: ResolvedResource, dd: DependencyDescriptor, moduleArtifact: IArtifact, downloader: ResourceDownloader, options: CacheMetadataOptions): ResolvedModuleRevision =
{
val rmr = super.cacheModuleDescriptor(resolver, mdRef, dd, moduleArtifact, downloader, options)
val mrid = moduleArtifact.getModuleRevisionId
// only handle changing modules whose metadata actually changed.
// Typically, the publication date in the metadata has to change to get here.
if(rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) {
// this is the locally cached metadata as originally retrieved (e.g. the pom)
val original = rmr.getReport.getOriginalLocalFile
if(original != null) {
// delete all files in subdirectories that are older than the original metadata file
val lm = original.lastModified
val indirectFiles = PathFinder(original.getParentFile).*(DirectoryFilter).**(-DirectoryFilter).get.toList
val older = indirectFiles.filter(f => f.lastModified < lm).toList
Message.verbose("Deleting additional old artifacts from cache for changed module " + mrid + older.mkString(":\n\t", "\n\t", ""))
IO.delete(older)
}
}
rmr
}
def isChanging(dd: DependencyDescriptor, requestedRevisionId: ModuleRevisionId): Boolean =
dd.isChanging || requestedRevisionId.getRevision.contains("-SNAPSHOT")
}
manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern)
manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern)
manager.setIvyPattern(PluginPattern + manager.getIvyPattern)
manager.setUseOrigin(true)
if(localOnly)
manager.setDefaultTTL(java.lang.Long.MAX_VALUE);
manager.setDefaultTTL(java.lang.Long.MAX_VALUE)
else
{
manager.setChangingMatcher(PatternMatcher.REGEXP);
manager.setChangingPattern(".*-SNAPSHOT");
manager.setChangingMatcher(PatternMatcher.REGEXP)
manager.setChangingPattern(".*-SNAPSHOT")
}
settings.addRepositoryCacheManager(manager)
settings.setDefaultRepositoryCacheManager(manager)

View File

@ -0,0 +1,9 @@
organization := "org.example"
name := "artifacta"
version := "1.0.0-SNAPSHOT"
publishArtifact in (Test,packageBin) := true
publishTo := Some(Resolver.file("demo", (baseDirectory in ThisBuild).value / "demo-repo"))

View File

@ -0,0 +1,4 @@
libraryDependencies += "org.example" %% "artifacta" % "1.0.0-SNAPSHOT" withSources() classifier("test") classifier("")
externalResolvers := Seq( "demo" at ( (baseDirectory in ThisBuild).value / "demo-repo").toURI.toString )

View File

@ -0,0 +1 @@
object A { val x = 3 }

View File

@ -0,0 +1,3 @@
object B {
val y = A.x
}

View File

@ -0,0 +1,3 @@
val b = project
val a = project

View File

@ -0,0 +1,12 @@
> a/publish
$ copy-file changes/B.scala b/B.scala
> b/update
-> b/test:compile
$ copy-file changes/A.scala a/src/test/scala/A.scala
> a/publish
-> b/test:compile
> b/update
> b/test:compile