From 9bd17e0fddf6db787f58f47f0a1f31e3a140c460 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Tue, 26 Feb 2019 13:29:55 +0100 Subject: [PATCH] Switch to coursier 1.1.0-M12, use high level API --- build.sbt | 2 +- .../lmcoursier/CoursierConfiguration.scala | 24 +-- .../src/main/contraband/lm-coursier.json | 4 +- .../coursier/lmcoursier/ArtifactsParams.scala | 2 +- .../coursier/lmcoursier/ArtifactsRun.scala | 118 +++++------ .../CoursierDependencyResolution.scala | 117 ++++++----- .../coursier/lmcoursier/CreateLogger.scala | 5 - .../scala/coursier/lmcoursier/FromSbt.scala | 2 +- .../coursier/lmcoursier/ResolutionError.scala | 124 ----------- .../lmcoursier/ResolutionException.scala | 10 - .../lmcoursier/ResolutionParams.scala | 91 +-------- .../coursier/lmcoursier/ResolutionRun.scala | 193 ++++++++---------- .../lmcoursier/SbtCoursierCache.scala | 6 +- .../coursier/lmcoursier/UpdateParams.scala | 24 +-- .../scala/coursier/lmcoursier/UpdateRun.scala | 41 +--- .../sbtcoursiershared/SbtCoursierShared.scala | 15 +- .../coursier/sbtcoursier/ArtifactsTasks.scala | 25 ++- .../coursier/sbtcoursier/CoursierPlugin.scala | 9 +- .../scala/coursier/sbtcoursier/Keys.scala | 12 +- .../sbtcoursier/ResolutionTasks.scala | 32 ++- .../coursier/sbtcoursier/UpdateTasks.scala | 15 +- .../src/sbt-test/shared-1/logger/build.sbt | 43 ++-- .../sbtlmcoursier/LmCoursierPlugin.scala | 4 +- .../src/main/scala/coursier/Shading.scala | 4 +- 24 files changed, 305 insertions(+), 617 deletions(-) delete mode 100644 modules/lm-coursier/src/main/scala/coursier/lmcoursier/CreateLogger.scala delete mode 100644 modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionError.scala delete mode 100644 modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionException.scala diff --git a/build.sbt b/build.sbt index e104bcfe2..e5d5cb779 100644 --- a/build.sbt +++ b/build.sbt @@ -15,7 +15,7 @@ inThisBuild(List( ) )) -val coursierVersion = "1.1.0-M11-1" +val coursierVersion = "1.1.0-M12" lazy val `lm-coursier` = project .in(file("modules/lm-coursier")) diff --git a/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala b/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala index 9a1ad2d82..c18c5c8da 100644 --- a/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala +++ b/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala @@ -24,23 +24,23 @@ final class CoursierConfiguration private ( val scalaVersion: Option[String], val authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], val authenticationByHost: Vector[(String, coursier.core.Authentication)], - val createLogger: Option[coursier.lmcoursier.CreateLogger], + val logger: Option[coursier.cache.CacheLogger], val cache: Option[java.io.File]) extends Serializable { private def this() = this(None, sbt.librarymanagement.Resolver.defaults, true, 6, 100, None, None, Vector.empty, Vector.empty, Vector.empty, Vector.empty, true, false, Vector.empty, Vector.empty, None, None, Vector.empty, Vector.empty, None, None) override def equals(o: Any): Boolean = o match { - case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.sbtScalaOrganization == x.sbtScalaOrganization) && (this.sbtScalaVersion == x.sbtScalaVersion) && (this.sbtScalaJars == x.sbtScalaJars) && (this.interProjectDependencies == x.interProjectDependencies) && (this.excludeDependencies == x.excludeDependencies) && (this.fallbackDependencies == x.fallbackDependencies) && (this.autoScalaLibrary == x.autoScalaLibrary) && (this.hasClassifiers == x.hasClassifiers) && (this.classifiers == x.classifiers) && (this.mavenProfiles == x.mavenProfiles) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.authenticationByRepositoryId == x.authenticationByRepositoryId) && (this.authenticationByHost == x.authenticationByHost) && (this.createLogger == x.createLogger) && (this.cache == x.cache) + case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.sbtScalaOrganization == x.sbtScalaOrganization) && (this.sbtScalaVersion == x.sbtScalaVersion) && (this.sbtScalaJars == x.sbtScalaJars) && (this.interProjectDependencies == x.interProjectDependencies) && (this.excludeDependencies == x.excludeDependencies) && (this.fallbackDependencies == x.fallbackDependencies) && (this.autoScalaLibrary == x.autoScalaLibrary) && (this.hasClassifiers == x.hasClassifiers) && (this.classifiers == x.classifiers) && (this.mavenProfiles == x.mavenProfiles) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.authenticationByRepositoryId == x.authenticationByRepositoryId) && (this.authenticationByHost == x.authenticationByHost) && (this.logger == x.logger) && (this.cache == x.cache) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "coursier.lmcoursier.CoursierConfiguration".##) + log.##) + resolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + sbtScalaOrganization.##) + sbtScalaVersion.##) + sbtScalaJars.##) + interProjectDependencies.##) + excludeDependencies.##) + fallbackDependencies.##) + autoScalaLibrary.##) + hasClassifiers.##) + classifiers.##) + mavenProfiles.##) + scalaOrganization.##) + scalaVersion.##) + authenticationByRepositoryId.##) + authenticationByHost.##) + createLogger.##) + cache.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "coursier.lmcoursier.CoursierConfiguration".##) + log.##) + resolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + sbtScalaOrganization.##) + sbtScalaVersion.##) + sbtScalaJars.##) + interProjectDependencies.##) + excludeDependencies.##) + fallbackDependencies.##) + autoScalaLibrary.##) + hasClassifiers.##) + classifiers.##) + mavenProfiles.##) + scalaOrganization.##) + scalaVersion.##) + authenticationByRepositoryId.##) + authenticationByHost.##) + logger.##) + cache.##) } override def toString: String = { - "CoursierConfiguration(" + log + ", " + resolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + sbtScalaOrganization + ", " + sbtScalaVersion + ", " + sbtScalaJars + ", " + interProjectDependencies + ", " + excludeDependencies + ", " + fallbackDependencies + ", " + autoScalaLibrary + ", " + hasClassifiers + ", " + classifiers + ", " + mavenProfiles + ", " + scalaOrganization + ", " + scalaVersion + ", " + authenticationByRepositoryId + ", " + authenticationByHost + ", " + createLogger + ", " + cache + ")" + "CoursierConfiguration(" + log + ", " + resolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + sbtScalaOrganization + ", " + sbtScalaVersion + ", " + sbtScalaJars + ", " + interProjectDependencies + ", " + excludeDependencies + ", " + fallbackDependencies + ", " + autoScalaLibrary + ", " + hasClassifiers + ", " + classifiers + ", " + mavenProfiles + ", " + scalaOrganization + ", " + scalaVersion + ", " + authenticationByRepositoryId + ", " + authenticationByHost + ", " + logger + ", " + cache + ")" } - private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, sbtScalaOrganization: Option[String] = sbtScalaOrganization, sbtScalaVersion: Option[String] = sbtScalaVersion, sbtScalaJars: Vector[java.io.File] = sbtScalaJars, interProjectDependencies: Vector[coursier.core.Project] = interProjectDependencies, excludeDependencies: Vector[(String, String)] = excludeDependencies, fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency] = fallbackDependencies, autoScalaLibrary: Boolean = autoScalaLibrary, hasClassifiers: Boolean = hasClassifiers, classifiers: Vector[String] = classifiers, mavenProfiles: Vector[String] = mavenProfiles, scalaOrganization: Option[String] = scalaOrganization, scalaVersion: Option[String] = scalaVersion, authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)] = authenticationByRepositoryId, authenticationByHost: Vector[(String, coursier.core.Authentication)] = authenticationByHost, createLogger: Option[coursier.lmcoursier.CreateLogger] = createLogger, cache: Option[java.io.File] = cache): CoursierConfiguration = { - new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, authenticationByHost, createLogger, cache) + private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, sbtScalaOrganization: Option[String] = sbtScalaOrganization, sbtScalaVersion: Option[String] = sbtScalaVersion, sbtScalaJars: Vector[java.io.File] = sbtScalaJars, interProjectDependencies: Vector[coursier.core.Project] = interProjectDependencies, excludeDependencies: Vector[(String, String)] = excludeDependencies, fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency] = fallbackDependencies, autoScalaLibrary: Boolean = autoScalaLibrary, hasClassifiers: Boolean = hasClassifiers, classifiers: Vector[String] = classifiers, mavenProfiles: Vector[String] = mavenProfiles, scalaOrganization: Option[String] = scalaOrganization, scalaVersion: Option[String] = scalaVersion, authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)] = authenticationByRepositoryId, authenticationByHost: Vector[(String, coursier.core.Authentication)] = authenticationByHost, logger: Option[coursier.cache.CacheLogger] = logger, cache: Option[java.io.File] = cache): CoursierConfiguration = { + new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, authenticationByHost, logger, cache) } def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { copy(log = log) @@ -114,11 +114,11 @@ final class CoursierConfiguration private ( def withAuthenticationByHost(authenticationByHost: Vector[(String, coursier.core.Authentication)]): CoursierConfiguration = { copy(authenticationByHost = authenticationByHost) } - def withCreateLogger(createLogger: Option[coursier.lmcoursier.CreateLogger]): CoursierConfiguration = { - copy(createLogger = createLogger) + def withLogger(logger: Option[coursier.cache.CacheLogger]): CoursierConfiguration = { + copy(logger = logger) } - def withCreateLogger(createLogger: coursier.lmcoursier.CreateLogger): CoursierConfiguration = { - copy(createLogger = Option(createLogger)) + def withLogger(logger: coursier.cache.CacheLogger): CoursierConfiguration = { + copy(logger = Option(logger)) } def withCache(cache: Option[java.io.File]): CoursierConfiguration = { copy(cache = cache) @@ -130,6 +130,6 @@ final class CoursierConfiguration private ( object CoursierConfiguration { def apply(): CoursierConfiguration = new CoursierConfiguration() - def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: Option[String], sbtScalaVersion: Option[String], sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: Option[String], scalaVersion: Option[String], authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], authenticationByHost: Vector[(String, coursier.core.Authentication)], createLogger: Option[coursier.lmcoursier.CreateLogger], cache: Option[java.io.File]): CoursierConfiguration = new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, authenticationByHost, createLogger, cache) - def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: String, sbtScalaVersion: String, sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: String, scalaVersion: String, authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], authenticationByHost: Vector[(String, coursier.core.Authentication)], createLogger: coursier.lmcoursier.CreateLogger, cache: java.io.File): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, reorderResolvers, parallelDownloads, maxIterations, Option(sbtScalaOrganization), Option(sbtScalaVersion), sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, Option(scalaOrganization), Option(scalaVersion), authenticationByRepositoryId, authenticationByHost, Option(createLogger), Option(cache)) + def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: Option[String], sbtScalaVersion: Option[String], sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: Option[String], scalaVersion: Option[String], authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], authenticationByHost: Vector[(String, coursier.core.Authentication)], logger: Option[coursier.cache.CacheLogger], cache: Option[java.io.File]): CoursierConfiguration = new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, authenticationByHost, logger, cache) + def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: String, sbtScalaVersion: String, sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: String, scalaVersion: String, authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], authenticationByHost: Vector[(String, coursier.core.Authentication)], logger: coursier.cache.CacheLogger, cache: java.io.File): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, reorderResolvers, parallelDownloads, maxIterations, Option(sbtScalaOrganization), Option(sbtScalaVersion), sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, Option(scalaOrganization), Option(scalaVersion), authenticationByRepositoryId, authenticationByHost, Option(logger), Option(cache)) } diff --git a/modules/lm-coursier/src/main/contraband/lm-coursier.json b/modules/lm-coursier/src/main/contraband/lm-coursier.json index d641b0c55..c97f96821 100644 --- a/modules/lm-coursier/src/main/contraband/lm-coursier.json +++ b/modules/lm-coursier/src/main/contraband/lm-coursier.json @@ -122,8 +122,8 @@ "since": "0.0.1" }, { - "name": "createLogger", - "type": "coursier.lmcoursier.CreateLogger?", + "name": "logger", + "type": "coursier.cache.CacheLogger?", "default": "None", "since": "0.0.1" }, diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala index 60ef7c829..74a04b65d 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala @@ -8,7 +8,7 @@ final case class ArtifactsParams( classifiers: Option[Seq[Classifier]], resolutions: Seq[Resolution], includeSignatures: Boolean, - logger: CacheLogger, + loggerOpt: Option[CacheLogger], projectName: String, sbtClassifiers: Boolean, cacheParams: CacheParams diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala index 9e94806d7..3adf5a0e2 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala @@ -1,92 +1,74 @@ package coursier.lmcoursier import java.io.File -import java.util.concurrent.ExecutorService -import coursier.cache.CacheLogger -import coursier.{Artifact, Cache, CachePolicy, FileError} -import coursier.util.{Schedulable, Task} +import coursier.cache.FileCache +import coursier.Artifact +import coursier.cache.loggers.{ProgressBarRefreshDisplay, RefreshLogger} +import coursier.core.Type +import coursier.util.Schedulable import sbt.util.Logger -import scala.concurrent.ExecutionContext - object ArtifactsRun { def artifacts( params: ArtifactsParams, verbosityLevel: Int, log: Logger - ): Either[ResolutionError.UnknownDownloadException, Map[Artifact, Either[FileError, File]]] = { - - val allArtifacts0 = params.resolutions.flatMap(_.dependencyArtifacts(params.classifiers)).map(_._3) - - val allArtifacts = - if (params.includeSignatures) - allArtifacts0.flatMap { a => - val sigOpt = a.extra.get("sig") - Seq(a) ++ sigOpt.toSeq - } - else - allArtifacts0 - + ): Either[coursier.error.FetchError, Map[Artifact, 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 { - var pool: ExecutorService = null - var artifactsLogger: CacheLogger = null - val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1 - val artifactFilesOrErrors = try { - pool = Schedulable.fixedThreadPool(params.cacheParams.parallel) + val artifactInitialMessage = + if (verbosityLevel >= 0) + s"Fetching artifacts of ${params.projectName}" + + (if (params.sbtClassifiers) " (sbt classifiers)" else "") + else + "" - val artifactFileOrErrorTasks = allArtifacts.toVector.distinct.map { a => - Cache.file[Task]( - a, - params.cacheParams.cacheLocation, - params.cacheParams.cachePolicies, - checksums = params.cacheParams.checksum, - logger = Some(params.logger), - pool = pool, - ttl = params.cacheParams.ttl + Schedulable.withFixedThreadPool(params.cacheParams.parallel) { pool => + + coursier.Artifacts() + .withResolutions(params.resolutions) + .withArtifactTypes(Set(Type.all)) + .withClassifiers(params.classifiers.getOrElse(Nil).toSet) + .withTransformArtifacts { l => + if (params.includeSignatures) + l.flatMap { a => + val sigOpt = a.extra.get("sig") + Seq(a) ++ sigOpt.toSeq + } + else + l + } + .withCache( + FileCache() + .withLocation(params.cacheParams.cacheLocation) + .withCachePolicies(params.cacheParams.cachePolicies) + .withChecksums(params.cacheParams.checksum) + .withLogger( + params.loggerOpt.getOrElse { + RefreshLogger.create( + 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 "") + ) + ) + ) + } + ) + .withTtl(params.cacheParams.ttl) + .withPool(pool) ) - .run - .map((a, _)) - } - - val artifactInitialMessage = - if (verbosityLevel >= 0) - s"Fetching artifacts of ${params.projectName}" + - (if (params.sbtClassifiers) " (sbt classifiers)" else "") - else - "" - - if (verbosityLevel >= 2) - log.info(artifactInitialMessage) - - artifactsLogger = params.logger - artifactsLogger.init(if (printOptionalMessage) log.info(artifactInitialMessage)) - - Task.gather.gather(artifactFileOrErrorTasks).attempt.unsafeRun()(ExecutionContext.fromExecutorService(pool)) match { - case Left(ex) => - Left(ResolutionError.UnknownDownloadException(ex)) - case Right(l) => - Right(l.toMap) - } - } finally { - if (pool != null) - pool.shutdown() - if (artifactsLogger != null) - if ((artifactsLogger.stopDidPrintSomething() && printOptionalMessage) || verbosityLevel >= 2) - log.info( - s"Fetched artifacts of ${params.projectName}" + - (if (params.sbtClassifiers) " (sbt classifiers)" else "") - ) + .either() + .map(_.toMap) } - - artifactFilesOrErrors } - } } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala index e656f3464..b106635c4 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala @@ -1,13 +1,12 @@ package coursier.lmcoursier -import java.io.{File, OutputStreamWriter} +import java.io.File -import _root_.coursier.{Artifact, CachePolicy, FileError, Organization, Resolution, TermDisplay, organizationString} +import _root_.coursier.{Artifact, Organization, Resolution, organizationString} import _root_.coursier.core.{Classifier, Configuration, ModuleName} import _root_.coursier.extra.Typelevel -import _root_.coursier.ivy.IvyRepository import _root_.coursier.lmcoursier.Inputs.withAuthenticationByHost -import coursier.cache.CacheDefaults +import coursier.cache.{CacheDefaults, CachePolicy} import coursier.params.CacheParams import sbt.internal.librarymanagement.IvySbt import sbt.librarymanagement._ @@ -77,9 +76,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen val verbosityLevel = 0 val ttl = CacheDefaults.ttl - val logger = conf.createLogger.map(_.create()).getOrElse { - new TermDisplay(new OutputStreamWriter(System.err), fallbackMode = true) - } + val loggerOpt = conf.logger val cache = conf.cache.getOrElse(CacheDefaults.location) val cachePolicies = CachePolicy.default val checksums = CacheDefaults.checksums @@ -138,22 +135,20 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen parentProjectCache = Map.empty, interProjectDependencies = conf.interProjectDependencies, internalRepositories = Seq(interProjectRepo), - typelevel = typelevel, sbtClassifiers = false, projectName = projectName, - logger = logger, - cacheParams = coursier.params.CacheParams( - cacheLocation = cache, - cachePolicies = cachePolicies, - ttl = ttl, - checksum = checksums, - parallel = conf.parallelDownloads - ), - params = coursier.params.ResolutionParams( - maxIterations = conf.maxIterations, - profiles = conf.mavenProfiles.toSet, - forceVersion = Map.empty - ) + loggerOpt = loggerOpt, + cacheParams = coursier.params.CacheParams() + .withCacheLocation(cache) + .withCachePolicies(cachePolicies) + .withTtl(ttl) + .withChecksum(checksums) + .withParallel(conf.parallelDownloads), + params = coursier.params.ResolutionParams() + .withMaxIterations(conf.maxIterations) + .withProfiles(conf.mavenProfiles.toSet) + .withForceVersion(Map.empty) + .withTypelevel(typelevel) ) def artifactsParams(resolutions: Map[Set[Configuration], Resolution]) = @@ -161,16 +156,15 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen classifiers = classifiers, resolutions = resolutions.values.toSeq, includeSignatures = false, - logger = logger, + loggerOpt = loggerOpt, projectName = projectName, sbtClassifiers = false, - cacheParams = CacheParams( - parallel = conf.parallelDownloads, - cacheLocation = cache, - checksum = checksums, - ttl = ttl, - cachePolicies = cachePolicies - ) + cacheParams = CacheParams() + .withParallel(conf.parallelDownloads) + .withCacheLocation(cache) + .withChecksum(checksums) + .withTtl(ttl) + .withCachePolicies(cachePolicies) ) val sbtBootJarOverrides = SbtBootJars( @@ -183,7 +177,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen def updateParams( resolutions: Map[Set[Configuration], Resolution], - artifacts: Map[Artifact, Either[FileError, File]] + artifacts: Map[Artifact, File] ) = UpdateParams( shadedConfigOpt = None, @@ -192,7 +186,6 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen configs = configs, dependencies = dependencies, res = resolutions, - ignoreArtifactErrors = false, includeSignatures = false, sbtBootJarOverrides = sbtBootJarOverrides ) @@ -201,37 +194,51 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen resolutions <- ResolutionRun.resolutions(resolutionParams, verbosityLevel, log) artifactsParams0 = artifactsParams(resolutions) artifacts <- ArtifactsRun.artifacts(artifactsParams0, verbosityLevel, log) - updateParams0 = updateParams(resolutions, artifacts) - updateReport <- UpdateRun.update(updateParams0, verbosityLevel, log) - } yield updateReport + } yield { + val updateParams0 = updateParams(resolutions, artifacts) + UpdateRun.update(updateParams0, verbosityLevel, log) + } e.left.map(unresolvedWarningOrThrow(uwconfig, _)) } - private def resolutionException(ex: ResolutionError): Either[Throwable, ResolveException] = - ex match { - case e: ResolutionError.MetadataDownloadErrors => - val r = new ResolveException( - e.errors.flatMap(_._2), - e.errors.map { - case ((mod, ver), _) => - ModuleID(mod.organization.value, mod.name.value, ver) - .withExtraAttributes(mod.attributes) - } - ) - Right(r) - case _ => Left(ex.exception()) - } - private def unresolvedWarningOrThrow( uwconfig: UnresolvedWarningConfiguration, - ex: ResolutionError - ): UnresolvedWarning = - resolutionException(ex) match { - case Left(t) => throw t - case Right(e) => - UnresolvedWarning(e, uwconfig) + ex: coursier.error.CoursierError + ): UnresolvedWarning = { + + // TODO Take coursier.error.FetchError.DownloadingArtifacts into account + + val downloadErrors = ex match { + case ex0: coursier.error.ResolutionError => + ex0.errors.collect { + case err: coursier.error.ResolutionError.CantDownloadModule => err + } + case _ => + Nil } + val otherErrors = ex match { + case ex0: coursier.error.ResolutionError => + ex0.errors.flatMap { + case _: coursier.error.ResolutionError.CantDownloadModule => None + case err => Some(err) + } + case _ => + Seq(ex) + } + + if (otherErrors.isEmpty) { + val r = new ResolveException( + downloadErrors.map(_.getMessage), + downloadErrors.map { err => + ModuleID(err.module.organization.value, err.module.name.value, err.version) + .withExtraAttributes(err.module.attributes) + } + ) + UnresolvedWarning(r, uwconfig) + } else + throw ex + } } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CreateLogger.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CreateLogger.scala deleted file mode 100644 index ffac71864..000000000 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CreateLogger.scala +++ /dev/null @@ -1,5 +0,0 @@ -package coursier.lmcoursier - -import coursier.cache.CacheLogger - -final case class CreateLogger(create: () => CacheLogger) diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala index 150ee9515..d9ea873cb 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala @@ -5,7 +5,7 @@ import coursier.ivy.IvyXml.{mappings => ivyXmlMappings} import java.net.{MalformedURLException, URL} import coursier.cache.CacheUrl -import coursier.{Attributes, Cache, Dependency, Module} +import coursier.{Attributes, Dependency, Module} import coursier.core._ import coursier.maven.MavenRepository import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionError.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionError.scala deleted file mode 100644 index d61081277..000000000 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionError.scala +++ /dev/null @@ -1,124 +0,0 @@ -package coursier.lmcoursier - -import coursier.FileError -import coursier.core.Module - -import scala.collection.mutable.ArrayBuffer - -sealed abstract class ResolutionError extends Product with Serializable { - - final def cause: Option[Throwable] = this match { - case ResolutionError.MaximumIterationsReached => None - case ResolutionError.UnknownException(ex) => Some(ex) - case ResolutionError.UnknownDownloadException(ex) => Some(ex) - case _: ResolutionError.Conflicts => None - case _: ResolutionError.MetadataDownloadErrors => None - case _: ResolutionError.DownloadErrors => None - } - - final def message: String = this match { - case ResolutionError.MaximumIterationsReached => - "Maximum number of iteration of dependency resolution reached" - case ResolutionError.UnknownException(_) => - "Exception during resolution" - case ResolutionError.UnknownDownloadException(ex) => - "Error while downloading / verifying artifacts" - case ResolutionError.Conflicts(description) => - description - - case err: ResolutionError.MetadataDownloadErrors => - err.description() - - case err: ResolutionError.DownloadErrors => - err.description(verbose = true) - } - - final def exception(): ResolutionException = - new ResolutionException(this) - - final def throwException(): Nothing = - throw exception() -} - -object ResolutionError { - - case object MaximumIterationsReached extends ResolutionError - final case class UnknownException(ex: Throwable) extends ResolutionError - final case class UnknownDownloadException(ex: Throwable) extends ResolutionError - final case class Conflicts(description: String) extends ResolutionError - - final case class MetadataDownloadErrors(errors: Seq[((Module, String), Seq[String])]) extends ResolutionError { - def description(): String = { - - def grouped(errs: Seq[String]) = - errs - .map { s => - s.split(": ", 2) match { - case Array(k, v) => (k, v) - case _ => ("", s) - } - } - .groupBy(_._1) - .mapValues(_.map(_._2)) - .toVector - .sortBy(_._1) - - - val lines = new ArrayBuffer[String] - def print(s: String, indentLevel: Int = 0) = - lines += " " * indentLevel * 2 + s - def result = lines.mkString("\n") - - - print(s"Encountered ${errors.length} error(s) in dependency resolution:") - - for (((mod, ver), errs) <- errors) { - print(s"$mod:$ver:", 1) - - for ((type0, errs0) <- grouped(errs)) - if (type0.isEmpty) - for (err <- errs0) - print(err, 2) - else - errs0 match { - case Seq(err) => - print(s"$type0: $err", 2) - case _ => - print(s"$type0:", 2) - for (err <- errs0) - print(err, 3) - } - } - - result - } - } - - final case class DownloadErrors(errors: Seq[FileError]) extends ResolutionError { - - def description(verbose: Boolean): String = { - - val groupedArtifactErrors = errors - .groupBy(_.`type`) - .mapValues(_.map(_.message).sorted) - .toVector - .sortBy(_._1) - - - val lines = new ArrayBuffer[String] - def print(s: String, indentLevel: Int = 0) = - lines += " " * indentLevel * 2 + s - def result = lines.mkString("\n") - - - for ((type0, errors) <- groupedArtifactErrors) { - print(s"${errors.size} $type0") - if (verbose) - for (err <- errors) - print(err, 1) - } - - result - } - } -} diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionException.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionException.scala deleted file mode 100644 index 903dba9bc..000000000 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionException.scala +++ /dev/null @@ -1,10 +0,0 @@ -package coursier.lmcoursier - -final class ResolutionException( - val error: ResolutionError -) extends Exception( - error.message, - error.cause.orNull, - true, - false // don't keep stack trace around (improves readability from the SBT console) -) diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala index c30fd0883..f980bcf6f 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala @@ -3,14 +3,10 @@ package coursier.lmcoursier import java.io.File import coursier.cache.CacheLogger -import coursier.{FallbackDependenciesRepository, ProjectCache, Resolution, moduleNameString} +import coursier.{FallbackDependenciesRepository, ProjectCache} import coursier.core._ -import coursier.extra.Typelevel -import coursier.ivy.PropertiesPattern import sbt.librarymanagement.{Resolver, URLRepository} -import scala.collection.mutable.ArrayBuffer - final case class ResolutionParams( dependencies: Seq[(Configuration, Dependency)], fallbackDependencies: Seq[FallbackDependency], @@ -20,10 +16,9 @@ final case class ResolutionParams( parentProjectCache: ProjectCache, interProjectDependencies: Seq[Project], internalRepositories: Seq[Repository], - typelevel: Boolean, sbtClassifiers: Boolean, projectName: String, - logger: CacheLogger, + loggerOpt: Option[CacheLogger], cacheParams: coursier.params.CacheParams, params: coursier.params.ResolutionParams ) { @@ -47,54 +42,19 @@ final case class ResolutionParams( mainRepositories ++ fallbackDependenciesRepositories - private val noOptionalFilter: Option[Dependency => Boolean] = Some(dep => !dep.optional) - private val typelevelOrgSwap: Option[Dependency => Dependency] = Some(Typelevel.swap(_)) - - private def forcedScalaModules( - scalaOrganization: Organization, - scalaVersion: String - ): Map[Module, String] = - Map( - Module(scalaOrganization, name"scala-library", Map.empty) -> scalaVersion, - Module(scalaOrganization, name"scala-compiler", Map.empty) -> scalaVersion, - Module(scalaOrganization, name"scala-reflect", Map.empty) -> scalaVersion, - Module(scalaOrganization, name"scalap", Map.empty) -> scalaVersion - ) - - private def startRes(configs: Set[Configuration]) = Resolution( - dependencies - .collect { - case (config, dep) if configs(config) => - dep - }, - filter = noOptionalFilter, - userActivations = - if (params.profiles.isEmpty) - None - else - Some(params.profiles.iterator.map(_ -> true).toMap), - forceVersions = - // order matters here - params.forceVersion ++ - autoScalaLibOpt - .filter(_ => configs(Configuration.compile) || configs(Configuration("scala-tool"))) - .map { case (so, sv) => forcedScalaModules(so, sv) } - .getOrElse(Map.empty) ++ - interProjectDependencies.map(_.moduleVersion), - projectCache = parentProjectCache, - mapDependencies = if (typelevel && (configs(Configuration.compile) || configs(Configuration("scala-tool")))) typelevelOrgSwap else None - ) - - lazy val allStartRes = configGraphs.map(configs => configs -> startRes(configs)).toMap - lazy val resolutionKey = SbtCoursierCache.ResolutionKey( dependencies, repositories, - params.profiles, - allStartRes, + copy( + parentProjectCache = Map.empty, + loggerOpt = None + ), sbtClassifiers ) + override lazy val hashCode = + ResolutionParams.unapply(this).get.## + } object ResolutionParams { @@ -117,39 +77,6 @@ object ResolutionParams { ) ++ sys.props } - private def exceptionPatternParser(): String => coursier.ivy.Pattern = { - - val props = sys.props.toMap - - val extraProps = new ArrayBuffer[(String, String)] - - def addUriProp(key: String): Unit = - for (b <- props.get(key)) { - val uri = new File(b).toURI.toString - extraProps += s"$key.uri" -> uri - } - - addUriProp("sbt.global.base") - addUriProp("user.home") - - { - s => - val p = PropertiesPattern.parse(s) match { - case Left(err) => - throw new Exception(s"Cannot parse pattern $s: $err") - case Right(p) => - p - } - - p.substituteProperties(props ++ extraProps) match { - case Left(err) => - throw new Exception(err) - case Right(p) => - p - } - } - } - private val slowReposBase = Seq( "https://repo.typesafe.com/", "https://repo.scala-sbt.org/", diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala index 73ddf8109..7ad211c02 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala @@ -1,136 +1,107 @@ package coursier.lmcoursier -import java.util.concurrent.ExecutorService - -import coursier.cache.CacheLogger -import coursier.{Cache, Resolution} +import coursier.cache.FileCache +import coursier.{Resolution, Resolve} +import coursier.cache.loggers.{ProgressBarRefreshDisplay, RefreshLogger} import coursier.core._ import coursier.ivy.IvyRepository import coursier.maven.MavenRepository -import coursier.util.{Print, Schedulable, Task} +import coursier.util.Schedulable import sbt.util.Logger -import scala.concurrent.ExecutionContext - object ResolutionRun { def resolution( params: ResolutionParams, verbosityLevel: Int, log: Logger, - startRes: Resolution - ): Either[ResolutionError, Resolution] = { + configs: Set[Configuration] + ): Either[coursier.error.ResolutionError, Resolution] = { - // TODO Re-use the thread pool across resolutions / downloads? - var pool: ExecutorService = null - - var resLogger: CacheLogger = null + val isCompileConfig = + configs(Configuration.compile) || configs(Configuration("scala-tool")) val printOptionalMessage = verbosityLevel >= 0 && verbosityLevel <= 1 - val resOrError: Either[ResolutionError, Resolution] = try { - pool = Schedulable.fixedThreadPool(params.cacheParams.parallel) - resLogger = params.logger + def depsRepr(deps: Seq[(Configuration, Dependency)]) = + deps.map { case (config, dep) => + s"${dep.module}:${dep.version}:${config.value}->${dep.configuration.value}" + }.sorted.distinct - val fetchs = Cache.fetchs[Task](params.cacheParams.cacheLocation, params.cacheParams.cachePolicies, checksums = params.cacheParams.checksum, logger = Some(params.logger), pool = pool, ttl = params.cacheParams.ttl) + val initialMessage = + Seq( + if (verbosityLevel >= 0) + Seq(s"Updating ${params.projectName}" + (if (params.sbtClassifiers) " (sbt classifiers)" else "")) + else + Nil, + if (verbosityLevel >= 2) + depsRepr(params.dependencies).map(depRepr => + s" $depRepr" + ) + else + Nil + ).flatten.mkString("\n") - val fetch = ResolutionProcess.fetch( - params.repositories, - fetchs.head, fetchs.tail: _* - ) - - def depsRepr(deps: Seq[(Configuration, Dependency)]) = - deps.map { case (config, dep) => - s"${dep.module}:${dep.version}:${config.value}->${dep.configuration.value}" - }.sorted.distinct - - if (verbosityLevel >= 2) { - val repoReprs = params.repositories.map { - case r: IvyRepository => - s"ivy:${r.pattern}" - case _: InterProjectRepository => - "inter-project" - case r: MavenRepository => - r.root - case r => - // should not happen - r.toString - } - - log.info( - "Repositories:\n" + - repoReprs.map(" " + _).mkString("\n") - ) + if (verbosityLevel >= 2) { + val repoReprs = params.repositories.map { + case r: IvyRepository => + s"ivy:${r.pattern}" + case _: InterProjectRepository => + "inter-project" + case r: MavenRepository => + r.root + case r => + // should not happen + r.toString } - val initialMessage = - Seq( - if (verbosityLevel >= 0) - Seq(s"Updating ${params.projectName}" + (if (params.sbtClassifiers) " (sbt classifiers)" else "")) - else - Nil, - if (verbosityLevel >= 2) - depsRepr(params.dependencies).map(depRepr => - s" $depRepr" - ) - else - Nil - ).flatten.mkString("\n") - - if (verbosityLevel >= 2) - log.info(initialMessage) - - resLogger = params.logger - resLogger.init(if (printOptionalMessage) log.info(initialMessage)) - - startRes - .process - .run(fetch, params.params.maxIterations) - .attempt - .unsafeRun()(ExecutionContext.fromExecutorService(pool)) - .left - .map(ex => - ResolutionError.UnknownException(ex) - ) - } finally { - if (pool != null) - pool.shutdown() - if (resLogger != null) - if ((resLogger.stopDidPrintSomething() && printOptionalMessage) || verbosityLevel >= 2) - log.info(s"Resolved ${params.projectName} dependencies") + log.info( + "Repositories:\n" + + repoReprs.map(" " + _).mkString("\n") + ) } - resOrError.flatMap { res => - if (!res.isDone) - Left( - ResolutionError.MaximumIterationsReached - ) - else if (res.conflicts.nonEmpty) { - val projCache = res.projectCache.mapValues { case (_, p) => p } + if (verbosityLevel >= 2) + log.info(initialMessage) - Left( - ResolutionError.Conflicts( - "Conflict(s) in dependency resolution:\n " + - Print.dependenciesUnknownConfigs(res.conflicts.toVector, projCache) - ) - ) - } else if (res.errors.nonEmpty) { - val internalRepositoriesLen = params.internalRepositories.length - val errors = - if (params.repositories.length > internalRepositoriesLen) - // drop internal repository errors - res.errors.map { - case (dep, errs) => - dep -> errs.drop(internalRepositoriesLen) - } - else - res.errors + Schedulable.withFixedThreadPool(params.cacheParams.parallel) { pool => - Left( - ResolutionError.MetadataDownloadErrors(errors) + Resolve() + .withDependencies( + params.dependencies.collect { + case (config, dep) if configs(config) => + dep + } ) - } else - Right(res) + .withRepositories(params.repositories) + .withResolutionParams( + params + .params + .addForceVersion(params.interProjectDependencies.map(_.moduleVersion): _*) + .withForceScalaVersion(isCompileConfig && params.autoScalaLibOpt.nonEmpty) + .withScalaVersion(params.autoScalaLibOpt.map(_._2)) + .withTypelevel(params.params.typelevel && isCompileConfig) + ) + .withCache( + FileCache() + .withLocation(params.cacheParams.cacheLocation) + .withCachePolicies(params.cacheParams.cachePolicies) + .withChecksums(params.cacheParams.checksum) + .withPool(pool) + .withTtl(params.cacheParams.ttl) + .withLogger( + params.loggerOpt.getOrElse { + RefreshLogger.create( + ProgressBarRefreshDisplay.create( + if (printOptionalMessage) log.info(initialMessage), + if (printOptionalMessage || verbosityLevel >= 2) + log.info(s"Resolved ${params.projectName} dependencies") + ) + ) + } + ) + ) + .either() } } @@ -138,7 +109,7 @@ object ResolutionRun { params: ResolutionParams, verbosityLevel: Int, log: Logger - ): Either[ResolutionError, Map[Set[Configuration], Resolution]] = { + ): Either[coursier.error.ResolutionError, Map[Set[Configuration], Resolution]] = { // TODO Warn about possible duplicated modules from source repositories? @@ -153,11 +124,11 @@ object ResolutionRun { // Downloads are already parallel, no need to parallelize further, anyway. val resOrError = Lock.lock.synchronized { - params.allStartRes.foldLeft[Either[ResolutionError, Map[Set[Configuration], Resolution]]](Right(Map())) { - case (acc, (config, startRes)) => + params.configGraphs.foldLeft[Either[coursier.error.ResolutionError, Map[Set[Configuration], Resolution]]](Right(Map())) { + case (acc, config) => for { m <- acc - res <- resolution(params, verbosityLevel, log, startRes) + res <- resolution(params, verbosityLevel, log, config) } yield m + (config -> res) } } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala index 1c0959505..b09ea7076 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala @@ -40,8 +40,7 @@ object SbtCoursierCache { final case class ResolutionKey( dependencies: Seq[(Configuration, Dependency)], repositories: Seq[Repository], - userEnabledProfiles: Set[String], - resolution: Map[Set[Configuration], Resolution], + params: ResolutionParams, sbtClassifiers: Boolean ) @@ -49,8 +48,7 @@ object SbtCoursierCache { dependencies: Seq[(Configuration, Dependency)], resolution: Map[Set[Configuration], Resolution], withClassifiers: Boolean, - sbtClassifiers: Boolean, - ignoreArtifactErrors: Boolean + sbtClassifiers: Boolean ) diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala index 71c780449..84f7f9332 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala @@ -2,34 +2,19 @@ package coursier.lmcoursier import java.io.File -import coursier.FileError import coursier.core._ final case class UpdateParams( shadedConfigOpt: Option[(String, Configuration)], - artifacts: Map[Artifact, Either[FileError, File]], + artifacts: Map[Artifact, File], classifiers: Option[Seq[Classifier]], configs: Map[Configuration, Set[Configuration]], dependencies: Seq[(Configuration, Dependency)], res: Map[Set[Configuration], Resolution], - ignoreArtifactErrors: Boolean, includeSignatures: Boolean, sbtBootJarOverrides: Map[(Module, String), File] ) { - lazy val artifactFiles = artifacts.collect { - case (artifact, Right(file)) => - artifact -> file - } - - // can be non empty only if ignoreArtifactErrors is true or some optional artifacts are not found - lazy val erroredArtifacts = artifacts - .collect { - case (artifact, Left(_)) => - artifact - } - .toSet - def artifactFileOpt( module: Module, version: String, @@ -47,12 +32,7 @@ final case class UpdateParams( else None - val res = fromBootJars.orElse(artifactFiles.get(artifact)) - - if (res.isEmpty && !erroredArtifacts(artifact)) - sys.error(s"${artifact.url} not downloaded (should not happen)") - - res + fromBootJars.orElse(artifacts.get(artifact)) } } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala index cdecaf1ff..61a3d4179 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala @@ -54,7 +54,7 @@ object UpdateRun { params: UpdateParams, verbosityLevel: Int, log: Logger - ): Either[ResolutionError.DownloadErrors, UpdateReport] = { + ): UpdateReport = { val configResolutions = params.res.flatMap { case (configs, r) => @@ -83,36 +83,15 @@ object UpdateRun { log.info(repr.split('\n').map(" " + _).mkString("\n")) } - val artifactErrors = params - .artifacts - .toVector - .collect { - case (a, Left(err)) if !a.optional || !err.notFound => - a -> err - } - - def report = - ToSbt.updateReport( - depsByConfig, - configResolutions, - params.configs, - params.classifiers, - params.artifactFileOpt, - log, - includeSignatures = params.includeSignatures - ) - - if (artifactErrors.isEmpty) - Right(report) - else { - val error = ResolutionError.DownloadErrors(artifactErrors.map(_._2)) - - if (params.ignoreArtifactErrors) { - log.warn(error.description(verbosityLevel >= 1)) - Right(report) - } else - Left(error) - } + ToSbt.updateReport( + depsByConfig, + configResolutions, + params.configs, + params.classifiers, + params.artifactFileOpt, + log, + includeSignatures = params.includeSignatures + ) } private def grouped[K, V](map: Seq[(K, V)])(mapKey: K => K): Map[K, Seq[V]] = diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala index ea626fb69..45832c5c0 100644 --- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala +++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala @@ -1,11 +1,11 @@ package coursier.sbtcoursiershared -import java.io.{File, OutputStreamWriter} +import java.io.File -import coursier.cache.CacheDefaults -import coursier.{Cache, Credentials, TermDisplay} +import coursier.cache.{CacheDefaults, CacheLogger} +import coursier.Credentials import coursier.core.{Configuration, Project, Publication} -import coursier.lmcoursier.{CreateLogger, FallbackDependency, SbtCoursierCache} +import coursier.lmcoursier.{FallbackDependency, SbtCoursierCache} import sbt.{AutoPlugin, Classpaths, Compile, Setting, TaskKey, Test, settingKey, taskKey} import sbt.Keys._ import sbt.librarymanagement.{Resolver, URLRepository} @@ -37,13 +37,10 @@ object SbtCoursierShared extends AutoPlugin { val coursierUseSbtCredentials = settingKey[Boolean]("") val coursierCredentials = taskKey[Map[String, Credentials]]("") - val coursierCreateLogger = taskKey[CreateLogger]("") + val coursierLogger = taskKey[Option[CacheLogger]]("") val coursierCache = settingKey[File]("") - type CoursierCreateLogger = coursier.lmcoursier.CreateLogger - val CoursierCreateLogger = coursier.lmcoursier.CreateLogger - val sbtCoursierVersion = Properties.version } @@ -58,7 +55,7 @@ object SbtCoursierShared extends AutoPlugin { coursierKeepPreloaded := false, coursierUseSbtCredentials := true, coursierCredentials := Map.empty, - coursierCreateLogger := CreateLogger { () => new TermDisplay(new OutputStreamWriter(System.err)) }, + coursierLogger := None, coursierCache := CacheDefaults.location ) 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 1db2a4057..6269f2d1c 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala @@ -2,12 +2,12 @@ package coursier.sbtcoursier import java.io.File -import coursier.{Artifact, FileError} +import coursier.Artifact import coursier.core._ import coursier.lmcoursier._ import coursier.params.CacheParams import coursier.sbtcoursier.Keys._ -import coursier.sbtcoursiershared.SbtCoursierShared.autoImport.{coursierCache, coursierCreateLogger} +import coursier.sbtcoursiershared.SbtCoursierShared.autoImport.{coursierCache, coursierLogger} import sbt.Def import sbt.Keys._ @@ -18,7 +18,7 @@ object ArtifactsTasks { sbtClassifiers: Boolean = false, ignoreArtifactErrors: Boolean = false, includeSignatures: Boolean = false - ): Def.Initialize[sbt.Task[Map[Artifact, Either[FileError, File]]]] = { + ): Def.Initialize[sbt.Task[Map[Artifact, File]]] = { val resTask: sbt.Def.Initialize[sbt.Task[Seq[Resolution]]] = if (withClassifiers && sbtClassifiers) @@ -44,7 +44,7 @@ object ArtifactsTasks { val cachePolicies = coursierCachePolicies.value val ttl = coursierTtl.value val cache = coursierCache.value - val createLogger = coursierCreateLogger.value + val createLogger = coursierLogger.value val log = streams.value.log @@ -57,16 +57,15 @@ object ArtifactsTasks { classifiers = classifiers, resolutions = res, includeSignatures = includeSignatures, - logger = createLogger.create(), + loggerOpt = createLogger, projectName = projectName, sbtClassifiers = sbtClassifiers, - cacheParams = CacheParams( - parallel = parallelDownloads, - cacheLocation = cache, - checksum = artifactsChecksums, - ttl = ttl, - cachePolicies = cachePolicies - ) + cacheParams = CacheParams() + .withParallel(parallelDownloads) + .withCacheLocation(cache) + .withChecksum(artifactsChecksums) + .withTtl(ttl) + .withCachePolicies(cachePolicies) ) val resOrError = ArtifactsRun.artifacts( @@ -77,7 +76,7 @@ object ArtifactsTasks { resOrError match { case Left(err) => - err.throwException() + throw err case Right(res) => res } diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala index 1400a079d..fa164d19d 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala @@ -1,7 +1,6 @@ package coursier.sbtcoursier -import coursier.cache.CacheDefaults -import coursier.{Cache, CachePolicy} +import coursier.cache.{CacheDefaults, CachePolicy} import coursier.core.{Configuration, ResolutionProcess} import coursier.sbtcoursiershared.SbtCoursierShared import sbt.{Cache => _, Configuration => _, _} @@ -156,14 +155,12 @@ object CoursierPlugin extends AutoPlugin { ).value, updateClassifiers := UpdateTasks.updateTask( shadedConfigOpt, - withClassifiers = true, - ignoreArtifactErrors = true + withClassifiers = true ).value, updateSbtClassifiers.in(Defaults.TaskGlobal) := UpdateTasks.updateTask( shadedConfigOpt, withClassifiers = true, - sbtClassifiers = true, - ignoreArtifactErrors = true + sbtClassifiers = true ).value, coursierConfigGraphs := InputsTasks.ivyGraphsTask.value, coursierSbtClassifiersModule := classifiersModule.in(updateSbtClassifiers).value, diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala index 894fca9fe..1b896b0d6 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala @@ -1,9 +1,9 @@ package coursier.sbtcoursier import java.io.File -import java.net.URL -import coursier.{Cache, CachePolicy, Credentials, FileError, ProjectCache} +import coursier.cache.CachePolicy +import coursier.ProjectCache import coursier.core._ import sbt.librarymanagement.{GetClassifiersModule, Resolver} import sbt.{InputKey, SettingKey, TaskKey} @@ -47,8 +47,8 @@ object Keys { "coursier-what-depends-on", "Prints dependencies and transitive dependencies as an inverted tree for a specific module (dependees as children)" ) - val coursierArtifacts = TaskKey[Map[Artifact, Either[FileError, File]]]("coursier-artifacts") - val coursierSignedArtifacts = TaskKey[Map[Artifact, Either[FileError, File]]]("coursier-signed-artifacts") - val coursierClassifiersArtifacts = TaskKey[Map[Artifact, Either[FileError, File]]]("coursier-classifiers-artifacts") - val coursierSbtClassifiersArtifacts = TaskKey[Map[Artifact, Either[FileError, File]]]("coursier-sbt-classifiers-artifacts") + val coursierArtifacts = TaskKey[Map[Artifact, File]]("coursier-artifacts") + val coursierSignedArtifacts = TaskKey[Map[Artifact, File]]("coursier-signed-artifacts") + val coursierClassifiersArtifacts = TaskKey[Map[Artifact, File]]("coursier-classifiers-artifacts") + val coursierSbtClassifiersArtifacts = TaskKey[Map[Artifact, File]]("coursier-sbt-classifiers-artifacts") } diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala index dc4430097..c066a9e0b 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala @@ -3,7 +3,6 @@ package coursier.sbtcoursier import coursier.ProjectCache import coursier.core._ import coursier.extra.Typelevel -import coursier.ivy.IvyRepository import coursier.lmcoursier._ import coursier.lmcoursier.Inputs.withAuthenticationByHost import coursier.sbtcoursier.Keys._ @@ -60,7 +59,7 @@ object ResolutionTasks { val cachePolicies = coursierCachePolicies.value val ttl = coursierTtl.value val cache = coursierCache.value - val createLogger = coursierCreateLogger.value + val createLogger = coursierLogger.value val log = streams.value.log @@ -120,22 +119,21 @@ object ResolutionTasks { parentProjectCache = parentProjectCache, interProjectDependencies = interProjectDependencies, internalRepositories = Seq(interProjectRepo), - typelevel = typelevel, sbtClassifiers = sbtClassifiers, projectName = projectName, - logger = createLogger.create(), - cacheParams = coursier.params.CacheParams( - cacheLocation = cache, - cachePolicies = cachePolicies, - ttl = ttl, - checksum = checksums, - parallel = parallelDownloads - ), - params = coursier.params.ResolutionParams( - maxIterations = maxIterations, - profiles = userEnabledProfiles, - forceVersion = userForceVersions - ) + loggerOpt = createLogger, + cacheParams = coursier.params.CacheParams() + .withCacheLocation(cache) + .withCachePolicies(cachePolicies) + .withTtl(ttl) + .withChecksum(checksums) + .withParallel(parallelDownloads) + , + params = coursier.params.ResolutionParams() + .withMaxIterations(maxIterations) + .withProfiles(userEnabledProfiles) + .withForceVersion(userForceVersions) + .withTypelevel(typelevel) ), verbosityLevel, log @@ -143,7 +141,7 @@ object ResolutionTasks { resOrError match { case Left(err) => - err.throwException() + throw err case Right(res) => res } diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala index 84928a14f..7ae6e983a 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala @@ -14,7 +14,6 @@ object UpdateTasks { shadedConfigOpt: Option[(String, Configuration)], withClassifiers: Boolean, sbtClassifiers: Boolean = false, - ignoreArtifactErrors: Boolean = false, includeSignatures: Boolean = false ): Def.Initialize[sbt.Task[UpdateReport]] = { @@ -111,8 +110,7 @@ object UpdateTasks { dependencies, res, withClassifiers, - sbtClassifiers, - ignoreArtifactErrors + sbtClassifiers ) SbtCoursierCache.default.reportOpt(key) match { @@ -132,21 +130,16 @@ object UpdateTasks { configs, dependencies, res, - ignoreArtifactErrors, includeSignatures, sbtBootJarOverrides ) - val repOrError = + val rep = Lock.lock.synchronized { UpdateRun.update(params, verbosityLevel, log) } - for (rep <- repOrError) - SbtCoursierCache.default.putReport(key, rep) - repOrError match { - case Left(err) => err.throwException() - case Right(rep) => rep - } + SbtCoursierCache.default.putReport(key, rep) + rep } } } diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt index 4ffb40ab7..d45af224f 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt @@ -6,34 +6,33 @@ libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.25" coursierCache := baseDirectory.value / "cache" logFile := baseDirectory.value / "log" -coursierCreateLogger := { +coursierLogger := { val logStream = new java.io.PrintStream(logFile.value) def log(msg: String): Unit = { println(msg) logStream.println(msg) } val cacheFile = coursierCache.value - ;CoursierCreateLogger { () => - new coursier.cache.CacheLogger { - override def init(beforeOutput: => Unit): Unit = { - beforeOutput - log("init") - } - override def foundLocally(url: String, file: File): Unit = { - log(s"found $url at ${IO.relativize(cacheFile, file).getOrElse(file)}") - } - override def downloadingArtifact(url: String, file: File): Unit = { - log(s"downloading $url to ${IO.relativize(cacheFile, file).getOrElse(file)}") - } - override def downloadedArtifact(url: String, success: Boolean): Unit = { - log(s"downloaded $url: $success") - } - override def stopDidPrintSomething(): Boolean = { - log("stop") - true - } + + val logger = new coursier.cache.CacheLogger { + override def init(sizeHint: Option[Int]): Unit = { + log("init") + } + override def foundLocally(url: String): Unit = { + log(s"found $url") + } + override def downloadingArtifact(url: String): Unit = { + log(s"downloading $url") + } + override def downloadedArtifact(url: String, success: Boolean): Unit = { + log(s"downloaded $url: $success") + } + override def stop(): Unit = { + log("stop") } } + + Some(logger) } TaskKey[Unit]("checkDownloaded") := { @@ -46,7 +45,7 @@ TaskKey[Unit]("checkDownloaded") := { } val url = "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar" val downloadedMsg = s"downloaded $url: true" - val downloadingMsgStart = s"downloading $url to " + val downloadingMsgStart = s"downloading $url" if (!log.contains(downloadedMsg)) sys.error(s"log doesn't contain '$downloadedMsg'") if (!log.exists(_.startsWith(downloadingMsgStart))) @@ -62,7 +61,7 @@ TaskKey[Unit]("checkFound") := { sys.error(s"log ended with '${log.last}', not stop") } val url = "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar" - val msg = s"found $url at " + val msg = s"found $url" if (!log.exists(_.startsWith(msg))) sys.error(s"log doesn't contain line starting with '$msg'") } diff --git a/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala b/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala index 4fba67dba..9c5c1da1c 100644 --- a/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala +++ b/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala @@ -90,7 +90,7 @@ object LmCoursierPlugin extends AutoPlugin { val authenticationByRepositoryId = coursierCredentials.value.mapValues(_.authentication) val authenticationByHost = authenticationByHostTask.value - val createLogger = coursierCreateLogger.value + val createLogger = coursierLogger.value val cache = coursierCache.value @@ -125,7 +125,7 @@ object LmCoursierPlugin extends AutoPlugin { .withScalaVersion(scalaVer) .withAuthenticationByRepositoryId(authenticationByRepositoryId.toVector.sortBy(_._1)) .withAuthenticationByHost(authenticationByHost.toVector.sortBy(_._1)) - .withCreateLogger(createLogger) + .withLogger(createLogger) .withCache(cache) .withLog(s.log) } diff --git a/modules/sbt-shading/src/main/scala/coursier/Shading.scala b/modules/sbt-shading/src/main/scala/coursier/Shading.scala index 5334205c7..77d9b5a63 100644 --- a/modules/sbt-shading/src/main/scala/coursier/Shading.scala +++ b/modules/sbt-shading/src/main/scala/coursier/Shading.scala @@ -56,7 +56,7 @@ object Shading { currentProject: Project, res: Resolution, configs: Map[Configuration, Set[Configuration]], - artifactFilesOrErrors: Map[Artifact, Either[FileError, File]], + artifactFilesOrErrors: Map[Artifact, File], classpathTypes: Set[Type], baseConfig: Configuration, shadedConf: Configuration, @@ -98,7 +98,7 @@ object Shading { val artifactFilesOrErrors0 = artifactFilesOrErrors .collect { - case (a, Right(f)) => a.url -> f + case (a, f) => a.url -> f } val compileDeps = configDependencies(baseConfig)