mirror of https://github.com/sbt/sbt.git
Fixes #2264. Use explicit artifacts if any, fallback to hardcoded
Even though it's not really used, updateClassifiers constructs
dependency graph based on the result from update.
The direct cause of #2264 came from the fact that the `allModules`
returned from ConfigurationReport did not include dependency
configurations. For example it returned "compile" instead of
"compile->runtime". I've identified that in #2264 and was fixed by
@Duhemm in f49fb33e6d.
Martin identified that the fix still does not address the fact that
updateClassifier hardcodes the classifiers to be tried. This commit
adds the fallback behavior so for Ivy-published modules it will use the
explicit list of artifacts, and for others it will fallback to the
hardcoded list of classifiers.
This commit is contained in:
parent
13410ca68e
commit
3a3965b5f5
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
Loading…
Reference in New Issue