[2.0.x] Prefer local ScalaModuleInfo over global config (#9028) (#9030)

Otherwise, a user will never be able to download scala library at any
other version.

Co-authored-by: Albert Meltzer <7529386+kitbellew@users.noreply.github.com>
This commit is contained in:
eugene yokota 2026-04-05 21:55:37 -04:00 committed by GitHub
parent 872985dcf4
commit 5469e046fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 138 additions and 21 deletions

View File

@ -150,13 +150,15 @@ class CoursierDependencyResolution(
sys.error(s"unrecognized ModuleDescriptor type: $module")
}
val soOpt = conf.scalaOrganization
.map(Organization(_))
.orElse(module0.scalaModuleInfo.map(m => Organization(m.scalaOrganization)))
val soOpt = module0.scalaModuleInfo
.map(_.scalaOrganization)
.orElse(conf.scalaOrganization)
.map(Organization.apply)
val so = soOpt.getOrElse(Organization("org.scala-lang"))
val sv = conf.scalaVersion
.orElse(module0.scalaModuleInfo.map(_.scalaFullVersion))
val sv = module0.scalaModuleInfo
.map(_.scalaFullVersion)
.orElse(conf.scalaVersion)
// FIXME Manage to do stuff below without a scala version?
.getOrElse(scala.util.Properties.versionNumberString)
@ -277,11 +279,13 @@ class CoursierDependencyResolution(
(coursier.Organization(strOrg), coursier.ModuleName(strName))
}.toSet
val autoScalaLib =
conf.autoScalaLibrary && module0.scalaModuleInfo.forall(_.overrideScalaVersion)
val resolutionParams = ResolutionParams(
dependencies = dependencies,
fallbackDependencies = conf.fallbackDependencies,
orderedConfigs = orderedConfigs,
autoScalaLibOpt = if (conf.autoScalaLibrary) Some((so, sv)) else None,
autoScalaLibOpt = if (autoScalaLib) Some((so, sv)) else None,
mainRepositories = mainRepositories,
parentProjectCache = Map.empty,
interProjectDependencies = interProjectDependencies,

View File

@ -2,16 +2,32 @@ package lmcoursier
import org.scalatest.matchers.should.Matchers
import org.scalatest.propspec.AnyPropSpec
import sbt.librarymanagement.ModuleID
import sbt.librarymanagement.UpdateConfiguration
import sbt.librarymanagement.UnresolvedWarningConfiguration
import sbt.librarymanagement.*
import sbt.util.Logger
import sbt.librarymanagement.ModuleInfo
import sbt.librarymanagement.ModuleDescriptorConfiguration
import sbt.librarymanagement.Configuration
class CoursierDependencyResolutionTests extends AnyPropSpec with Matchers {
private val logger: Logger = new Logger {
def log(level: sbt.util.Level.Value, message: => String): Unit =
System.err.println(s"${level.id} $message")
def success(message: => String): Unit =
System.err.println(message)
def trace(t: => Throwable): Unit =
System.err.println(s"trace $t")
}
private val conf211 =
CoursierConfiguration().withAutoScalaLibrary(true).withScalaVersion(Some("2.11.12"))
private val scalaModule212 = ModuleID("org.scala-lang", "scala-library", "2.12.21")
private val scalaModuleInfo213 = ScalaModuleInfo(
"2.13.18",
"2.13",
Vector.empty,
checkExplicit = false,
filterImplicit = false,
overrideScalaVersion = false
)
property("missingOk from passed UpdateConfiguration") {
val depRes = CoursierDependencyResolution(CoursierConfiguration().withAutoScalaLibrary(false))
@ -27,15 +43,6 @@ class CoursierDependencyResolutionTests extends AnyPropSpec with Matchers {
.withConfigurations(Vector(Configuration.of("Compile", "compile")))
val module = depRes.moduleDescriptor(desc)
val logger: Logger = new Logger {
def log(level: sbt.util.Level.Value, message: => String): Unit =
System.err.println(s"${level.id} $message")
def success(message: => String): Unit =
System.err.println(message)
def trace(t: => Throwable): Unit =
System.err.println(s"trace $t")
}
depRes
.update(module, UpdateConfiguration(), UnresolvedWarningConfiguration(), logger)
.fold(w => (), rep => sys.error(s"Expected resolution to fail, got report $rep"))
@ -50,4 +57,110 @@ class CoursierDependencyResolutionTests extends AnyPropSpec with Matchers {
.fold(w => throw w.resolveException, identity)
}
property("get scalalib at global version, no scalaModuleInfo") {
val depRes = CoursierDependencyResolution(conf211)
val desc = ModuleDescriptorConfiguration(ModuleID("test", "foo", "1.0"), ModuleInfo("foo"))
.withDependencies(Vector(scalaModule212.withConfigurations(Some("compile"))))
.withConfigurations(Vector(Configuration.of("Compile", "compile")))
val module = depRes.moduleDescriptor(desc)
depRes.update(module, UpdateConfiguration(), UnresolvedWarningConfiguration(), logger) match {
case Left(x) => throw x.resolveException
case Right(x) =>
x.allModules.collect {
case m: ModuleID if m.organization == scalaModule212.organization && m.name == m.name =>
m.revision
} should (contain(conf211.scalaVersion.get) and have length 1) // from config
}
}
property("get scalalib at local version, scalaModuleInfo:overrideScalaVersion") {
val depRes = CoursierDependencyResolution(conf211)
val desc = ModuleDescriptorConfiguration(ModuleID("test", "foo", "1.0"), ModuleInfo("foo"))
.withDependencies(Vector(scalaModule212.withConfigurations(Some("compile"))))
.withConfigurations(Vector(Configuration.of("Compile", "compile")))
.withScalaModuleInfo(scalaModuleInfo213.withOverrideScalaVersion(true))
val module = depRes.moduleDescriptor(desc)
depRes.update(module, UpdateConfiguration(), UnresolvedWarningConfiguration(), logger) match {
case Left(x) => throw x.resolveException
case Right(x) =>
x.allModules.collect {
case m: ModuleID if m.organization == scalaModule212.organization && m.name == m.name =>
m.revision
} should (
contain(scalaModuleInfo213.scalaFullVersion) and have length 1
) // from autoScalaLib
}
}
property("get scalalib at local version, scalaModuleInfo:!overrideScalaVersion") {
val depRes = CoursierDependencyResolution(conf211)
val desc = ModuleDescriptorConfiguration(ModuleID("test", "foo", "1.0"), ModuleInfo("foo"))
.withDependencies(Vector(scalaModule212.withConfigurations(Some("compile"))))
.withConfigurations(Vector(Configuration.of("Compile", "compile")))
.withScalaModuleInfo(scalaModuleInfo213.withOverrideScalaVersion(false))
val module = depRes.moduleDescriptor(desc)
depRes.update(module, UpdateConfiguration(), UnresolvedWarningConfiguration(), logger) match {
case Left(x) => throw x.resolveException
case Right(x) =>
x.allModules.collect {
case m: ModuleID if m.organization == scalaModule212.organization && m.name == m.name =>
m.revision
} should (contain(scalaModule212.revision) and have length 1) // from dependency
}
}
property(
"get scalalib at local version, scalaModuleInfo:overrideScalaVersion, no explicit scala lib"
) {
val depRes = CoursierDependencyResolution(conf211)
val coursierModule212 = ModuleID("io.get-coursier", "coursier_2.12", "2.1.24")
val desc = ModuleDescriptorConfiguration(ModuleID("test", "foo", "1.0"), ModuleInfo("foo"))
.withDependencies(Vector(coursierModule212.withConfigurations(Some("compile"))))
.withConfigurations(Vector(Configuration.of("Compile", "compile")))
.withScalaModuleInfo(scalaModuleInfo213.withOverrideScalaVersion(true))
val module = depRes.moduleDescriptor(desc)
depRes.update(module, UpdateConfiguration(), UnresolvedWarningConfiguration(), logger) match {
case Left(x) => throw x.resolveException
case Right(x) =>
x.allModules.collect {
case m: ModuleID if m.organization == scalaModule212.organization && m.name == m.name =>
m.revision
} should (
contain(scalaModuleInfo213.scalaFullVersion) and have length 1
) // from autoScalaLib
}
}
property(
"get scalalib at local version, scalaModuleInfo:!overrideScalaVersion, no explicit scala lib"
) {
val depRes = CoursierDependencyResolution(conf211)
val coursierModule212 = ModuleID("io.get-coursier", "coursier_2.12", "2.1.24")
val desc = ModuleDescriptorConfiguration(ModuleID("test", "foo", "1.0"), ModuleInfo("foo"))
.withDependencies(Vector(coursierModule212.withConfigurations(Some("compile"))))
.withConfigurations(Vector(Configuration.of("Compile", "compile")))
.withScalaModuleInfo(scalaModuleInfo213.withOverrideScalaVersion(false))
val module = depRes.moduleDescriptor(desc)
depRes.update(module, UpdateConfiguration(), UnresolvedWarningConfiguration(), logger) match {
case Left(x) => throw x.resolveException
case Right(x) =>
x.allModules.collect {
case m: ModuleID if m.organization == scalaModule212.organization && m.name == m.name =>
CrossVersion.binaryScalaVersion(m.revision)
} should (contain("2.12") and have length 1) // from transitive dependency
}
}
}