From 998df8b692415bdfad5bb6af2a4853dcb45e0967 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH] 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. --- .../sbt/librarymanagement/EvictionError.scala | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 9711a4d6f..27333fb2f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -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 _ => () }