diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index bc4bd61fd..3fa3c5476 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -31,7 +31,9 @@ final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value = this.logging): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging) } -final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) +final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean) { + def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false) +} final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) // exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) @@ -177,7 +179,7 @@ object IvyActions { Left(UnresolvedWarning(x, uwconfig)) case Right(uReport) => configuration.retrieve match { - case Some(rConf) => Right(retrieve(ivy, uReport, rConf)) + case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) case None => Right(uReport) } } @@ -193,7 +195,7 @@ object IvyActions { val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) configuration.retrieve match { - case Some(rConf) => Right(retrieve(ivy, uReport, rConf)) + case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) case None => Right(uReport) } } @@ -292,11 +294,12 @@ object IvyActions { } else None (resolveReport, err) } - private def retrieve(ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = - retrieve(ivy, report, config.retrieveDirectory, config.outputPattern) + private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = + retrieve(log, ivy, report, config.retrieveDirectory, config.outputPattern, config.sync) - private def retrieve(ivy: Ivy, report: UpdateReport, base: File, pattern: String): UpdateReport = + private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, base: File, pattern: String, sync: Boolean): UpdateReport = { + val existingFiles = PathFinder(base).***.get filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf, mid, art, cached) => val to = retrieveTarget(conf, mid, art, base, pattern) @@ -304,6 +307,15 @@ object IvyActions { to } IO.copy(toCopy) + val resolvedFiles = toCopy.map(_._2) + if (sync) { + val filesToDelete = existingFiles.filterNot(resolvedFiles.contains) + filesToDelete foreach { f => + log.info(s"Deleting old dependency: ${f.getAbsolutePath}") + f.delete() + } + } + retReport } private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index 1be01ab25..00cbfc013 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -54,7 +54,7 @@ trait BaseIvySpecification extends Specification { def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) - val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern) + val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false) val config = new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full) IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 44b4062c5..5dc348471 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -99,6 +99,7 @@ object Defaults extends BuildCommon { credentials :== Nil, exportJars :== false, retrieveManaged :== false, + retrieveManagedSync :== false, scalaOrganization :== ScalaArtifacts.Organization, sbtResolver := { if (sbtVersion.value endsWith "-SNAPSHOT") Classpaths.typesafeSnapshots else Classpaths.typesafeReleases }, crossVersion :== CrossVersion.Disabled, @@ -1135,7 +1136,7 @@ object Classpaths { projectDescriptors <<= depMap, updateConfiguration := new UpdateConfiguration(retrieveConfiguration.value, false, ivyLoggingLevel.value), updateOptions := (updateOptions in Global).value, - retrieveConfiguration := { if (retrieveManaged.value) Some(new RetrieveConfiguration(managedDirectory.value, retrievePattern.value)) else None }, + retrieveConfiguration := { if (retrieveManaged.value) Some(new RetrieveConfiguration(managedDirectory.value, retrievePattern.value, retrieveManagedSync.value)) else None }, ivyConfiguration <<= mkIvyConfiguration, ivyConfigurations := { val confs = thisProject.value.configurations diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 03e8208e0..d14221061 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -316,6 +316,7 @@ object Keys { val projectDescriptors = TaskKey[Map[ModuleRevisionId, ModuleDescriptor]]("project-descriptors", "Project dependency map for the inter-project resolver.", DTask) val autoUpdate = SettingKey[Boolean]("auto-update", "", Invisible) val retrieveManaged = SettingKey[Boolean]("retrieve-managed", "If true, enables retrieving dependencies to the current build. Otherwise, dependencies are used directly from the cache.", BSetting) + val retrieveManagedSync = SettingKey[Boolean]("retrieve-managed-sync", "If true, enables synchronizing the dependencies retrieved to the current build by removed unneeded files.", BSetting) val managedDirectory = SettingKey[File]("managed-directory", "Directory to which managed dependencies are retrieved.", BSetting) val classpathTypes = SettingKey[Set[String]]("classpath-types", "Artifact types that are included on the classpath.", BSetting) val publishArtifact = SettingKey[Boolean]("publish-artifact", "Enables (true) or disables (false) publishing an artifact.", AMinusSetting) diff --git a/notes/0.13.9/retrievemanagedsync.markdown b/notes/0.13.9/retrievemanagedsync.markdown new file mode 100644 index 000000000..8c6dc33e9 --- /dev/null +++ b/notes/0.13.9/retrievemanagedsync.markdown @@ -0,0 +1,9 @@ + [@ajsquared]: https://github.com/ajsquared + + +### Changes with compatibility implications + +### Improvements +- Adds retrieveManagedSync key that, when set to true, enables synchronizing retrieved to the current build by removed unneeded files. By [@ajsquared][@ajsquared] + +### Fixes diff --git a/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/build.sbt b/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/build.sbt new file mode 100644 index 000000000..4568f6663 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/build.sbt @@ -0,0 +1,9 @@ +retrieveManaged := true + +libraryDependencies += "log4j" % "log4j" % "1.2.16" + +autoScalaLibrary := false + +managedDirectory := file("dependencies") + +retrievePattern := "[artifact]-[revision](-[classifier]).[ext]" \ No newline at end of file diff --git a/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/dependencies/notreal.jar b/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/dependencies/notreal.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/test b/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/test new file mode 100644 index 000000000..052f9b014 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/retrieve-managed-sync/test @@ -0,0 +1,7 @@ +$ exists dependencies/notreal.jar +> update + +$ exists dependencies/notreal.jar +> set retrieveManagedSync := true +> update +-$ exists dependencies/notreal.jar \ No newline at end of file