diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala index 94ebf893e..4a9639567 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala @@ -222,9 +222,9 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen val e = for { resolutions <- ResolutionRun.resolutions(resolutionParams, verbosityLevel, log) artifactsParams0 = artifactsParams(resolutions) - artifacts <- ArtifactsRun.artifactsResult(artifactsParams0, verbosityLevel, log) + artifacts <- ArtifactsRun(artifactsParams0, verbosityLevel, log) } yield { - val updateParams0 = updateParams(resolutions, artifacts) + val updateParams0 = updateParams(resolutions, artifacts.fullDetailedArtifacts) UpdateRun.update(updateParams0, verbosityLevel, log) } e.left.map(unresolvedWarningOrThrow(uwconfig, _)) diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala index f208fd2ec..839cc7868 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala @@ -1,90 +1,83 @@ package lmcoursier.internal -import java.io.File - -import coursier.cache.internal.ThreadUtil +import coursier.Artifacts +import coursier.cache.CacheLogger import coursier.cache.loggers.{FallbackRefreshDisplay, ProgressBarRefreshDisplay, RefreshLogger} import coursier.core.Type -import coursier.util.Artifact import sbt.util.Logger -import coursier.core.Dependency -import coursier.core.Publication -// private[coursier] +// private[lmcoursier] object ArtifactsRun { - def artifacts( + def apply( params: ArtifactsParams, verbosityLevel: Int, log: Logger - ): Either[coursier.error.FetchError, Map[Artifact, File]] = - artifactsResult(params, verbosityLevel, log).map(_.collect { case (_, _, a, Some(f)) => (a, f) }.toMap) + ): Either[coursier.error.FetchError, Artifacts.Result] = { - 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 - // Downloads are already parallel, no need to parallelize further anyway - Lock.lock.synchronized { + val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1 - val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1 + val artifactInitialMessage = + if (verbosityLevel >= 0) + s"Fetching artifacts of ${params.projectName}" + + (if (params.sbtClassifiers) " (sbt classifiers)" else "") + else + "" - val artifactInitialMessage = - if (verbosityLevel >= 0) - s"Fetching artifacts of ${params.projectName}" + - (if (params.sbtClassifiers) " (sbt classifiers)" else "") + // Ensuring only one resolution / artifact fetching runs at a time when the logger + // may rely on progress bars, as two progress bar loggers can't display stuff at the + // same time. + val needsLock = params.loggerOpt.nonEmpty || !RefreshLogger.defaultFallbackMode + + val coursierLogger = params.loggerOpt.getOrElse { + RefreshLogger.create( + if (RefreshLogger.defaultFallbackMode) + new FallbackRefreshDisplay() else - "" - - ThreadUtil.withFixedThreadPool(params.parallel) { pool => - - coursier.Artifacts() - .withResolutions(params.resolutions) - .withArtifactTypes(Set(Type.all)) - .withClassifiers(params.classifiers.getOrElse(Nil).toSet) - .withClasspathOrder(params.classpathOrder) - .addExtraArtifacts { l => - if (params.includeSignatures) - l.flatMap(_._3.extra.get("sig").toSeq) - else - Nil - } - .addTransformArtifacts { artifacts => - if (params.missingOk) - artifacts.map { - case (dependency, publication, artifact) => - (dependency, publication, artifact.withOptional(true)) - } - else - artifacts - } - .withCache( - params - .cache - .withPool(pool) - .withLogger( - params.loggerOpt.getOrElse { - RefreshLogger.create( - if (RefreshLogger.defaultFallbackMode) - new FallbackRefreshDisplay() - else - ProgressBarRefreshDisplay.create( - if (printOptionalMessage) log.info(artifactInitialMessage), - if (printOptionalMessage || verbosityLevel >= 2) - log.info( - s"Fetched artifacts of ${params.projectName}" + - (if (params.sbtClassifiers) " (sbt classifiers)" else "") - ) - ) - ) - } + ProgressBarRefreshDisplay.create( + if (printOptionalMessage) log.info(artifactInitialMessage), + if (printOptionalMessage || verbosityLevel >= 2) + log.info( + s"Fetched artifacts of ${params.projectName}" + + (if (params.sbtClassifiers) " (sbt classifiers)" else "") ) ) - .eitherResult() - .map(_.fullDetailedArtifacts) // FIXME Misses extraArtifacts, that we don't use for now though - } + ) } + if (needsLock) + Lock.lock.synchronized { + result(params, coursierLogger) + } + else + result(params, coursierLogger) + } + + private def result( + params: ArtifactsParams, + coursierLogger: CacheLogger + ): Either[coursier.error.FetchError, Artifacts.Result] = + coursier.Artifacts() + .withResolutions(params.resolutions) + .withArtifactTypes(Set(Type.all)) + .withClassifiers(params.classifiers.getOrElse(Nil).toSet) + .withClasspathOrder(params.classpathOrder) + .addExtraArtifacts { l => + if (params.includeSignatures) + l.flatMap(_._3.extra.get("sig").toSeq) + else + Nil + } + .addTransformArtifacts { artifacts => + if (params.missingOk) + artifacts.map { + case (dependency, publication, artifact) => + (dependency, publication, artifact.withOptional(true)) + } + else + artifacts + } + .withCache(params.cache.withLogger(coursierLogger)) + .eitherResult() + } diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala index 3a976d71d..9321cee43 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala @@ -1,6 +1,5 @@ package lmcoursier.internal -import coursier.cache.internal.ThreadUtil import coursier.{Resolution, Resolve} import coursier.cache.loggers.{FallbackRefreshDisplay, ProgressBarRefreshDisplay, RefreshLogger} import coursier.core._ @@ -80,51 +79,47 @@ object ResolutionRun { if (verbosityLevel >= 2) log.info(initialMessage) - ThreadUtil.withFixedThreadPool(params.parallel) { pool => - - Resolve() - // re-using various caches from a resolution of a configuration we extend - .withInitialResolution(startingResolutionOpt) - .withDependencies( - params.dependencies.collect { - case (config, dep) if configs(config) => - dep - } - ) - .withRepositories(repositories) - .withResolutionParams( - params - .params - .addForceVersion((if (isSandboxConfig) Nil else params.interProjectDependencies.map(_.moduleVersion)): _*) - .withForceScalaVersion(params.autoScalaLibOpt.nonEmpty) - .withScalaVersionOpt(params.autoScalaLibOpt.map(_._2)) - .withTypelevel(params.params.typelevel) - .withRules(rules) - ) - .withCache( - params - .cache - .withPool(pool) - .withLogger( - params.loggerOpt.getOrElse { - RefreshLogger.create( - if (RefreshLogger.defaultFallbackMode) - new FallbackRefreshDisplay() - else - ProgressBarRefreshDisplay.create( - if (printOptionalMessage) log.info(initialMessage), - if (printOptionalMessage || verbosityLevel >= 2) - log.info(s"Resolved ${params.projectName} dependencies") - ) - ) - } - ) - ) - .either() match { - case Left(err) if params.missingOk => Right(err.resolution) - case others => others + Resolve() + // re-using various caches from a resolution of a configuration we extend + .withInitialResolution(startingResolutionOpt) + .withDependencies( + params.dependencies.collect { + case (config, dep) if configs(config) => + dep } - } + ) + .withRepositories(repositories) + .withResolutionParams( + params + .params + .addForceVersion((if (isSandboxConfig) Nil else params.interProjectDependencies.map(_.moduleVersion)): _*) + .withForceScalaVersion(params.autoScalaLibOpt.nonEmpty) + .withScalaVersionOpt(params.autoScalaLibOpt.map(_._2)) + .withTypelevel(params.params.typelevel) + .withRules(rules) + ) + .withCache( + params + .cache + .withLogger( + params.loggerOpt.getOrElse { + RefreshLogger.create( + if (RefreshLogger.defaultFallbackMode) + new FallbackRefreshDisplay() + else + ProgressBarRefreshDisplay.create( + if (printOptionalMessage) log.info(initialMessage), + if (printOptionalMessage || verbosityLevel >= 2) + log.info(s"Resolved ${params.projectName} dependencies") + ) + ) + } + ) + ) + .either() match { + case Left(err) if params.missingOk => Right(err.resolution) + case others => others + } } def resolutions( @@ -188,7 +183,7 @@ object ResolutionRun { () } } - either.map(_ => map.toMap) + withSubResolutions.map(_ => map.toMap) } for (res <- resOrError) SbtCoursierCache.default.putResolution(params.resolutionKey, res) diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala index 39e3a24db..e31a540ff 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala @@ -75,7 +75,7 @@ object ArtifactsTasks { missingOk = sbtClassifiers ) - val resOrError = ArtifactsRun.artifacts( + val resOrError = ArtifactsRun( params, verbosityLevel, log @@ -85,7 +85,7 @@ object ArtifactsTasks { case Left(err) => throw err case Right(res0) => - res0 + res0.artifacts.toMap } } }