Allow user to suppress eviction errors for a specific library

... even if they would result in an incompatible eviction
based on the assumed version scheme.
This commit is contained in:
Adriaan Moors 2023-05-04 21:04:29 +02:00
parent 87f8089ba8
commit 998df8b692
1 changed files with 30 additions and 22 deletions

View File

@ -88,35 +88,43 @@ object EvictionError {
// https://github.com/sbt/sbt/issues/4946
case p if p.winner.isDefined =>
val winner = p.winner.get
def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") =
userDefinedSchemes.get((org, mod))
def fromWinnerPom = VersionSchemes.extractFromExtraAttributes(
winner.extraAttributes.toMap ++ winner.module.extraAttributes
)
// prioritize user-defined version scheme to allow overriding the real scheme
val userDefinedSchemeOrFromPom =
fromLibraryDependencySchemes(p.organization, p.name)
.orElse(fromLibraryDependencySchemes(p.organization))
.orElse(fromWinnerPom)
.orElse(fromLibraryDependencySchemes())
val assumedScheme =
if (isNameScalaSuffixed(p.name)) assumedVersionScheme
else assumedVersionSchemeJava
def hasIncompatibleVersionForScheme(scheme: String) = {
val isCompat =
VersionSchemes.evalFunc(scheme)
val isCompat = VersionSchemes.evalFunc(scheme)
p.evicteds.exists { r =>
!isCompat((r.module, Some(winner.module), module.scalaModuleInfo))
}
}
val userDefinedSchemeOrAlways = userDefinedSchemeOrFromPom.getOrElse(VersionSchemes.Always)
if (hasIncompatibleVersionForScheme(userDefinedSchemeOrAlways))
incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?"))
else if (hasIncompatibleVersionForScheme(assumedScheme))
assumedIncompatEvictions += (p -> assumedScheme)
// from libraryDependencyScheme or defined in the pom using the `info.versionScheme` attribute
val userDefinedSchemeOrFromPom = {
def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") =
userDefinedSchemes.get((org, mod))
def fromWinnerPom = VersionSchemes.extractFromExtraAttributes(
winner.extraAttributes.toMap ++ winner.module.extraAttributes
)
fromLibraryDependencySchemes(p.organization, p.name) // by org and name
.orElse(fromLibraryDependencySchemes(p.organization)) // for whole org
.orElse(fromWinnerPom) // from pom
.orElse(fromLibraryDependencySchemes()) // global
}
// We want the user to be able to suppress eviction errors for a specific library,
// which would result in an incompatible eviction based on the assumed version scheme.
// So, only fall back to the assumed scheme if there is no given scheme by the user or the pom.
userDefinedSchemeOrFromPom match {
case Some(givenScheme) =>
if (hasIncompatibleVersionForScheme(givenScheme))
incompatibleEvictions += (p -> givenScheme)
case None =>
val assumedScheme =
if (isNameScalaSuffixed(p.name)) assumedVersionScheme
else assumedVersionSchemeJava
if (hasIncompatibleVersionForScheme(assumedScheme))
assumedIncompatEvictions += (p -> assumedScheme)
}
case _ => ()
}