From 0f28164b53c2e68f39036c602c9a71836c4be017 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 15 Jan 2013 08:21:53 -0500 Subject: [PATCH] Invalidate artifacts not recorded in the original metadata when a module marked as changing changes. Fixes #637, #641. --- ivy/src/main/scala/sbt/Ivy.scala | 34 +++++++++++++++++-- .../cache-classifiers/a/build.sbt | 9 +++++ .../cache-classifiers/b/build.sbt | 4 +++ .../cache-classifiers/changes/A.scala | 1 + .../cache-classifiers/changes/B.scala | 3 ++ .../cache-classifiers/multi.sbt | 3 ++ .../cache-classifiers/test | 12 +++++++ 7 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 sbt/src/sbt-test/dependency-management/cache-classifiers/a/build.sbt create mode 100644 sbt/src/sbt-test/dependency-management/cache-classifiers/b/build.sbt create mode 100644 sbt/src/sbt-test/dependency-management/cache-classifiers/changes/A.scala create mode 100644 sbt/src/sbt-test/dependency-management/cache-classifiers/changes/B.scala create mode 100644 sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt create mode 100644 sbt/src/sbt-test/dependency-management/cache-classifiers/test diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 0414cb0c5..9260f3ed1 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -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) diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/a/build.sbt b/sbt/src/sbt-test/dependency-management/cache-classifiers/a/build.sbt new file mode 100644 index 000000000..66e3e8487 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/a/build.sbt @@ -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")) diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/b/build.sbt b/sbt/src/sbt-test/dependency-management/cache-classifiers/b/build.sbt new file mode 100644 index 000000000..4e94e4922 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/b/build.sbt @@ -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 ) + diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/changes/A.scala b/sbt/src/sbt-test/dependency-management/cache-classifiers/changes/A.scala new file mode 100644 index 000000000..6ea495dda --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/changes/A.scala @@ -0,0 +1 @@ +object A { val x = 3 } diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/changes/B.scala b/sbt/src/sbt-test/dependency-management/cache-classifiers/changes/B.scala new file mode 100644 index 000000000..6ba7a4620 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/changes/B.scala @@ -0,0 +1,3 @@ +object B { + val y = A.x +} diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt b/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt new file mode 100644 index 000000000..167a22186 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt @@ -0,0 +1,3 @@ +val b = project + +val a = project diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/test b/sbt/src/sbt-test/dependency-management/cache-classifiers/test new file mode 100644 index 000000000..f3e1d1300 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/test @@ -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