diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 5c43452c2..22f0bf251 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -242,8 +242,8 @@ object Defaults extends BuildCommon { forceUpdatePeriod :== None, // coursier settings csrExtraCredentials :== Nil, - csrLogger :== None, - csrCachePath :== LMCoursier.defaultCacheLocation, + csrLogger := LMCoursier.coursierLoggerTask.value, + csrCacheDirectory :== LMCoursier.defaultCacheLocation, csrMavenProfiles :== Set.empty, ) @@ -2160,8 +2160,8 @@ object Classpaths { }).value, moduleName := normalizedName.value, ivyPaths := IvyPaths(baseDirectory.value, bootIvyHome(appConfiguration.value)), - csrCachePath := { - val old = csrCachePath.value + csrCacheDirectory := { + val old = csrCacheDirectory.value val ip = ivyPaths.value val defaultIvyCache = bootIvyHome(appConfiguration.value) if (old != LMCoursier.defaultCacheLocation) old @@ -2438,7 +2438,7 @@ object Classpaths { csrConfiguration := LMCoursier.coursierConfigurationTask(false, false).value, csrResolvers := CoursierRepositoriesTasks.coursierResolversTask.value, csrRecursiveResolvers := CoursierRepositoriesTasks.coursierRecursiveResolversTask.value, - csrSbtResolvers := LMCoursier.coursierSbtResolversTask.value, + csrSbtResolvers := CoursierRepositoriesTasks.coursierSbtResolversTask.value, csrInterProjectDependencies := CoursierInputsTasks.coursierInterProjectDependenciesTask.value, csrFallbackDependencies := CoursierInputsTasks.coursierFallbackDependenciesTask.value, ) ++ diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index fc5c4db35..dfb69d13e 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -324,7 +324,7 @@ object Keys { val internalDependencyConfigurations = settingKey[Seq[(ProjectRef, Set[String])]]("The project configurations that this configuration depends on") val useCoursier = settingKey[Boolean]("Use Coursier for dependency resolution.").withRank(BSetting) - val csrCachePath = settingKey[File]("Coursier cache path").withRank(CSetting) + val csrCacheDirectory = settingKey[File]("Coursier cache directory. Uses -Dsbt.coursier.home or Coursier's default.").withRank(CSetting) val csrMavenProfiles = settingKey[Set[String]]("").withRank(CSetting) private[sbt] val csrConfiguration = taskKey[CoursierConfiguration]("General dependency management (Coursier) settings, such as the resolvers and options to use.").withRank(DTask) private[sbt] val csrProject = taskKey[lmcoursier.definitions.Project]("") diff --git a/main/src/main/scala/sbt/internal/LMCoursier.scala b/main/src/main/scala/sbt/internal/LMCoursier.scala index ab159b13e..4a7c9e2bd 100644 --- a/main/src/main/scala/sbt/internal/LMCoursier.scala +++ b/main/src/main/scala/sbt/internal/LMCoursier.scala @@ -9,14 +9,20 @@ package sbt package internal import java.io.File -import lmcoursier.definitions.{ Classifier, Configuration => CConfiguration } +import lmcoursier.definitions.{ Classifier, Configuration => CConfiguration, CacheLogger } import lmcoursier._ import sbt.librarymanagement._ import Keys._ import sbt.internal.librarymanagement.{ CoursierArtifactsTasks, CoursierInputsTasks } +import sbt.util.Logger +import sbt.io.syntax._ private[sbt] object LMCoursier { - def defaultCacheLocation: File = CoursierDependencyResolution.defaultCacheLocation + def defaultCacheLocation: File = + sys.props.get("sbt.coursier.home") match { + case Some(home) => new File(home).getAbsoluteFile / "cache" + case _ => CoursierDependencyResolution.defaultCacheLocation + } def coursierConfigurationTask( withClassifiers: Boolean, @@ -55,7 +61,7 @@ private[sbt] object LMCoursier { val createLogger = csrLogger.value - val cache = csrCachePath.value + val cache = csrCacheDirectory.value val internalSbtScalaProvider = appConfiguration.value.provider.scalaProvider val sbtBootJars = internalSbtScalaProvider.jars() @@ -89,35 +95,16 @@ private[sbt] object LMCoursier { } } - private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots" + def coursierLoggerTask: Def.Initialize[Task[Option[CacheLogger]]] = Def.task { + val st = Keys.streams.value + val progress = useSuperShell.value + if (progress) None + else Some(new CoursierLogger(st.log)) + } - def coursierSbtResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] = Def.task { - val resolvers = - sbt.Classpaths - .bootRepositories(appConfiguration.value) - .toSeq - .flatten ++ // required because of the hack above it seems - externalResolvers.in(updateSbtClassifiers).value - - val pluginIvySnapshotsFound = resolvers.exists { - case repo: URLRepository => - repo.patterns.artifactPatterns.headOption - .exists(_.startsWith(pluginIvySnapshotsBase)) - case _ => false - } - - val resolvers0 = - if (pluginIvySnapshotsFound && !resolvers.contains(Classpaths.sbtPluginReleases)) - resolvers :+ Classpaths.sbtPluginReleases - else - resolvers - val keepPreloaded = true // coursierKeepPreloaded.value - if (keepPreloaded) - resolvers0 - else - resolvers0.filter { r => - !r.name.startsWith("local-preloaded") - } + private[sbt] class CoursierLogger(logger: Logger) extends CacheLogger { + override def downloadedArtifact(url: String, success: Boolean): Unit = + logger.debug(s"downloaded $url") } def publicationsSetting(packageConfigs: Seq[(Configuration, CConfiguration)]): Def.Setting[_] = { diff --git a/main/src/main/scala/sbt/internal/librarymanagement/CoursierRepositoriesTasks.scala b/main/src/main/scala/sbt/internal/librarymanagement/CoursierRepositoriesTasks.scala index 17c2e037e..1e4994311 100644 --- a/main/src/main/scala/sbt/internal/librarymanagement/CoursierRepositoriesTasks.scala +++ b/main/src/main/scala/sbt/internal/librarymanagement/CoursierRepositoriesTasks.scala @@ -74,6 +74,10 @@ private[sbt] object CoursierRepositoriesTasks { } } + // local-preloaded-ivy contains dangling ivy.xml without JAR files + // https://github.com/sbt/sbt/issues/4661 + private final val keepPreloaded = false // coursierKeepPreloaded.value + def coursierResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] = Def.taskDyn { @@ -83,9 +87,6 @@ private[sbt] object CoursierRepositoriesTasks { Def.task { val result0 = resultTask(bootResOpt, overrideFlag).value val reorderResolvers = true // coursierReorderResolvers.value - // local-preloaded-ivy contains dangling ivy.xml without JAR files - // https://github.com/sbt/sbt/issues/4661 - val keepPreloaded = false // coursierKeepPreloaded.value val paths = ivyPaths.value val result1 = @@ -120,6 +121,36 @@ private[sbt] object CoursierRepositoriesTasks { } } + private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots" + + def coursierSbtResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] = Def.task { + val resolvers = + sbt.Classpaths + .bootRepositories(appConfiguration.value) + .toSeq + .flatten ++ // required because of the hack above it seems + externalResolvers.in(updateSbtClassifiers).value + + val pluginIvySnapshotsFound = resolvers.exists { + case repo: URLRepository => + repo.patterns.artifactPatterns.headOption + .exists(_.startsWith(pluginIvySnapshotsBase)) + case _ => false + } + + val resolvers0 = + if (pluginIvySnapshotsFound && !resolvers.contains(Classpaths.sbtPluginReleases)) + resolvers :+ Classpaths.sbtPluginReleases + else + resolvers + if (keepPreloaded) + resolvers0 + else + resolvers0.filter { r => + !r.name.startsWith("local-preloaded") + } + } + def coursierRecursiveResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] = Def.taskDyn { val s = state.value