From dd24b0bf144714e24d244c21d26ba7d78c9d8695 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 23 Nov 2025 13:21:12 -0500 Subject: [PATCH] [2.x] Update to Coursier 2.1.25-M19 --- build.sbt | 5 +- .../CoursierDependencyResolution.scala | 26 ++++--- .../lmcoursier/definitions/ToCoursier.scala | 67 +++++++++++++------ .../internal/InterProjectRepository.scala | 6 +- .../lmcoursier/internal/ResolutionRun.scala | 4 ++ .../lmcoursier/internal/SbtUpdateReport.scala | 32 +++++++-- .../TemporaryInMemoryRepository.scala | 3 + .../lmcoursier/internal/UpdateParams.scala | 4 +- .../scala/lmcoursier/internal/UpdateRun.scala | 4 ++ project/Dependencies.scala | 3 +- .../update-sbt-classifiers/build.sbt | 1 + 11 files changed, 117 insertions(+), 38 deletions(-) diff --git a/build.sbt b/build.sbt index 0f55f9391..7ae059790 100644 --- a/build.sbt +++ b/build.sbt @@ -697,6 +697,7 @@ lazy val mainProj = (project in file("main")) sjsonNewCore.value, launcherInterface, caffeine, + scalaCollectionCompat, ), libraryDependencies ++= List(scalaPar), contrabandSettings, @@ -1245,6 +1246,7 @@ lazy val lmCoursierShaded = project "coursier", "org.fusesource", "macrocompat", + "io.github.alexarchambault.isterminal", "io.github.alexarchambault.windowsansi", "concurrentrefhashmap", "com.github.ghik", @@ -1254,6 +1256,7 @@ lazy val lmCoursierShaded = project "com.jcraft", "com.lmax", "org.apache.commons", + "org.apache.tika", "org.apache.xbean", "org.codehaus", "org.iq80", @@ -1280,7 +1283,7 @@ lazy val lmCoursierShaded = project case PathList("com", "typesafe") => MergeStrategy.discard case PathList("gigahorse") => MergeStrategy.discard case PathList("jline") => MergeStrategy.discard - case PathList("scala") => MergeStrategy.discard + case PathList("scala", _*) => MergeStrategy.discard case PathList("sjsonnew") => MergeStrategy.discard case PathList("xsbti") => MergeStrategy.discard case PathList("META-INF", "native", _*) => MergeStrategy.first diff --git a/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala b/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala index 80a035586..ebbb6abc1 100644 --- a/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala +++ b/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala @@ -4,7 +4,7 @@ import java.io.File import java.net.{ URI, URLClassLoader } import coursier.{ Organization, Resolution } -import coursier.core.{ Classifier, Configuration } +import coursier.core.{ Classifier, Configuration, Dependency, VariantPublication, Publication } import coursier.cache.CacheDefaults import coursier.util.Artifact import coursier.internal.Typelevel @@ -25,8 +25,6 @@ import lmcoursier.syntax.* import sbt.internal.librarymanagement.IvySbt import sbt.librarymanagement.* import sbt.util.Logger -import coursier.core.Dependency -import coursier.core.Publication import scala.util.{ Try, Failure } @@ -263,9 +261,15 @@ class CoursierDependencyResolution( .ResolutionParams() .withMaxIterations(conf.maxIterations) .withProfiles(conf.mavenProfiles.toSet) - .withForceVersion(conf.forceVersions.map { (k, v) => (ToCoursier.module(k), v) }.toMap) + .withForceVersion0( + conf.forceVersions + .map: (k, v) => + (ToCoursier.module(k), ToCoursier.versionConstraint(v)) + .toMap + ) .withTypelevel(typelevel) - .withReconciliation(ToCoursier.reconciliation(conf.reconciliation)) + .withReconciliation0(conf.reconciliation.map: (k, v) => + ToCoursier.moduleMatchers(k) -> ToCoursier.constraintReconciliation(v)) .withExclusions(excludeDependencies) .withRules(ToCoursier.sameVersions(conf.sameVersions)), strictOpt = conf.strict.map(ToCoursier.strict), @@ -299,7 +303,9 @@ class CoursierDependencyResolution( def updateParams( resolutions: Map[Configuration, Resolution], - artifacts: Seq[(Dependency, Publication, Artifact, Option[File])] + artifacts: Seq[ + (Dependency, Either[VariantPublication, Publication], Artifact, Option[File]) + ] ) = UpdateParams( thisModule = (ToCoursier.module(mod), ver), @@ -323,7 +329,7 @@ class CoursierDependencyResolution( artifactsParams0 = artifactsParams(resolutions) artifacts <- ArtifactsRun(artifactsParams0, verbosityLevel, log) } yield { - val updateParams0 = updateParams(resolutions, artifacts.fullDetailedArtifacts) + val updateParams0 = updateParams(resolutions, artifacts.fullDetailedArtifacts0) UpdateRun.update(updateParams0, verbosityLevel, log) } e.left.map(unresolvedWarningOrThrow(uwconfig, _)) @@ -358,7 +364,11 @@ class CoursierDependencyResolution( val r = new ResolveException( downloadErrors.map(_.getMessage), downloadErrors.map { err => - ModuleID(err.module.organization.value, err.module.name.value, err.version) + ModuleID( + err.module.organization.value, + err.module.name.value, + err.versionConstraint.asString, + ) .withExtraAttributes(err.module.attributes) } ) diff --git a/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala b/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala index 70b8b8365..92b02eaa6 100644 --- a/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala +++ b/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala @@ -1,7 +1,10 @@ package lmcoursier.definitions +import coursier.core.Overrides +import coursier.version.{ ConstraintReconciliation, VersionConstraint, Version } import lmcoursier.credentials.{ Credentials, DirectCredentials, FileCredentials } import sbt.librarymanagement.InclExclRule +import scala.annotation.nowarn // TODO Make private[lmcoursier] // private[coursier] @@ -10,6 +13,12 @@ object ToCoursier { def configuration(configuration: Configuration): coursier.core.Configuration = coursier.core.Configuration(configuration.value) + def configurationBased(c: Configuration): coursier.core.VariantSelector = + coursier.core.VariantSelector.ConfigurationBased(configuration(c)) + + def variantConfiguration(c: Configuration): coursier.core.Variant = + coursier.core.Variant.Configuration(configuration(c)) + def publication(publication: Publication): coursier.core.Publication = coursier.core.Publication( publication.name, @@ -52,6 +61,7 @@ object ToCoursier { includeByDefault = matcher.includeByDefault ) + @nowarn def reconciliation(r: Reconciliation): coursier.core.Reconciliation = r match { case Reconciliation.Default => coursier.core.Reconciliation.Default @@ -60,11 +70,22 @@ object ToCoursier { case Reconciliation.SemVer => coursier.core.Reconciliation.SemVer } + @nowarn def reconciliation( rs: Vector[(ModuleMatchers, Reconciliation)] ): Vector[(coursier.util.ModuleMatchers, coursier.core.Reconciliation)] = rs map { (m, r) => (moduleMatchers(m), reconciliation(r)) } + def constraintReconciliation(r: Reconciliation): coursier.version.ConstraintReconciliation = + r match + case Reconciliation.Default => ConstraintReconciliation.Default + case Reconciliation.Relaxed => ConstraintReconciliation.Relaxed + case Reconciliation.Strict => ConstraintReconciliation.Strict + case Reconciliation.SemVer => ConstraintReconciliation.SemVer + + def versionConstraint(v: String): VersionConstraint = + VersionConstraint(v) + def sameVersions( sv: Seq[Set[InclExclRule]] ): Seq[(coursier.params.rule.SameVersion, coursier.params.rule.RuleResolution)] = @@ -74,11 +95,14 @@ object ToCoursier { coursier.params.rule.SameVersion(matchers) -> coursier.params.rule.RuleResolution.TryResolve } + def version(v: String): Version = + Version(v) + def dependency(dependency: Dependency): coursier.core.Dependency = coursier.core.Dependency( module(dependency.module), - dependency.version, - configuration(dependency.configuration), + versionConstraint(dependency.version), + configurationBased(dependency.configuration), dependency.exclusions.map { (org, name) => (coursier.core.Organization(org.value), coursier.core.ModuleName(name.value)) }, @@ -89,27 +113,27 @@ object ToCoursier { def project(project: Project): coursier.core.Project = coursier.core.Project( - module(project.module), - project.version, - project.dependencies.map { (conf, dep) => - configuration(conf) -> dependency(dep) + module = module(project.module), + version0 = version(project.version), + dependencies0 = project.dependencies.map { (conf, dep) => + variantConfiguration(conf) -> dependency(dep) }, - project.configurations.map { (k, l) => + configurations = project.configurations.map { (k, l) => configuration(k) -> l.map(configuration) }, - None, - Nil, - project.properties, - Nil, - None, - None, - project.packagingOpt.map(t => coursier.core.Type(t.value)), + parent0 = None, + dependencyManagement0 = Nil, + properties = project.properties, + profiles = Nil, + versions = None, + snapshotVersioning = None, + packagingOpt = project.packagingOpt.map(t => coursier.core.Type(t.value)), relocated = false, - None, - project.publications.map { (conf, pub) => - configuration(conf) -> publication(pub) + actualVersionOpt0 = None, + publications0 = project.publications.map { (conf, pub) => + variantConfiguration(conf) -> publication(pub) }, - coursier.core.Info( + info = coursier.core.Info( project.info.description, project.info.homePage, project.info.licenses, @@ -130,8 +154,11 @@ object ToCoursier { dt.second ) }, - None // TODO Add scm field in lmcoursier.definitions.Info? - ) + None, // TODO Add scm field in lmcoursier.definitions.Info? + ), + overrides = Overrides.empty, + variants = Map.empty, + variantPublications = Map.empty, ) def credentials(credentials: Credentials): coursier.credentials.Credentials = diff --git a/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala b/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala index 73eea7e88..17348540c 100644 --- a/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala +++ b/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala @@ -7,7 +7,11 @@ import coursier.util.{ EitherT, Monad } final case class InterProjectRepository(projects: Seq[Project]) extends Repository { private val map = projects - .map(proj => proj.moduleVersion -> proj) + .map(proj => + (proj.moduleVersion0 match + case (m, v) => (m, v.asString) + ) -> proj + ) .toMap def find[F[_]]( diff --git a/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala b/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala index 28967745a..a9b07bf1f 100644 --- a/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala +++ b/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala @@ -12,6 +12,7 @@ import coursier.params.rule.RuleResolution import coursier.util.Task import sbt.util.Logger +import scala.annotation.nowarn import scala.concurrent.duration.FiniteDuration import scala.collection.mutable @@ -44,6 +45,7 @@ object ResolutionRun { val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1 + @nowarn def depsRepr(deps: Seq[(Configuration, Dependency)]) = deps .map { (config, dep) => @@ -89,6 +91,7 @@ object ResolutionRun { if (verbosityLevel >= 2) log.info(initialMessage) + @nowarn val resolveTask: Resolve[Task] = { Resolve() // re-using various caches from a resolution of a configuration we extend @@ -172,6 +175,7 @@ object ResolutionRun { } } + @nowarn def resolutions( params: ResolutionParams, verbosityLevel: Int, diff --git a/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala b/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala index 649e24da0..82f88c1c8 100644 --- a/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala +++ b/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala @@ -4,14 +4,23 @@ import java.io.File import java.util.{ Collections, GregorianCalendar, WeakHashMap } import coursier.cache.CacheUrl import coursier.{ Attributes, Dependency, Module, Project, Resolution } -import coursier.core.{ Classifier, Configuration, Extension, Info, Publication, Type } +import coursier.core.{ + Classifier, + Configuration, + Extension, + Info, + MinimizedExclusions, + Publication, + Type, + VariantPublication +} import coursier.maven.MavenAttributes import coursier.util.Artifact import sbt.librarymanagement.{ Artifact as _, Configuration as _, * } import sbt.util.Logger +import scala.annotation.nowarn import scala.annotation.tailrec -import coursier.core.MinimizedExclusions private[internal] object SbtUpdateReport { @@ -32,6 +41,7 @@ private[internal] object SbtUpdateReport { private def infoProperties(project: Project): Seq[(String, String)] = project.properties.filter(_._1.startsWith("info.")) + @nowarn private val moduleId = caching[(Dependency, String, Map[String, String]), ModuleID] { (dependency, version, extraProperties) => val mod = sbt.librarymanagement.ModuleID( @@ -75,6 +85,7 @@ private[internal] object SbtUpdateReport { .withExtraAttributes(module.attributes ++ extraProperties) } + @nowarn private val moduleReport = caching[ ( Dependency, @@ -138,13 +149,16 @@ private[internal] object SbtUpdateReport { .withCallers(callers.toVector) } + @nowarn private def moduleReports( thisModule: (Module, String), res: Resolution, interProjectDependencies: Seq[Project], classifiersOpt: Option[Seq[Classifier]], artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], - fullArtifactsOpt: Option[Map[(Dependency, Publication, Artifact), Option[File]]], + fullArtifactsOpt: Option[ + Map[(Dependency, Either[VariantPublication, Publication], Artifact), Option[File]] + ], log: Logger, includeSignatures: Boolean, classpathOrder: Boolean, @@ -164,7 +178,7 @@ private[internal] object SbtUpdateReport { deps.map { (d, p, a) => val d0 = d.withAttributes(d.attributes.withClassifier(p.classifier)) val a0 = if (missingOk) a.withOptional(true) else a - val f = map.get((d0, p, a0)).flatten + val f = map.get((d0, Right(p), a0)).flatten (d, p, a0, f) // not d0 } case None => @@ -311,6 +325,7 @@ private[internal] object SbtUpdateReport { } } + @nowarn def apply( thisModule: (Module, String), configDependencies: Map[Configuration, Seq[Dependency]], @@ -318,7 +333,9 @@ private[internal] object SbtUpdateReport { interProjectDependencies: Vector[Project], classifiersOpt: Option[Seq[Classifier]], artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], - fullArtifactsOpt: Option[Map[(Dependency, Publication, Artifact), Option[File]]], + fullArtifactsOpt: Option[ + Map[(Dependency, Either[VariantPublication, Publication], Artifact), Option[File]] + ], log: Logger, includeSignatures: Boolean, classpathOrder: Boolean, @@ -361,8 +378,11 @@ private[internal] object SbtUpdateReport { OrganizationArtifactReport(rep.module.organization, rep.module.name, Vector(rep)) } + def conflicts: Seq[coursier.graph.Conflict] = + try coursier.graph.Conflict(subRes) + catch case e: Throwable if missingOk => Nil val evicted = for { - c <- coursier.graph.Conflict(subRes) + c <- conflicts // ideally, forceVersions should be taken into account by coursier.core.Resolution itself, when // it computes transitive dependencies. It only handles forced versions at a global level for now, // rather than handing them for each dependency (where each dependency could have its own forced diff --git a/lm-coursier/src/main/scala/lmcoursier/internal/TemporaryInMemoryRepository.scala b/lm-coursier/src/main/scala/lmcoursier/internal/TemporaryInMemoryRepository.scala index fb63e0d1f..5d1e71f58 100644 --- a/lm-coursier/src/main/scala/lmcoursier/internal/TemporaryInMemoryRepository.scala +++ b/lm-coursier/src/main/scala/lmcoursier/internal/TemporaryInMemoryRepository.scala @@ -7,6 +7,7 @@ import coursier.cache.{ ConnectionBuilder, FileCache } import coursier.core.* import coursier.util.{ Artifact, EitherT, Monad } +import scala.annotation.nowarn import scala.util.Try object TemporaryInMemoryRepository { @@ -134,6 +135,7 @@ final class TemporaryInMemoryRepository private ( val cacheOpt: Option[FileCache[Nothing]] ) extends Repository { + @nowarn def find[F[_]]( module: Module, version: String, @@ -183,6 +185,7 @@ final class TemporaryInMemoryRepository private ( EitherT(F.map(F.point(()))(_ => res)) } + @nowarn def artifacts( dependency: Dependency, project: Project, diff --git a/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala b/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala index 6cc3e077c..cb3c1eb84 100644 --- a/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala +++ b/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala @@ -9,7 +9,9 @@ import coursier.util.Artifact final case class UpdateParams( thisModule: (Module, String), artifacts: Map[Artifact, File], - fullArtifacts: Option[Map[(Dependency, Publication, Artifact), Option[File]]], + fullArtifacts: Option[ + Map[(Dependency, Either[VariantPublication, Publication], Artifact), Option[File]] + ], classifiers: Option[Seq[Classifier]], configs: Map[Configuration, Set[Configuration]], dependencies: Seq[(Configuration, Dependency)], diff --git a/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala b/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala index b79f3cec6..643d08c2c 100644 --- a/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala +++ b/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala @@ -6,11 +6,13 @@ import coursier.core.* import coursier.util.Print import sbt.librarymanagement.UpdateReport import sbt.util.Logger +import scala.annotation.nowarn // private[coursier] object UpdateRun { // Move back to coursier.util (in core module) after 1.0? + @nowarn private def allDependenciesByConfig( res: Map[Configuration, Resolution], depsByConfig: Map[Configuration, Seq[Dependency]], @@ -33,6 +35,7 @@ object UpdateRun { } // Move back to coursier.util (in core module) after 1.0? + @nowarn private def dependenciesWithConfig( res: Map[Configuration, Resolution], depsByConfig: Map[Configuration, Seq[Dependency]], @@ -48,6 +51,7 @@ object UpdateRun { } .toSet + @nowarn def update( params: UpdateParams, verbosityLevel: Int, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 183a224b0..e8e5cc153 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -98,6 +98,7 @@ object Dependencies { val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.4.0" val scalaParsers = "org.scala-lang.modules" %% "scala-parser-combinators" % "2.4.0" val scalaPar = "org.scala-lang.modules" %% "scala-parallel-collections" % "1.2.0" + val scalaCollectionCompat = "org.scala-lang.modules" %% "scala-collection-compat" % "2.14.0" // specify all of log4j modules to prevent misalignment def log4jModule = (n: String) => "org.apache.logging.log4j" % n % "2.17.1" @@ -118,7 +119,7 @@ object Dependencies { // lm-coursier dependencies val dataclassScalafixVersion = "0.3.0" - val coursierVersion = "2.1.23" + val coursierVersion = "2.1.25-M19" val coursier = ("io.get-coursier" %% "coursier" % coursierVersion) .cross(CrossVersion.for3Use2_13) diff --git a/sbt-app/src/sbt-test/dependency-management/update-sbt-classifiers/build.sbt b/sbt-app/src/sbt-test/dependency-management/update-sbt-classifiers/build.sbt index 7c483b453..f2393d13c 100644 --- a/sbt-app/src/sbt-test/dependency-management/update-sbt-classifiers/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/update-sbt-classifiers/build.sbt @@ -52,6 +52,7 @@ lazy val root = (project in file(".")) "org.jline:jline-terminal-jni", "org.reactivestreams:reactive-streams", "org.scala-lang.modules:scala-asm", + "org.scala-lang.modules:scala-collection-compat_3", "org.scala-lang.modules:scala-parallel-collections_3", "org.scala-lang.modules:scala-parser-combinators_3", "org.scala-lang.modules:scala-xml_3",