diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 419f41a56..657cdd65c 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -231,20 +231,24 @@ object IvyActions { throw w.resolveException } val newConfig = config.copy(module = mod.copy(modules = report.allModules)) - updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, log, ???) + updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, Vector(), log) } @deprecated("This is no longer public.", "0.13.6") def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = - updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log, ???) + updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) + // artifacts can be obtained from calling toSeq on UpdateReport private[sbt] def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger, upd: UpdateReport): UpdateReport = + uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], + artifacts: Vector[(String, ModuleID, Artifact, File)], + log: Logger): UpdateReport = { import config.{ configuration => c, module => mod, _ } import mod.{ configurations => confs, _ } assert(classifiers.nonEmpty, "classifiers cannot be empty") val baseModules = modules map { m => restrictedCopy(m, true) } - val deps = baseModules.distinct flatMap classifiedArtifacts(upd, exclude) //classifiedArtifacts(classifiers, exclude) + // Adding list of explicit artifacts here. + val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) @@ -254,14 +258,21 @@ object IvyActions { throw w.resolveException } } - def classifiedArtifacts(updateReport: UpdateReport, exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = { + // This version adds explicit artifact + private[sbt] def classifiedArtifacts(classifiers: Seq[String], + exclude: Map[ModuleID, Set[String]], + artifacts: Vector[(String, ModuleID, Artifact, File)])(m: ModuleID): Option[ModuleID] = { def sameModule(m1: ModuleID, m2: ModuleID): Boolean = m1.organization == m2.organization && m1.name == m2.name && m1.revision == m2.revision - updateReport.toSeq.groupBy(_._2) collectFirst { - case (k, v) if sameModule(k, m) => - val arts = v.collect { case (_, _, art, _) if art.classifier.isDefined => art }.distinct - m.copy(isTransitive = false, explicitArtifacts = arts) - } + def explicitArtifacts = + { + val arts = (artifacts collect { case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art }).distinct + if (arts.isEmpty) None + else Some(m.copy(isTransitive = false, explicitArtifacts = arts)) + } + def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) + explicitArtifacts orElse hardcodedArtifacts } + @deprecated("This is no longer public.", "0.13.10") def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = { val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index d7d364b47..6cb401c5f 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -200,7 +200,21 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString /** All resolved modules in all configurations. */ - def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct + def allModules: Seq[ModuleID] = + { + val key = (m: ModuleID) => (m.organization, m.name, m.revision) + configurations.flatMap(_.allModules).groupBy(key).toSeq map { + case (k, v) => + v reduceLeft { (agg, x) => + agg.copy( + configurations = (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + }) + } + } + } def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = new UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 24baf2d34..55730060c 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1234,7 +1234,8 @@ object Classpaths { val uwConfig = (unresolvedWarningConfiguration in update).value val logicalClock = LogicalClock(state.value.hashCode) val depDir = dependencyCacheDirectory.value - IvyActions.updateClassifiers(is, GetClassifiersConfiguration(mod, excludes, c, ivyScala.value), uwConfig, LogicalClock(state.value.hashCode), Some(depDir), s.log, update.value) + val artifacts = update.value.toSeq.toVector + IvyActions.updateClassifiers(is, GetClassifiersConfiguration(mod, excludes, c, ivyScala.value), uwConfig, LogicalClock(state.value.hashCode), Some(depDir), artifacts, s.log) } } tag (Tags.Update, Tags.Network) ) diff --git a/notes/0.13.10/fix-updateclassifiers-configuration.markdown b/notes/0.13.10/fix-updateclassifiers-configuration.markdown new file mode 100644 index 000000000..b69053d5a --- /dev/null +++ b/notes/0.13.10/fix-updateclassifiers-configuration.markdown @@ -0,0 +1,13 @@ + + [@eed3si9n]: https://github.com/eed3si9n + [@Duhemm]: https://github.com/Duhemm + [2264]: https://github.com/sbt/sbt/issues/2264 + +### Fixes with compatibility implications + +### Improvements + +### Bug fixes + +- Fixes `updateClassifiers` on Ivy modules without `default` configuration. + [#2264][2264] by [@eed3si9n][@eed3si9n]/[@Duhemm][@Duhemm]