Merge pull request #4725 from eed3si9n/wip/bridge

scalaCompilerBridgeDependencyResolution
This commit is contained in:
eugene yokota 2019-05-25 11:39:06 -04:00 committed by GitHub
commit 07dec80a70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 292 additions and 159 deletions

View File

@ -546,6 +546,7 @@ object Defaults extends BuildCommon {
val zincDir = BuildPaths.getZincDirectory(st, g)
val app = appConfiguration.value
val launcher = app.provider.scalaProvider.launcher
val dr = scalaCompilerBridgeDependencyResolution.value
val scalac =
scalaCompilerBridgeBinaryJar.value match {
case Some(jar) =>
@ -561,7 +562,7 @@ object Defaults extends BuildCommon {
globalLock = launcher.globalLock,
componentProvider = app.provider.components,
secondaryCacheDir = Option(zincDir),
dependencyResolution = bootDependencyResolution.value,
dependencyResolution = dr,
compilerBridgeSource = scalaCompilerBridgeSource.value,
scalaJarsTarget = zincDir,
log = streams.value.log
@ -2391,7 +2392,7 @@ object Classpaths {
)
},
dependencyResolution := LibraryManagement.dependencyResolutionTask.value,
csrConfiguration := LMCoursier.coursierConfigurationTask(true, false).value,
csrConfiguration := LMCoursier.updateClassifierConfigurationTask.value,
updateClassifiers in TaskGlobal := (Def.task {
val s = streams.value
val is = ivySbt.value
@ -2430,7 +2431,7 @@ object Classpaths {
)
) ++ Seq(
csrProject := CoursierInputsTasks.coursierProjectTask.value,
csrConfiguration := LMCoursier.coursierConfigurationTask(false, false).value,
csrConfiguration := LMCoursier.coursierConfigurationTask.value,
csrResolvers := CoursierRepositoriesTasks.coursierResolversTask.value,
csrRecursiveResolvers := CoursierRepositoriesTasks.coursierRecursiveResolversTask.value,
csrSbtResolvers := CoursierRepositoriesTasks.coursierSbtResolversTask.value,
@ -2560,13 +2561,7 @@ object Classpaths {
.plugins
.pluginData
.resolvers
// https://github.com/sbt/sbt/issues/4408
(explicit, boot) match {
case (Some(ex), Some(b)) => (ex.toVector ++ b.toVector).distinct
case (Some(ex), None) => ex
case (None, Some(b)) => b
case _ => externalResolvers.value
}
explicit orElse boot getOrElse externalResolvers.value
},
ivyConfiguration := InlineIvyConfiguration(
lock = Option(lock(appConfiguration.value)),
@ -2599,7 +2594,7 @@ object Classpaths {
)
},
dependencyResolution := LibraryManagement.dependencyResolutionTask.value,
csrConfiguration := LMCoursier.coursierConfigurationTask(false, true).value,
csrConfiguration := LMCoursier.updateSbtClassifierConfigurationTask.value,
updateSbtClassifiers in TaskGlobal := (Def.task {
val lm = dependencyResolution.value
val s = streams.value
@ -2638,9 +2633,48 @@ object Classpaths {
}
} tag (Tags.Update, Tags.Network)).value
)
) ++
inTask(scalaCompilerBridgeScope)(
Seq(
dependencyResolution := LibraryManagement.dependencyResolutionTask.value,
csrConfiguration := LMCoursier.scalaCompilerBridgeConfigurationTask.value,
csrResolvers := CoursierRepositoriesTasks.coursierResolversTask.value,
externalResolvers := scalaCompilerBridgeResolvers.value,
ivyConfiguration := InlineIvyConfiguration(
lock = Option(lock(appConfiguration.value)),
log = Option(streams.value.log),
updateOptions = UpdateOptions(),
paths = Option(ivyPaths.value),
resolvers = scalaCompilerBridgeResolvers.value.toVector,
otherResolvers = Vector.empty,
moduleConfigurations = Vector.empty,
checksums = checksums.value.toVector,
managedChecksums = false,
resolutionCacheDir = Some(crossTarget.value / "bridge-resolution-cache"),
)
)
) ++ Seq(
bootIvyConfiguration := (updateSbtClassifiers / ivyConfiguration).value,
bootDependencyResolution := (updateSbtClassifiers / dependencyResolution).value
bootDependencyResolution := (updateSbtClassifiers / dependencyResolution).value,
scalaCompilerBridgeResolvers := {
val boot = bootResolvers.value
val explicit = buildStructure.value
.units(thisProjectRef.value.build)
.unit
.plugins
.pluginData
.resolvers
val ext = externalResolvers.value.toVector
// https://github.com/sbt/sbt/issues/4408
val xs = (explicit, boot) match {
case (Some(ex), Some(b)) => (ex.toVector ++ b.toVector).distinct
case (Some(ex), None) => ex.toVector
case (None, Some(b)) => b.toVector
case _ => Vector()
}
(xs ++ ext).distinct
},
scalaCompilerBridgeDependencyResolution := (scalaCompilerBridgeScope / dependencyResolution).value
)
def classifiersModuleTask: Initialize[Task[GetClassifiersModule]] =

View File

@ -183,6 +183,7 @@ object Keys {
val fileInputOptions = settingKey[Seq[String]]("Options that take file input, which may invalidate the cache.").withRank(CSetting)
val scalaCompilerBridgeBinaryJar = taskKey[Option[File]]("Optionally, the jar of the compiler bridge. When not None, this takes precedence over scalaCompilerBridgeSource").withRank(CSetting)
val scalaCompilerBridgeSource = settingKey[ModuleID]("Configures the module ID of the sources of the compiler bridge when scalaCompilerBridgeBinaryJar is None").withRank(CSetting)
val scalaCompilerBridgeScope = taskKey[Unit]("The compiler bridge scope.").withRank(DTask)
val scalaArtifacts = settingKey[Seq[String]]("Configures the list of artifacts which should match the Scala binary version").withRank(CSetting)
val enableBinaryCompileAnalysis = settingKey[Boolean]("Writes the analysis file in binary format")
val crossJavaVersions = settingKey[Seq[String]]("The java versions used during JDK cross testing").withRank(BPlusSetting)
@ -344,6 +345,7 @@ object Keys {
// This setting was created to work around the limitation of derived tasks not being able to use task-scoped task: ivyConfiguration in updateSbtClassifiers
val bootIvyConfiguration = taskKey[IvyConfiguration]("General dependency management (Ivy) settings, configured to retrieve sbt's components.").withRank(DTask)
val bootDependencyResolution = taskKey[DependencyResolution]("Dependency resolution to retrieve sbt's components.").withRank(CTask)
val scalaCompilerBridgeDependencyResolution = taskKey[DependencyResolution]("Dependency resolution to retrieve the compiler bridge.").withRank(CTask)
val moduleSettings = taskKey[ModuleSettings]("Module settings, which configure dependency management for a specific module, such as a project.").withRank(DTask)
val unmanagedBase = settingKey[File]("The default directory for manually managed libraries.").withRank(ASetting)
val updateConfiguration = settingKey[UpdateConfiguration]("Configuration for resolving and retrieving managed dependencies.").withRank(DSetting)
@ -403,6 +405,7 @@ object Keys {
val projectResolver = taskKey[Resolver]("Resolver that handles inter-project dependencies.").withRank(DTask)
val fullResolvers = taskKey[Seq[Resolver]]("Combines the project resolver, default resolvers, and user-defined resolvers.").withRank(CTask)
val otherResolvers = taskKey[Seq[Resolver]]("Resolvers not included in the main resolver chain, such as those in module configurations.").withRank(CSetting)
val scalaCompilerBridgeResolvers = taskKey[Seq[Resolver]]("Resolvers used to resolve compiler bridges.").withRank(CSetting)
val useJCenter = settingKey[Boolean]("Use JCenter as the default repository.").withRank(BSetting)
val moduleConfigurations = settingKey[Seq[ModuleConfiguration]]("Defines module configurations, which override resolvers on a per-module basis.").withRank(BMinusSetting)
val retrievePattern = settingKey[String]("Pattern used to retrieve managed dependencies to the current build.").withRank(DSetting)

View File

@ -17,10 +17,12 @@ import lmcoursier.definitions.{
}
import lmcoursier._
import sbt.librarymanagement._
import lmcoursier.credentials.Credentials
import Keys._
import sbt.internal.librarymanagement.{ CoursierArtifactsTasks, CoursierInputsTasks }
import sbt.util.Logger
import sbt.io.syntax._
import xsbti.AppConfiguration
private[sbt] object LMCoursier {
def defaultCacheLocation: File =
@ -29,81 +31,148 @@ private[sbt] object LMCoursier {
case _ => CoursierDependencyResolution.defaultCacheLocation
}
def coursierConfigurationTask(
withClassifiers: Boolean,
sbtClassifiers: Boolean
): Def.Initialize[Task[CoursierConfiguration]] =
Def.taskDyn {
val s = streams.value
val log = s.log
val resolversTask =
if (sbtClassifiers)
csrSbtResolvers
else
csrRecursiveResolvers
val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[Classifier]]]] =
if (withClassifiers && !sbtClassifiers)
Def.task(Some(sbt.Keys.transitiveClassifiers.value.map(Classifier(_))))
else
Def.task(None)
Def.task {
val rs = resolversTask.value
val scalaOrg = scalaOrganization.value
val scalaVer = scalaVersion.value
val interProjectDependencies0 = csrInterProjectDependencies.value.toVector
// during the resolution of sbt artifacts, such as compiler bridge source
// interproject dependencies should not be used (otherwise you can't compile sbt/zinc using sbt)
val interProjectDependencies: Vector[CProject] =
if (sbtClassifiers) Vector()
else interProjectDependencies0
val excludeDeps = Inputs.exclusions(
allExcludeDependencies.value,
scalaVer,
scalaBinaryVersion.value,
streams.value.log
)
val fallbackDeps = csrFallbackDependencies.value
val autoScalaLib = autoScalaLibrary.value && scalaModuleInfo.value.forall(
_.overrideScalaVersion
)
val profiles = csrMavenProfiles.value
val credentials = CoursierInputsTasks.credentialsTask.value
val createLogger = csrLogger.value
val cache = csrCacheDirectory.value
val internalSbtScalaProvider = appConfiguration.value.provider.scalaProvider
val sbtBootJars = internalSbtScalaProvider.jars()
val sbtScalaVersion = internalSbtScalaProvider.version()
val sbtScalaOrganization = "org.scala-lang" // always assuming sbt uses mainline scala
val classifiers = classifiersTask.value
Classpaths.warnResolversConflict(rs, log)
CoursierConfiguration()
.withResolvers(rs.toVector)
.withInterProjectDependencies(interProjectDependencies)
.withFallbackDependencies(fallbackDeps.toVector)
.withExcludeDependencies(
excludeDeps.toVector.map {
case (o, n) =>
(o.value, n.value)
}.sorted
)
.withAutoScalaLibrary(autoScalaLib)
.withSbtScalaJars(sbtBootJars.toVector)
.withSbtScalaVersion(sbtScalaVersion)
.withSbtScalaOrganization(sbtScalaOrganization)
.withClassifiers(classifiers.toVector.flatten.map(_.value))
.withHasClassifiers(classifiers.nonEmpty)
.withMavenProfiles(profiles.toVector.sorted)
.withScalaOrganization(scalaOrg)
.withScalaVersion(scalaVer)
.withCredentials(credentials)
.withLogger(createLogger)
.withCache(cache)
.withLog(log)
def coursierConfiguration(
rs: Seq[Resolver],
interProjectDependencies: Seq[CProject],
fallbackDeps: Seq[FallbackDependency],
appConfig: AppConfiguration,
classifiers: Option[Seq[Classifier]],
profiles: Set[String],
scalaOrg: String,
scalaVer: String,
scalaBinaryVer: String,
autoScalaLib: Boolean,
scalaModInfo: Option[ScalaModuleInfo],
excludeDeps: Seq[InclExclRule],
credentials: Seq[Credentials],
createLogger: Option[CacheLogger],
cacheDirectory: File,
log: Logger
): CoursierConfiguration = {
val coursierExcludeDeps = Inputs
.exclusions(
excludeDeps,
scalaVer,
scalaBinaryVer,
log
)
.toVector
.map {
case (o, n) =>
(o.value, n.value)
}
}
.sorted
val autoScala = autoScalaLib && scalaModInfo.forall(
_.overrideScalaVersion
)
val internalSbtScalaProvider = appConfig.provider.scalaProvider
val sbtBootJars = internalSbtScalaProvider.jars()
val sbtScalaVersion = internalSbtScalaProvider.version()
val sbtScalaOrganization = "org.scala-lang" // always assuming sbt uses mainline scala
Classpaths.warnResolversConflict(rs, log)
CoursierConfiguration()
.withResolvers(rs.toVector)
.withInterProjectDependencies(interProjectDependencies.toVector)
.withFallbackDependencies(fallbackDeps.toVector)
.withExcludeDependencies(coursierExcludeDeps)
.withAutoScalaLibrary(autoScala)
.withSbtScalaJars(sbtBootJars.toVector)
.withSbtScalaVersion(sbtScalaVersion)
.withSbtScalaOrganization(sbtScalaOrganization)
.withClassifiers(classifiers.toVector.flatten.map(_.value))
.withHasClassifiers(classifiers.nonEmpty)
.withMavenProfiles(profiles.toVector.sorted)
.withScalaOrganization(scalaOrg)
.withScalaVersion(scalaVer)
.withCredentials(credentials)
.withLogger(createLogger)
.withCache(cacheDirectory)
.withLog(log)
}
def coursierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
coursierConfiguration(
csrRecursiveResolvers.value,
csrInterProjectDependencies.value.toVector,
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 updateClassifierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
coursierConfiguration(
csrRecursiveResolvers.value,
csrInterProjectDependencies.value.toVector,
csrFallbackDependencies.value,
appConfiguration.value,
Some(transitiveClassifiers.value.map(Classifier(_))),
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 updateSbtClassifierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
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,
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 coursierLoggerTask: Def.Initialize[Task[Option[CacheLogger]]] = Def.task {
val st = Keys.streams.value

View File

@ -47,17 +47,18 @@ private[sbt] object LibraryManagement {
coursierOpt.orElse(notIvyOpt).getOrElse(true)
}
def dependencyResolutionTask: Def.Initialize[Task[DependencyResolution]] = Def.taskDyn {
if (Keys.useCoursier.value) {
Def.task { CoursierDependencyResolution(Keys.csrConfiguration.value) }
} else
Def.task {
IvyDependencyResolution(
Keys.ivyConfiguration.value,
CustomHttp.okhttpClient.value
)
}
}
def dependencyResolutionTask: Def.Initialize[Task[DependencyResolution]] =
Def.taskDyn {
if (Keys.useCoursier.value) {
Def.task { CoursierDependencyResolution(Keys.csrConfiguration.value) }
} else
Def.task {
IvyDependencyResolution(
Keys.ivyConfiguration.value,
CustomHttp.okhttpClient.value
)
}
}
def cachedUpdate(
lm: DependencyResolution,

View File

@ -53,73 +53,58 @@ private[sbt] object CoursierRepositoriesTasks {
resolvers
}
private def resultTask(
bootResOpt: Option[Seq[Resolver]],
overrideFlag: Boolean
): Def.Initialize[sbt.Task[Seq[Resolver]]] =
bootResOpt.filter(_ => overrideFlag) match {
case Some(r) => Def.task(r)
case None =>
Def.taskDyn {
val extRes = externalResolvers.value
val isSbtPlugin = sbtPlugin.value
if (isSbtPlugin)
Def.task {
Seq(
sbtResolver.value,
Classpaths.sbtPluginReleases
) ++ extRes
} else
Def.task(extRes)
}
}
// 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 {
val bootResOpt = bootResolvers.value
val overrideFlag = overrideBuildResolvers.value
Def.task {
val result0 = resultTask(bootResOpt, overrideFlag).value
val reorderResolvers = true // coursierReorderResolvers.value
val paths = ivyPaths.value
val result1 =
if (reorderResolvers) CResolvers.reorderResolvers(result0)
else result0
val result2 =
paths.ivyHome match {
case Some(ivyHome) =>
val ivyHomeUri = IO.toURI(ivyHome).getSchemeSpecificPart
result1 map {
case r: FileRepository =>
val ivyPatterns = r.patterns.ivyPatterns map {
_.replaceAllLiterally("$" + "{ivy.home}", ivyHomeUri)
}
val artifactPatterns = r.patterns.artifactPatterns map {
_.replaceAllLiterally("$" + "{ivy.home}", ivyHomeUri)
}
val p =
r.patterns.withIvyPatterns(ivyPatterns).withArtifactPatterns(artifactPatterns)
r.withPatterns(p)
case r => r
}
case _ => result1
}
if (keepPreloaded)
result2
else
result2.filter { r =>
!r.name.startsWith("local-preloaded")
}
}
def coursierResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] = Def.task {
val bootResOpt = bootResolvers.value
val overrideFlag = overrideBuildResolvers.value
val result0 = bootResOpt.filter(_ => overrideFlag) match {
case Some(r) => r
case None =>
val extRes = externalResolvers.value
val isSbtPlugin = sbtPlugin.value
if (isSbtPlugin)
Seq(
sbtResolver.value,
Classpaths.sbtPluginReleases
) ++ extRes
else extRes
}
val reorderResolvers = true // coursierReorderResolvers.value
val paths = ivyPaths.value
val result1 =
if (reorderResolvers) CResolvers.reorderResolvers(result0)
else result0
val result2 =
paths.ivyHome match {
case Some(ivyHome) =>
val ivyHomeUri = IO.toURI(ivyHome).getSchemeSpecificPart
result1 map {
case r: FileRepository =>
val ivyPatterns = r.patterns.ivyPatterns map {
_.replaceAllLiterally("$" + "{ivy.home}", ivyHomeUri)
}
val artifactPatterns = r.patterns.artifactPatterns map {
_.replaceAllLiterally("$" + "{ivy.home}", ivyHomeUri)
}
val p =
r.patterns.withIvyPatterns(ivyPatterns).withArtifactPatterns(artifactPatterns)
r.withPatterns(p)
case r => r
}
case _ => result1
}
if (keepPreloaded)
result2
else
result2.filter { r =>
!r.name.startsWith("local-preloaded")
}
}
private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots"

View File

@ -0,0 +1,5 @@
package example
object Hello extends App {
println("Hello!")
}

View File

@ -0,0 +1,12 @@
ThisBuild / scalaVersion := "2.12.8"
lazy val check = taskKey[Unit]("")
lazy val root = (project in file("."))
.settings(
name := "hello",
check := {
val rs = scalaCompilerBridgeResolvers.value
assert(rs.exists(r => r.name == "Triplequote Maven Releases"))
}
)

View File

@ -0,0 +1,23 @@
package sbtmyplugin
import sbt._
import sbt.Keys._
object HydraPlugin extends AutoPlugin {
override def requires: Plugins = plugins.JvmPlugin
override def trigger: PluginTrigger = allRequirements
override lazy val projectSettings = Seq(
resolvers += "Triplequote Maven Releases" at "https://repo.triplequote.com/artifactory/libs-release/",
) ++ inConfig(Compile)(compileSettings) ++ inConfig(Test)(compileSettings)
private lazy val compileSettings: Seq[Def.Setting[_]] = inTask(compile)(compileInputsSettings)
private def compileInputsSettings: Seq[Setting[_]] = Seq(
scalaCompilerBridgeSource := {
ModuleID("com.triplequote", "hydra-bridge_1_0", "2.1.4")
.withConfigurations(Some(Configurations.Compile.name))
.sources()
}
)
}

View File

@ -0,0 +1 @@
> check