Get dependency / artifact matching straight from coursier

Rather than matching them after-the-fact in a fragile way.
This commit is contained in:
Alexandre Archambault 2020-05-14 16:31:28 +02:00
parent ecd84e2b83
commit 597a4c014a
6 changed files with 60 additions and 13 deletions

View File

@ -12,6 +12,8 @@ import lmcoursier.internal.{ArtifactsParams, ArtifactsRun, CoursierModuleDescrip
import sbt.internal.librarymanagement.IvySbt import sbt.internal.librarymanagement.IvySbt
import sbt.librarymanagement._ import sbt.librarymanagement._
import sbt.util.Logger import sbt.util.Logger
import coursier.core.Dependency
import coursier.core.Publication
class CoursierDependencyResolution(conf: CoursierConfiguration) extends DependencyResolutionInterface { class CoursierDependencyResolution(conf: CoursierConfiguration) extends DependencyResolutionInterface {
@ -191,12 +193,13 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
def updateParams( def updateParams(
resolutions: Map[Set[Configuration], Resolution], resolutions: Map[Set[Configuration], Resolution],
artifacts: Map[Artifact, File] artifacts: Seq[(Dependency, Publication, Artifact, Option[File])]
) = ) =
UpdateParams( UpdateParams(
thisModule = (ToCoursier.module(mod), ver), thisModule = (ToCoursier.module(mod), ver),
shadedConfigOpt = None, shadedConfigOpt = None,
artifacts = artifacts, artifacts = artifacts.collect { case (d, p, a, Some(f)) => a -> f }.toMap,
fullArtifacts = Some(artifacts.map { case (d, p, a, f) => (d, p, a) -> f }.toMap),
classifiers = classifiers, classifiers = classifiers,
configs = configs, configs = configs,
dependencies = dependencies, dependencies = dependencies,
@ -210,7 +213,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
val e = for { val e = for {
resolutions <- ResolutionRun.resolutions(resolutionParams, verbosityLevel, log) resolutions <- ResolutionRun.resolutions(resolutionParams, verbosityLevel, log)
artifactsParams0 = artifactsParams(resolutions) artifactsParams0 = artifactsParams(resolutions)
artifacts <- ArtifactsRun.artifacts(artifactsParams0, verbosityLevel, log) artifacts <- ArtifactsRun.artifactsResult(artifactsParams0, verbosityLevel, log)
} yield { } yield {
val updateParams0 = updateParams(resolutions, artifacts) val updateParams0 = updateParams(resolutions, artifacts)
UpdateRun.update(updateParams0, verbosityLevel, log) UpdateRun.update(updateParams0, verbosityLevel, log)

View File

@ -7,6 +7,8 @@ import coursier.cache.loggers.{FallbackRefreshDisplay, ProgressBarRefreshDisplay
import coursier.core.Type import coursier.core.Type
import coursier.util.Artifact import coursier.util.Artifact
import sbt.util.Logger import sbt.util.Logger
import coursier.core.Dependency
import coursier.core.Publication
// private[coursier] // private[coursier]
object ArtifactsRun { object ArtifactsRun {
@ -16,6 +18,13 @@ object ArtifactsRun {
verbosityLevel: Int, verbosityLevel: Int,
log: Logger log: Logger
): Either[coursier.error.FetchError, Map[Artifact, File]] = ): Either[coursier.error.FetchError, Map[Artifact, File]] =
artifactsResult(params, verbosityLevel, log).map(_.collect { case (_, _, a, Some(f)) => (a, f) }.toMap)
def artifactsResult(
params: ArtifactsParams,
verbosityLevel: Int,
log: Logger
): Either[coursier.error.FetchError, Seq[(Dependency, Publication, Artifact, Option[File])]] =
// let's update only one module at once, for a better output // let's update only one module at once, for a better output
// Downloads are already parallel, no need to parallelize further anyway // Downloads are already parallel, no need to parallelize further anyway
Lock.lock.synchronized { Lock.lock.synchronized {
@ -64,8 +73,8 @@ object ArtifactsRun {
} }
) )
) )
.either() .eitherResult()
.map(_.toMap) .map(_.fullDetailedArtifacts) // FIXME Misses extraArtifacts, that we don't use for now though
} }
} }

View File

@ -137,19 +137,41 @@ private[internal] object SbtUpdateReport {
interProjectDependencies: Seq[Project], interProjectDependencies: Seq[Project],
classifiersOpt: Option[Seq[Classifier]], classifiersOpt: Option[Seq[Classifier]],
artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File],
fullArtifactsOpt: Option[Map[(Dependency, Publication, Artifact), Option[File]]],
log: Logger, log: Logger,
keepPomArtifact: Boolean = false, keepPomArtifact: Boolean = false,
includeSignatures: Boolean = false, includeSignatures: Boolean = false,
classpathOrder: Boolean, classpathOrder: Boolean,
): Vector[ModuleReport] = { ): Vector[ModuleReport] = {
val depArtifacts1 = res.dependencyArtifacts(classifiersOpt, classpathOrder)
val deps = classifiersOpt match {
case Some(classifiers) =>
res.dependencyArtifacts(Some(classifiers.toSeq), classpathOrder)
case None =>
res.dependencyArtifacts(None, classpathOrder)
}
val depArtifacts1 = fullArtifactsOpt match {
case Some(map) =>
deps.map {
case (d, p, a) =>
val d0 = d.withAttributes(d.attributes.withClassifier(p.classifier))
val f = map.get((d0, p, a)).flatten
(d, p, a, f) // not d0
}
case None =>
deps.map {
case (d, p, a) =>
(d, p, a, None)
}
}
val depArtifacts0 = val depArtifacts0 =
if (keepPomArtifact) if (keepPomArtifact)
depArtifacts1 depArtifacts1
else else
depArtifacts1.filter { depArtifacts1.filter {
case (_, pub, _) => pub.attributes != Attributes(Type.pom, Classifier.empty) case (_, pub, _, _) => pub.attributes != Attributes(Type.pom, Classifier.empty)
} }
val depArtifacts = val depArtifacts =
@ -159,16 +181,16 @@ private[internal] object SbtUpdateReport {
if (notFound.isEmpty) if (notFound.isEmpty)
depArtifacts0.flatMap { depArtifacts0.flatMap {
case (dep, pub, a) => case (dep, pub, a, f) =>
val sigPub = pub val sigPub = pub
// not too sure about those // not too sure about those
.withExt(Extension(pub.ext.value)) .withExt(Extension(pub.ext.value))
.withType(Type(pub.`type`.value)) .withType(Type(pub.`type`.value))
Seq((dep, pub, a)) ++ Seq((dep, pub, a, f)) ++
a.extra.get("sig").toSeq.map((dep, sigPub, _)) a.extra.get("sig").toSeq.map((dep, sigPub, _, None))
} }
else { else {
for ((_, _, a) <- notFound) for ((_, _, a, _) <- notFound)
log.error(s"No signature found for ${a.url}") log.error(s"No signature found for ${a.url}")
sys.error(s"${notFound.length} signature(s) not found") sys.error(s"${notFound.length} signature(s) not found")
} }
@ -178,7 +200,7 @@ private[internal] object SbtUpdateReport {
val groupedDepArtifacts = { val groupedDepArtifacts = {
val m = depArtifacts.groupBy(_._1) val m = depArtifacts.groupBy(_._1)
val fromLib = depArtifacts.map(_._1).distinct.map { dep => val fromLib = depArtifacts.map(_._1).distinct.map { dep =>
dep -> m.getOrElse(dep, Nil).map { case (_, pub, a) => (pub, a) } dep -> m.getOrElse(dep, Nil).map { case (_, pub, a, f) => (pub, a, f) }
} }
val fromInterProj = interProjectDependencies val fromInterProj = interProjectDependencies
.filter(p => p.module != thisModule._1) .filter(p => p.module != thisModule._1)
@ -249,11 +271,19 @@ private[internal] object SbtUpdateReport {
Vector.empty Vector.empty
} }
} }
val filesOpt = artifacts.map {
case (pub, a, fileOpt) =>
val fileOpt0 = fileOpt.orElse {
if (fullArtifactsOpt.isEmpty) artifactFileOpt(proj.module, proj.version, pub.attributes, a)
else None
}
(pub, a, fileOpt0)
}
moduleReport(( moduleReport((
dep, dep,
dependees, dependees,
proj, proj,
artifacts.map { case (pub, a) => (pub, a, artifactFileOpt(proj.module, proj.version, pub.attributes, a)) } filesOpt
)) ))
} }
} }
@ -266,6 +296,7 @@ private[internal] object SbtUpdateReport {
configs: Map[Configuration, Set[Configuration]], configs: Map[Configuration, Set[Configuration]],
classifiersOpt: Option[Seq[Classifier]], classifiersOpt: Option[Seq[Classifier]],
artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File],
fullArtifactsOpt: Option[Map[(Dependency, Publication, Artifact), Option[File]]],
log: Logger, log: Logger,
keepPomArtifact: Boolean = false, keepPomArtifact: Boolean = false,
includeSignatures: Boolean = false, includeSignatures: Boolean = false,
@ -288,6 +319,7 @@ private[internal] object SbtUpdateReport {
interProjectDependencies, interProjectDependencies,
classifiersOpt, classifiersOpt,
artifactFileOpt, artifactFileOpt,
fullArtifactsOpt,
log, log,
keepPomArtifact = keepPomArtifact, keepPomArtifact = keepPomArtifact,
includeSignatures = includeSignatures, includeSignatures = includeSignatures,

View File

@ -10,6 +10,7 @@ final case class UpdateParams(
thisModule: (Module, String), thisModule: (Module, String),
shadedConfigOpt: Option[(String, Configuration)], shadedConfigOpt: Option[(String, Configuration)],
artifacts: Map[Artifact, File], artifacts: Map[Artifact, File],
fullArtifacts: Option[Map[(Dependency, Publication, Artifact), Option[File]]],
classifiers: Option[Seq[Classifier]], classifiers: Option[Seq[Classifier]],
configs: Map[Configuration, Set[Configuration]], configs: Map[Configuration, Set[Configuration]],
dependencies: Seq[(Configuration, Dependency)], dependencies: Seq[(Configuration, Dependency)],

View File

@ -92,6 +92,7 @@ object UpdateRun {
params.configs, params.configs,
params.classifiers, params.classifiers,
params.artifactFileOpt, params.artifactFileOpt,
params.fullArtifacts,
log, log,
includeSignatures = params.includeSignatures, includeSignatures = params.includeSignatures,
classpathOrder = params.classpathOrder, classpathOrder = params.classpathOrder,

View File

@ -130,6 +130,7 @@ object UpdateTasks {
(p.module, p.version), (p.module, p.version),
shadedConfigOpt, shadedConfigOpt,
artifactFilesOrErrors0, artifactFilesOrErrors0,
None,
classifiers, classifiers,
configs, configs,
dependencies, dependencies,