From 3eb210eb1b2fa49ea6b75f8a8cbf6269d4e188db Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Mon, 18 Feb 2019 11:30:23 +0100 Subject: [PATCH] Less flaky handling of special project org.scala-sbt:global-plugins --- .../CoursierDependencyResolution.scala | 13 +-- .../lmcoursier/ResolutionParams.scala | 20 ---- .../sbtcoursiershared/InputsTasks.scala | 107 +++++++++++++++++- .../sbtcoursier/ResolutionTasks.scala | 13 +-- 4 files changed, 106 insertions(+), 47 deletions(-) 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 15d71812d..e656f3464 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala @@ -106,19 +106,8 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen } .map(withAuthenticationByHost(_, conf.authenticationByHost.toMap)) - val globalPluginsRepos = - for (p <- ResolutionParams.globalPluginPatterns(sbtBinaryVersion)) - yield IvyRepository.fromPattern( - p, - withChecksums = false, - withSignatures = false, - withArtifacts = false - ) - val interProjectRepo = InterProjectRepository(conf.interProjectDependencies) - val internalRepositories = globalPluginsRepos :+ interProjectRepo - val dependencies = module0 .dependencies .flatMap { d => @@ -148,7 +137,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen mainRepositories = mainRepositories, parentProjectCache = Map.empty, interProjectDependencies = conf.interProjectDependencies, - internalRepositories = internalRepositories, + internalRepositories = Seq(interProjectRepo), typelevel = typelevel, sbtClassifiers = false, projectName = projectName, 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 e561b5ea4..c30fd0883 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala +++ b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala @@ -150,26 +150,6 @@ object ResolutionParams { } } - def globalPluginPatterns(sbtVersion: String): Seq[coursier.ivy.Pattern] = { - - val defaultRawPattern = s"$${sbt.global.base.uri-$${user.home.uri}/.sbt/$sbtVersion}/plugins/target" + - "/resolution-cache/" + - "[organization]/[module](/scala_[scalaVersion])(/sbt_[sbtVersion])/[revision]/resolved.xml.[ext]" - - // seems to be required in more recent versions of sbt (since 0.13.16?) - val extraRawPattern = s"$${sbt.global.base.uri-$${user.home.uri}/.sbt/$sbtVersion}/plugins/target" + - "(/scala-[scalaVersion])(/sbt-[sbtVersion])" + - "/resolution-cache/" + - "[organization]/[module](/scala_[scalaVersion])(/sbt_[sbtVersion])/[revision]/resolved.xml.[ext]" - - val p = exceptionPatternParser() - - Seq( - defaultRawPattern, - extraRawPattern - ).map(p) - } - private val slowReposBase = Seq( "https://repo.typesafe.com/", "https://repo.scala-sbt.org/", diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala index 7ec1c37d5..9d0e2def8 100644 --- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala +++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala @@ -7,6 +7,8 @@ import coursier.sbtcoursiershared.Structure._ import sbt.Def import sbt.Keys._ +import scala.collection.JavaConverters._ + object InputsTasks { def coursierProjectTask: Def.Initialize[sbt.Task[Project]] = @@ -31,17 +33,116 @@ object InputsTasks { } } + private def moduleFromIvy(id: org.apache.ivy.core.module.id.ModuleRevisionId): Module = + Module( + Organization(id.getOrganisation), + ModuleName(id.getName), + id.getExtraAttributes + .asScala + .map { + case (k0, v0) => k0.asInstanceOf[String] -> v0.asInstanceOf[String] + } + .toMap + ) + + private def dependencyFromIvy(desc: org.apache.ivy.core.module.descriptor.DependencyDescriptor): Seq[(Configuration, Dependency)] = { + + val id = desc.getDependencyRevisionId + val module = moduleFromIvy(id) + val exclusions = desc + .getAllExcludeRules + .map { rule => + // we're ignoring rule.getConfigurations and rule.getMatcher here + val modId = rule.getId.getModuleId + // we're ignoring modId.getAttributes here + (Organization(modId.getOrganisation), ModuleName(modId.getName)) + } + .toSet + + val configurations = desc + .getModuleConfigurations + .toVector + .flatMap(s => coursier.ivy.IvyXml.mappings(s)) + + def dependency(conf: Configuration, attr: Attributes) = Dependency( + module, + id.getRevision, + conf, + exclusions, + attr, + optional = false, + desc.isTransitive + ) + + val attributes: Configuration => Attributes = { + + val artifacts = desc.getAllDependencyArtifacts + + val m = artifacts.toVector.flatMap { art => + val attr = Attributes(Type(art.getType), Classifier.empty) + art.getConfigurations.map(Configuration(_)).toVector.map { conf => + conf -> attr + } + }.toMap + + c => m.getOrElse(c, Attributes.empty) + } + + configurations.map { + case (from, to) => + from -> dependency(to, attributes(to)) + } + } + def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] = Def.taskDyn { val state = sbt.Keys.state.value val projectRef = sbt.Keys.thisProjectRef.value - val projects = Structure.allRecursiveInterDependencies(state, projectRef) + val projectRefs = Structure.allRecursiveInterDependencies(state, projectRef) - val t = coursierProject.forAllProjects(state, projects).map(_.values.toVector) + val t = coursierProject.forAllProjects(state, projectRefs).map(_.values.toVector) - Def.task(t.value) + Def.task { + val projects = t.value + val projectModules = projects.map(_.module).toSet + + // this includes org.scala-sbt:global-plugins referenced from meta-builds in particular + val extraProjects = sbt.Keys.projectDescriptors.value + .map { + case (k, v) => + moduleFromIvy(k) -> v + } + .filter { + case (module, _) => + !projectModules(module) + } + .toVector + .map { + case (module, v) => + val deps = v.getDependencies.flatMap(dependencyFromIvy) + Project( + module, + v.getModuleRevisionId.getRevision, + deps, + Map(), + None, + Nil, + Nil, + Nil, + None, + None, + None, + relocated = false, + None, + Nil, + Info.empty + ) + } + + projects ++ extraProjects + } } def coursierFallbackDependenciesTask: Def.Initialize[sbt.Task[Seq[FallbackDependency]]] = 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 adeefec11..dc4430097 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala @@ -78,15 +78,6 @@ object ResolutionTasks { val typelevel = Organization(scalaOrganization.value) == Typelevel.typelevelOrg - val globalPluginsRepos = - for (p <- ResolutionParams.globalPluginPatterns(sbtBinaryVersion.value)) - yield IvyRepository.fromPattern( - p, - withChecksums = false, - withSignatures = false, - withArtifacts = false - ) - val interProjectRepo = InterProjectRepository(interProjectDependencies) val ivyProperties = ResolutionParams.defaultIvyProperties() @@ -103,8 +94,6 @@ object ResolutionTasks { val authenticationByHost = authenticationByHostTask.value - val internalRepositories = globalPluginsRepos :+ interProjectRepo - val parentProjectCache: ProjectCache = coursierParentProjectCache.value .get(resolvers) .map(_.foldLeft[ProjectCache](Map.empty)(_ ++ _)) @@ -130,7 +119,7 @@ object ResolutionTasks { mainRepositories = mainRepositories, parentProjectCache = parentProjectCache, interProjectDependencies = interProjectDependencies, - internalRepositories = internalRepositories, + internalRepositories = Seq(interProjectRepo), typelevel = typelevel, sbtClassifiers = sbtClassifiers, projectName = projectName,