diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 0c11909b6..27c699e45 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -249,6 +249,7 @@ object Defaults extends BuildCommon { csrLogger := LMCoursier.coursierLoggerTask.value, csrCacheDirectory :== LMCoursier.defaultCacheLocation, csrMavenProfiles :== Set.empty, + csrReconciliations :== LMCoursier.relaxedForAllModules, ) /** Core non-plugin settings for sbt builds. These *must* be on every build or the sbt engine will fail to run at all. */ @@ -2457,6 +2458,7 @@ object Classpaths { csrRecursiveResolvers := CoursierRepositoriesTasks.coursierRecursiveResolversTask.value, csrSbtResolvers := CoursierRepositoriesTasks.coursierSbtResolversTask.value, csrInterProjectDependencies := CoursierInputsTasks.coursierInterProjectDependenciesTask.value, + csrExtraProjects := CoursierInputsTasks.coursierExtraProjectsTask.value, csrFallbackDependencies := CoursierInputsTasks.coursierFallbackDependenciesTask.value, ) ++ IvyXml.generateIvyXmlSettings() ++ diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 0632fd45f..438c551ae 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -10,7 +10,7 @@ package sbt import java.io.File import java.net.URL -import lmcoursier.definitions.CacheLogger +import lmcoursier.definitions.{ CacheLogger, ModuleMatchers, Reconciliation } import lmcoursier.{ CoursierConfiguration, FallbackDependency } import org.apache.ivy.core.module.descriptor.ModuleDescriptor import org.apache.ivy.core.module.id.ModuleRevisionId @@ -335,11 +335,13 @@ object Keys { val csrRecursiveResolvers = taskKey[Seq[Resolver]]("Resolvers of the current project, plus those of all from its inter-dependency projects") val csrSbtResolvers = taskKey[Seq[Resolver]]("Resolvers used for sbt artifacts.") val csrInterProjectDependencies = taskKey[Seq[lmcoursier.definitions.Project]]("Projects the current project depends on, possibly transitively") + val csrExtraProjects = taskKey[Seq[lmcoursier.definitions.Project]]("").withRank(CTask) val csrFallbackDependencies = taskKey[Seq[FallbackDependency]]("") val csrLogger = taskKey[Option[CacheLogger]]("") val csrExtraCredentials = taskKey[Seq[lmcoursier.credentials.Credentials]]("") val csrPublications = taskKey[Seq[(lmcoursier.definitions.Configuration, lmcoursier.definitions.Publication)]]("") - + val csrReconciliations = settingKey[Seq[(ModuleMatchers, Reconciliation)]]("Strategy to reconcile version conflicts.") + val internalConfigurationMap = settingKey[Configuration => Configuration]("Maps configurations to the actual configuration used to define the classpath.").withRank(CSetting) val classpathConfiguration = taskKey[Configuration]("The configuration used to define the classpath.").withRank(CTask) val ivyConfiguration = taskKey[IvyConfiguration]("General dependency management (Ivy) settings, such as the resolvers and paths to use.").withRank(DTask) diff --git a/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala b/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala index 655eff843..86172e0bb 100644 --- a/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala +++ b/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala @@ -13,15 +13,16 @@ import sbt.librarymanagement._ import sbt.util.Logger import sbt.Keys._ import lmcoursier.definitions.{ - Attributes => CAttributes, Classifier => CClassifier, Configuration => CConfiguration, Dependency => CDependency, + Extension => CExtension, Info => CInfo, Module => CModule, ModuleName => CModuleName, Organization => COrganization, Project => CProject, + Publication => CPublication, Type => CType } import lmcoursier.credentials.DirectCredentials @@ -108,81 +109,83 @@ object CoursierInputsTasks { val configurations = desc.getModuleConfigurations.toVector .flatMap(Inputs.ivyXmlMappings) - def dependency(conf: CConfiguration, attr: CAttributes) = CDependency( + def dependency(conf: CConfiguration, pub: CPublication) = CDependency( module, id.getRevision, conf, exclusions, - attr, + pub, optional = false, desc.isTransitive ) - val attributes: CConfiguration => CAttributes = { + val publications: CConfiguration => CPublication = { val artifacts = desc.getAllDependencyArtifacts val m = artifacts.toVector.flatMap { art => - val attr = CAttributes(CType(art.getType), CClassifier("")) + val pub = + CPublication(art.getName, CType(art.getType), CExtension(art.getExt()), CClassifier("")) art.getConfigurations.map(CConfiguration(_)).toVector.map { conf => - conf -> attr + conf -> pub } }.toMap - c => m.getOrElse(c, CAttributes(CType(""), CClassifier(""))) + c => m.getOrElse(c, CPublication("", CType(""), CExtension(""), CClassifier(""))) } configurations.map { case (from, to) => - from -> dependency(to, attributes(to)) + from -> dependency(to, publications(to)) } } private[sbt] def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[CProject]]] = Def.taskDyn { - val state = sbt.Keys.state.value val projectRef = sbt.Keys.thisProjectRef.value - val projectRefs = Project.transitiveInterDependencies(state, projectRef) - Def.task { - val projects = csrProject.all(ScopeFilter(inProjects(projectRefs: _*))).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 configurations = v.getConfigurations.map { c => - CConfiguration(c.getName) -> c.getExtends.map(CConfiguration(_)).toSeq - }.toMap - val deps = v.getDependencies.flatMap(dependencyFromIvy) - CProject( - module, - v.getModuleRevisionId.getRevision, - deps, - configurations, - Nil, - None, - Nil, - CInfo("", "", Nil, Nil, None) - ) - } - - projects ++ extraProjects + csrProject.all(ScopeFilter(inProjects(projectRefs :+ projectRef: _*))).value } } + private[sbt] def coursierExtraProjectsTask: Def.Initialize[sbt.Task[Seq[CProject]]] = { + Def.task { + val projects = csrInterProjectDependencies.value + val projectModules = projects.map(_.module).toSet + + // this includes org.scala-sbt:global-plugins referenced from meta-builds in particular + sbt.Keys.projectDescriptors.value + .map { + case (k, v) => + moduleFromIvy(k) -> v + } + .filter { + case (module, _) => + !projectModules(module) + } + .toVector + .map { + case (module, v) => + val configurations = v.getConfigurations.map { c => + CConfiguration(c.getName) -> c.getExtends.map(CConfiguration(_)).toSeq + }.toMap + val deps = v.getDependencies.flatMap(dependencyFromIvy) + CProject( + module, + v.getModuleRevisionId.getRevision, + deps, + configurations, + Nil, + None, + Nil, + CInfo("", "", Nil, Nil, None) + ) + } + } + } + private[sbt] def coursierFallbackDependenciesTask : Def.Initialize[sbt.Task[Seq[FallbackDependency]]] = Def.taskDyn { diff --git a/main/src/main/scala/sbt/coursierint/LMCoursier.scala b/main/src/main/scala/sbt/coursierint/LMCoursier.scala index a544d8f87..15bbe41e2 100644 --- a/main/src/main/scala/sbt/coursierint/LMCoursier.scala +++ b/main/src/main/scala/sbt/coursierint/LMCoursier.scala @@ -14,7 +14,9 @@ import lmcoursier.definitions.{ Classifier, Configuration => CConfiguration, CacheLogger, - Project => CProject + Project => CProject, + ModuleMatchers, + Reconciliation, } import lmcoursier._ import lmcoursier.credentials.Credentials @@ -40,9 +42,13 @@ object LMCoursier { case _ => CoursierDependencyResolution.defaultCacheLocation } + def relaxedForAllModules: Seq[(ModuleMatchers, Reconciliation)] = + Vector((ModuleMatchers.all, Reconciliation.Relaxed)) + def coursierConfiguration( rs: Seq[Resolver], interProjectDependencies: Seq[CProject], + extraProjects: Seq[CProject], fallbackDeps: Seq[FallbackDependency], appConfig: AppConfiguration, classifiers: Option[Seq[Classifier]], @@ -56,6 +62,7 @@ object LMCoursier { credentials: Seq[Credentials], createLogger: Option[CacheLogger], cacheDirectory: File, + reconciliation: Seq[(ModuleMatchers, Reconciliation)], log: Logger ): CoursierConfiguration = { val coursierExcludeDeps = Inputs @@ -82,6 +89,7 @@ object LMCoursier { CoursierConfiguration() .withResolvers(rs.toVector) .withInterProjectDependencies(interProjectDependencies.toVector) + .withExtraProjects(extraProjects.toVector) .withFallbackDependencies(fallbackDeps.toVector) .withExcludeDependencies(coursierExcludeDeps) .withAutoScalaLibrary(autoScala) @@ -96,6 +104,7 @@ object LMCoursier { .withCredentials(credentials) .withLogger(createLogger) .withCache(cacheDirectory) + .withReconciliation(reconciliation.toVector) .withLog(log) } @@ -103,6 +112,7 @@ object LMCoursier { coursierConfiguration( csrRecursiveResolvers.value, csrInterProjectDependencies.value.toVector, + csrExtraProjects.value.toVector, csrFallbackDependencies.value, appConfiguration.value, None, @@ -116,6 +126,7 @@ object LMCoursier { CoursierInputsTasks.credentialsTask.value, csrLogger.value, csrCacheDirectory.value, + csrReconciliations.value, streams.value.log ) } @@ -124,6 +135,7 @@ object LMCoursier { coursierConfiguration( csrRecursiveResolvers.value, csrInterProjectDependencies.value.toVector, + csrExtraProjects.value.toVector, csrFallbackDependencies.value, appConfiguration.value, Some(transitiveClassifiers.value.map(Classifier(_))), @@ -137,6 +149,7 @@ object LMCoursier { CoursierInputsTasks.credentialsTask.value, csrLogger.value, csrCacheDirectory.value, + csrReconciliations.value, streams.value.log ) } @@ -145,26 +158,6 @@ object LMCoursier { coursierConfiguration( csrSbtResolvers.value, Vector(), - csrFallbackDependencies.value, - appConfiguration.value, - None, - csrMavenProfiles.value, - scalaOrganization.value, - scalaVersion.value, - scalaBinaryVersion.value, - autoScalaLibrary.value, - scalaModuleInfo.value, - allExcludeDependencies.value, - CoursierInputsTasks.credentialsTask.value, - csrLogger.value, - csrCacheDirectory.value, - streams.value.log - ) - } - - def scalaCompilerBridgeConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task { - coursierConfiguration( - csrResolvers.value, Vector(), csrFallbackDependencies.value, appConfiguration.value, @@ -179,6 +172,30 @@ object LMCoursier { CoursierInputsTasks.credentialsTask.value, csrLogger.value, csrCacheDirectory.value, + csrReconciliations.value, + streams.value.log + ) + } + + def scalaCompilerBridgeConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task { + coursierConfiguration( + csrResolvers.value, + Vector(), + Vector(), + csrFallbackDependencies.value, + appConfiguration.value, + None, + csrMavenProfiles.value, + scalaOrganization.value, + scalaVersion.value, + scalaBinaryVersion.value, + autoScalaLibrary.value, + scalaModuleInfo.value, + allExcludeDependencies.value, + CoursierInputsTasks.credentialsTask.value, + csrLogger.value, + csrCacheDirectory.value, + csrReconciliations.value, streams.value.log ) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e0c1d97a1..8537b07e1 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -112,7 +112,7 @@ object Dependencies { def addSbtZincCompileCore(p: Project): Project = addSbtModule(p, sbtZincPath, "zincCompileCore", zincCompileCore) - val lmCoursierVersion = "2.0.0-RC2-1" + val lmCoursierVersion = "2.0.0-RC3-3" val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % lmCoursierVersion val sjsonNewScalaJson = Def.setting { diff --git a/sbt/src/sbt-test/dependency-management/conflict-coursier/build.sbt b/sbt/src/sbt-test/dependency-management/conflict-coursier/build.sbt new file mode 100644 index 000000000..4c49c2b30 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/conflict-coursier/build.sbt @@ -0,0 +1,5 @@ +ThisBuild / scalaVersion := "2.12.8" +libraryDependencies ++= List( + "org.webjars.npm" % "randomatic" % "1.1.7", + "org.webjars.npm" % "is-odd" % "2.0.0", +) diff --git a/sbt/src/sbt-test/dependency-management/conflict-coursier/test b/sbt/src/sbt-test/dependency-management/conflict-coursier/test new file mode 100644 index 000000000..103bd8d2f --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/conflict-coursier/test @@ -0,0 +1 @@ +> update