mirror of https://github.com/sbt/sbt.git
Remove sbt-coursier, sbt-lm-coursier
This commit is contained in:
parent
7a325bc414
commit
4992ad868f
|
|
@ -1,60 +0,0 @@
|
|||
package coursier
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
import java.util.Properties
|
||||
|
||||
import lmcoursier.definitions.Authentication
|
||||
|
||||
// actually deprecated (all public ways of creating that are)
|
||||
sealed abstract class Credentials extends Product with Serializable {
|
||||
def user: String
|
||||
def password: String
|
||||
|
||||
def authentication: Authentication =
|
||||
Authentication(user, password)
|
||||
}
|
||||
|
||||
object Credentials {
|
||||
|
||||
private final case class Direct(user: String, password: String) extends Credentials {
|
||||
override def toString = s"Direct($user, ******)"
|
||||
}
|
||||
|
||||
private final case class FromFile(file: File) extends Credentials {
|
||||
|
||||
private lazy val props = {
|
||||
val p = new Properties()
|
||||
p.load(new FileInputStream(file))
|
||||
p
|
||||
}
|
||||
|
||||
private def findKey(keys: Seq[String]) = keys
|
||||
.iterator
|
||||
.map(props.getProperty)
|
||||
.filter(_ != null)
|
||||
.toStream
|
||||
.headOption
|
||||
.getOrElse {
|
||||
throw new NoSuchElementException(s"${keys.head} key in $file")
|
||||
}
|
||||
|
||||
lazy val user: String = findKey(FromFile.fileUserKeys)
|
||||
lazy val password: String = findKey(FromFile.filePasswordKeys)
|
||||
}
|
||||
|
||||
private object FromFile {
|
||||
// from sbt.Credentials
|
||||
private val fileUserKeys = Seq("user", "user.name", "username")
|
||||
private val filePasswordKeys = Seq("password", "pwd", "pass", "passwd")
|
||||
}
|
||||
|
||||
|
||||
@deprecated("Use coursierExtraCredentials rather than coursierCredentials", "1.1.0-M14")
|
||||
def apply(user: String, password: String): Credentials =
|
||||
Direct(user, password)
|
||||
|
||||
@deprecated("Use coursierExtraCredentials rather than coursierCredentials", "1.1.0-M14")
|
||||
def apply(file: File): Credentials =
|
||||
FromFile(file)
|
||||
|
||||
}
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import lmcoursier.definitions.{Classifier, Configuration, Extension, Publication, Type}
|
||||
import coursier.sbtcoursiershared.Structure._
|
||||
import sbt.librarymanagement.{Artifact => _, Configuration => _, _}
|
||||
import sbt.Def
|
||||
import sbt.Keys._
|
||||
|
||||
private[sbtcoursiershared] object ArtifactsTasks {
|
||||
|
||||
def coursierPublicationsTask(
|
||||
configsMap: (sbt.librarymanagement.Configuration, Configuration)*
|
||||
): Def.Initialize[sbt.Task[Seq[(Configuration, Publication)]]] =
|
||||
Def.task {
|
||||
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
val projId = sbt.Keys.projectID.value
|
||||
val sv = sbt.Keys.scalaVersion.value
|
||||
val sbv = sbt.Keys.scalaBinaryVersion.value
|
||||
val ivyConfs = sbt.Keys.ivyConfigurations.value
|
||||
|
||||
val sourcesConfigOpt =
|
||||
if (ivyConfigurations.value.exists(_.name == "sources"))
|
||||
Some(Configuration("sources"))
|
||||
else
|
||||
None
|
||||
|
||||
val docsConfigOpt =
|
||||
if (ivyConfigurations.value.exists(_.name == "docs"))
|
||||
Some(Configuration("docs"))
|
||||
else
|
||||
None
|
||||
|
||||
val sbtBinArtifacts =
|
||||
for ((config, targetConfig) <- configsMap) yield {
|
||||
|
||||
val publish = publishArtifact
|
||||
.in(projectRef)
|
||||
.in(packageBin)
|
||||
.in(config)
|
||||
.getOrElse(state, false)
|
||||
|
||||
if (publish)
|
||||
artifact
|
||||
.in(projectRef)
|
||||
.in(packageBin)
|
||||
.in(config)
|
||||
.find(state)
|
||||
.map(targetConfig -> _)
|
||||
else
|
||||
None
|
||||
}
|
||||
|
||||
val sbtSourceArtifacts =
|
||||
for ((config, targetConfig) <- configsMap) yield {
|
||||
|
||||
val publish = publishArtifact
|
||||
.in(projectRef)
|
||||
.in(packageSrc)
|
||||
.in(config)
|
||||
.getOrElse(state, false)
|
||||
|
||||
if (publish)
|
||||
artifact
|
||||
.in(projectRef)
|
||||
.in(packageSrc)
|
||||
.in(config)
|
||||
.find(state)
|
||||
.map(sourcesConfigOpt.getOrElse(targetConfig) -> _)
|
||||
else
|
||||
None
|
||||
}
|
||||
|
||||
val sbtDocArtifacts =
|
||||
for ((config, targetConfig) <- configsMap) yield {
|
||||
|
||||
val publish = publishArtifact
|
||||
.in(projectRef)
|
||||
.in(packageDoc)
|
||||
.in(config)
|
||||
.getOrElse(state, false)
|
||||
|
||||
if (publish)
|
||||
artifact
|
||||
.in(projectRef)
|
||||
.in(packageDoc)
|
||||
.in(config)
|
||||
.find(state)
|
||||
.map(docsConfigOpt.getOrElse(targetConfig) -> _)
|
||||
else
|
||||
None
|
||||
}
|
||||
|
||||
val sbtArtifacts = sbtBinArtifacts ++ sbtSourceArtifacts ++ sbtDocArtifacts
|
||||
|
||||
def artifactPublication(artifact: sbt.Artifact) = {
|
||||
|
||||
val name = CrossVersion(projId.crossVersion, sv, sbv)
|
||||
.fold(artifact.name)(_(artifact.name))
|
||||
|
||||
Publication(
|
||||
name,
|
||||
Type(artifact.`type`),
|
||||
Extension(artifact.extension),
|
||||
artifact.classifier.fold(Classifier(""))(Classifier(_))
|
||||
)
|
||||
}
|
||||
|
||||
val sbtArtifactsPublication = sbtArtifacts.collect {
|
||||
case Some((config, artifact)) =>
|
||||
config -> artifactPublication(artifact)
|
||||
}
|
||||
|
||||
val stdArtifactsSet = sbtArtifacts.flatMap(_.map { case (_, a) => a }.toSeq).toSet
|
||||
|
||||
// Second-way of getting artifacts from SBT
|
||||
// No obvious way of getting the corresponding publishArtifact value for the ones
|
||||
// only here, it seems.
|
||||
val extraSbtArtifacts = sbt.Keys.artifacts.in(projectRef).getOrElse(state, Nil)
|
||||
.filterNot(stdArtifactsSet)
|
||||
|
||||
// Seems that SBT does that - if an artifact has no configs,
|
||||
// it puts it in all of them. See for example what happens to
|
||||
// the standalone JAR artifact of the coursier cli module.
|
||||
def allConfigsIfEmpty(configs: Iterable[ConfigRef]): Iterable[ConfigRef] =
|
||||
if (configs.isEmpty) ivyConfs.filter(_.isPublic).map(c => ConfigRef(c.name)) else configs
|
||||
|
||||
val extraSbtArtifactsPublication = for {
|
||||
artifact <- extraSbtArtifacts
|
||||
config <- allConfigsIfEmpty(artifact.configurations.map(x => ConfigRef(x.name)))
|
||||
// FIXME If some configurations from artifact.configurations are not public, they may leak here :\
|
||||
} yield Configuration(config.name) -> artifactPublication(artifact)
|
||||
|
||||
sbtArtifactsPublication ++ extraSbtArtifactsPublication
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import lmcoursier.definitions.{Attributes, Classifier, Configuration, Dependency, Extension, Info, Module, ModuleName, Organization, Project, Publication, Strict, Type}
|
||||
import lmcoursier.{FallbackDependency, FromSbt, Inputs}
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
|
||||
import coursier.sbtcoursiershared.Structure._
|
||||
import lmcoursier.credentials.DirectCredentials
|
||||
import sbt.{Def, SettingKey}
|
||||
import sbt.Keys._
|
||||
import sbt.librarymanagement.{ConflictManager, InclExclRule, ModuleID}
|
||||
import sbt.util.Logger
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.language.reflectiveCalls
|
||||
|
||||
object InputsTasks {
|
||||
|
||||
lazy val actualExcludeDependencies =
|
||||
try {
|
||||
sbt.Keys
|
||||
.asInstanceOf[{ def allExcludeDependencies: SettingKey[scala.Seq[InclExclRule]] }]
|
||||
.allExcludeDependencies
|
||||
} catch {
|
||||
case _: NoSuchMethodException =>
|
||||
excludeDependencies
|
||||
}
|
||||
|
||||
private def coursierProject0(
|
||||
projId: ModuleID,
|
||||
dependencies: Seq[ModuleID],
|
||||
configurations: Seq[sbt.librarymanagement.Configuration],
|
||||
sv: String,
|
||||
sbv: String,
|
||||
log: Logger
|
||||
): Project = {
|
||||
|
||||
val configMap = Inputs.configExtendsSeq(configurations).toMap
|
||||
|
||||
FromSbt.project(
|
||||
projId,
|
||||
dependencies,
|
||||
configMap,
|
||||
sv,
|
||||
sbv
|
||||
)
|
||||
}
|
||||
|
||||
private[sbtcoursiershared] def coursierProjectTask: Def.Initialize[sbt.Task[Project]] =
|
||||
Def.taskDyn {
|
||||
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
|
||||
val allDependenciesTask = allDependencies.in(projectRef).get(state)
|
||||
|
||||
Def.task {
|
||||
coursierProject0(
|
||||
projectID.in(projectRef).get(state),
|
||||
allDependenciesTask.value,
|
||||
// should projectID.configurations be used instead?
|
||||
ivyConfigurations.in(projectRef).get(state),
|
||||
scalaVersion.in(projectRef).get(state),
|
||||
scalaBinaryVersion.in(projectRef).get(state),
|
||||
state.log
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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(Inputs.ivyXmlMappings)
|
||||
|
||||
def dependency(conf: Configuration, pub: Publication) = Dependency(
|
||||
module,
|
||||
id.getRevision,
|
||||
conf,
|
||||
exclusions,
|
||||
pub,
|
||||
optional = false,
|
||||
desc.isTransitive
|
||||
)
|
||||
|
||||
val publications: Configuration => Publication = {
|
||||
|
||||
val artifacts = desc.getAllDependencyArtifacts
|
||||
|
||||
val m = artifacts.toVector.flatMap { art =>
|
||||
val pub = Publication(art.getName, Type(art.getType), Extension(art.getExt), Classifier(""))
|
||||
art.getConfigurations.map(Configuration(_)).toVector.map { conf =>
|
||||
conf -> pub
|
||||
}
|
||||
}.toMap
|
||||
|
||||
c => m.getOrElse(c, Publication("", Type(""), Extension(""), Classifier("")))
|
||||
}
|
||||
|
||||
configurations.map {
|
||||
case (from, to) =>
|
||||
from -> dependency(to, publications(to))
|
||||
}
|
||||
}
|
||||
|
||||
private[sbtcoursiershared] def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] =
|
||||
Def.taskDyn {
|
||||
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
|
||||
val projectRefs = Structure.allRecursiveInterDependencies(state, projectRef)
|
||||
|
||||
val t = coursierProject.forAllProjectsOpt(state, projectRefs :+ projectRef)
|
||||
|
||||
Def.task {
|
||||
t.value.toVector.flatMap {
|
||||
case (ref, None) =>
|
||||
if (ref.build != projectRef.build)
|
||||
state.log.warn(s"Cannot get coursier info for project under ${ref.build}, is sbt-coursier also added to it?")
|
||||
Nil
|
||||
case (_, Some(p)) =>
|
||||
Seq(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[sbtcoursiershared] def coursierExtraProjectsTask: Def.Initialize[sbt.Task[Seq[Project]]] =
|
||||
Def.task {
|
||||
val projects = coursierInterProjectDependencies.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 =>
|
||||
Configuration(c.getName) -> c.getExtends.map(Configuration(_)).toSeq
|
||||
}
|
||||
.toMap
|
||||
val deps = v.getDependencies.flatMap(dependencyFromIvy)
|
||||
Project(
|
||||
module,
|
||||
v.getModuleRevisionId.getRevision,
|
||||
deps,
|
||||
configurations,
|
||||
Nil,
|
||||
None,
|
||||
Nil,
|
||||
Info("", "", Nil, Nil, None)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private[sbtcoursiershared] def coursierFallbackDependenciesTask: Def.Initialize[sbt.Task[Seq[FallbackDependency]]] =
|
||||
Def.taskDyn {
|
||||
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
|
||||
val projects = allRecursiveInterDependencies(state, projectRef)
|
||||
|
||||
val allDependenciesTask = allDependencies
|
||||
.forAllProjects(state, projectRef +: projects)
|
||||
.map(_.values.toVector.flatten)
|
||||
|
||||
Def.task {
|
||||
val allDependencies = allDependenciesTask.value
|
||||
|
||||
FromSbt.fallbackDependencies(
|
||||
allDependencies,
|
||||
scalaVersion.in(projectRef).get(state),
|
||||
scalaBinaryVersion.in(projectRef).get(state)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val credentialsTask = Def.taskDyn {
|
||||
|
||||
val useSbtCredentials = coursierUseSbtCredentials.value
|
||||
|
||||
val fromSbt =
|
||||
if (useSbtCredentials)
|
||||
Def.task {
|
||||
val log = streams.value.log
|
||||
|
||||
sbt.Keys.credentials.value
|
||||
.flatMap {
|
||||
case dc: sbt.DirectCredentials => List(dc)
|
||||
case fc: sbt.FileCredentials =>
|
||||
sbt.Credentials.loadCredentials(fc.path) match {
|
||||
case Left(err) =>
|
||||
log.warn(s"$err, ignoring it")
|
||||
Nil
|
||||
case Right(dc) => List(dc)
|
||||
}
|
||||
}
|
||||
.map { c =>
|
||||
DirectCredentials()
|
||||
.withHost(c.host)
|
||||
.withUsername(c.userName)
|
||||
.withPassword(c.passwd)
|
||||
.withRealm(Some(c.realm).filter(_.nonEmpty))
|
||||
.withHttpsOnly(false)
|
||||
.withMatchHost(true)
|
||||
}
|
||||
}
|
||||
else
|
||||
Def.task(Seq.empty[DirectCredentials])
|
||||
|
||||
Def.task {
|
||||
fromSbt.value ++ coursierExtraCredentials.value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def strictTask = Def.task {
|
||||
val cm = conflictManager.value
|
||||
val log = streams.value.log
|
||||
|
||||
cm.name match {
|
||||
case ConflictManager.latestRevision.name =>
|
||||
None
|
||||
case ConflictManager.strict.name =>
|
||||
val strict = Strict()
|
||||
.withInclude(Set((cm.organization, cm.module)))
|
||||
Some(strict)
|
||||
case other =>
|
||||
log.warn(s"Unsupported conflict manager $other")
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.Files
|
||||
|
||||
import lmcoursier.{Inputs, IvyXml}
|
||||
import lmcoursier.definitions.{Configuration, Project}
|
||||
import org.apache.ivy.core.module.id.ModuleRevisionId
|
||||
import sbt.{Def, Setting, Task, TaskKey}
|
||||
import sbt.internal.librarymanagement.IvySbt
|
||||
import sbt.librarymanagement.{CrossVersion, PublishConfiguration}
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
object IvyXmlGeneration {
|
||||
|
||||
// These are required for publish to be fine, later on.
|
||||
private def writeFiles(
|
||||
currentProject: Project,
|
||||
exclusions: Seq[(String, String)],
|
||||
overrides: Seq[(String, String, String)],
|
||||
ivySbt: IvySbt,
|
||||
log: sbt.util.Logger
|
||||
): File = {
|
||||
|
||||
val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
|
||||
ivy.getResolutionCacheManager
|
||||
)
|
||||
|
||||
val ivyModule = ModuleRevisionId.newInstance(
|
||||
currentProject.module.organization.value,
|
||||
currentProject.module.name.value,
|
||||
currentProject.version,
|
||||
currentProject.module.attributes.asJava
|
||||
)
|
||||
|
||||
val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
|
||||
val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
|
||||
|
||||
val content0 = IvyXml(currentProject, exclusions, overrides)
|
||||
cacheIvyFile.getParentFile.mkdirs()
|
||||
log.info(s"Writing Ivy file $cacheIvyFile")
|
||||
Files.write(cacheIvyFile.toPath, content0.getBytes(UTF_8))
|
||||
|
||||
// Just writing an empty file here... Are these only used?
|
||||
cacheIvyPropertiesFile.getParentFile.mkdirs()
|
||||
Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray)
|
||||
|
||||
cacheIvyFile
|
||||
}
|
||||
|
||||
def writeIvyXml: Def.Initialize[Task[File]] =
|
||||
Def.task {
|
||||
import SbtCoursierShared.autoImport._
|
||||
|
||||
val sv = sbt.Keys.scalaVersion.value
|
||||
val sbv = sbt.Keys.scalaBinaryVersion.value
|
||||
val log = sbt.Keys.streams.value.log
|
||||
val currentProject = {
|
||||
val proj = coursierProject.value
|
||||
val publications = coursierPublications.value
|
||||
proj.withPublications(publications)
|
||||
}
|
||||
val overrides = Inputs.forceVersions(sbt.Keys.dependencyOverrides.value, sv, sbv).map {
|
||||
case (mod, ver) =>
|
||||
(mod.organization.value, mod.name.value, ver)
|
||||
}
|
||||
val excludeDeps = Inputs.exclusionsSeq(InputsTasks.actualExcludeDependencies.value, sv, sbv, log)
|
||||
.map {
|
||||
case (org, name) =>
|
||||
(org.value, name.value)
|
||||
}
|
||||
writeFiles(currentProject, excludeDeps, overrides, sbt.Keys.ivySbt.value, log)
|
||||
}
|
||||
|
||||
private def makeIvyXmlBefore[T](task: TaskKey[T]): Setting[Task[T]] =
|
||||
task := task.dependsOn {
|
||||
Def.taskDyn {
|
||||
import SbtCoursierShared.autoImport._
|
||||
val doGen = coursierGenerateIvyXml.value
|
||||
if (doGen)
|
||||
Def.task {
|
||||
coursierWriteIvyXml.value
|
||||
()
|
||||
}
|
||||
else
|
||||
Def.task(())
|
||||
}
|
||||
}.value
|
||||
|
||||
private lazy val needsIvyXmlLocal = Seq(sbt.Keys.publishLocalConfiguration) ++ getPubConf("makeIvyXmlLocalConfiguration")
|
||||
private lazy val needsIvyXml = Seq(sbt.Keys.publishConfiguration) ++ getPubConf("makeIvyXmlConfiguration")
|
||||
|
||||
private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
|
||||
try {
|
||||
val cls = sbt.Keys.getClass
|
||||
val m = cls.getMethod(method)
|
||||
val task = m.invoke(sbt.Keys).asInstanceOf[TaskKey[PublishConfiguration]]
|
||||
List(task)
|
||||
} catch {
|
||||
case _: Throwable => // FIXME Too wide
|
||||
Nil
|
||||
}
|
||||
|
||||
def generateIvyXmlSettings: Seq[Setting[_]] =
|
||||
(needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore)
|
||||
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import java.util.{Properties => JProperties}
|
||||
|
||||
object Properties {
|
||||
|
||||
private lazy val props = {
|
||||
val p = new JProperties
|
||||
try {
|
||||
p.load(
|
||||
getClass
|
||||
.getClassLoader
|
||||
.getResourceAsStream("coursier/sbtcoursier.properties")
|
||||
)
|
||||
}
|
||||
catch {
|
||||
case _: NullPointerException =>
|
||||
}
|
||||
p
|
||||
}
|
||||
|
||||
lazy val version = props.getProperty("version")
|
||||
lazy val commitHash = props.getProperty("commit-hash")
|
||||
|
||||
}
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
|
||||
import coursier.sbtcoursiershared.Structure._
|
||||
import sbt.{Classpaths, Def}
|
||||
import sbt.Keys._
|
||||
import sbt.librarymanagement.{Resolver, URLRepository}
|
||||
|
||||
private[sbtcoursiershared] object RepositoriesTasks {
|
||||
|
||||
private object Resolvers {
|
||||
|
||||
private val slowReposBase = Seq(
|
||||
"https://repo.typesafe.com/",
|
||||
"https://repo.scala-sbt.org/",
|
||||
"http://repo.typesafe.com/",
|
||||
"http://repo.scala-sbt.org/"
|
||||
)
|
||||
|
||||
private val fastReposBase = Seq(
|
||||
"http://repo1.maven.org/",
|
||||
"https://repo1.maven.org/"
|
||||
)
|
||||
|
||||
private def url(res: Resolver): Option[String] =
|
||||
res match {
|
||||
case m: sbt.librarymanagement.MavenRepository =>
|
||||
Some(m.root)
|
||||
case u: URLRepository =>
|
||||
u.patterns.artifactPatterns.headOption
|
||||
.orElse(u.patterns.ivyPatterns.headOption)
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
|
||||
private def fastRepo(res: Resolver): Boolean =
|
||||
url(res).exists(u => fastReposBase.exists(u.startsWith))
|
||||
|
||||
private def slowRepo(res: Resolver): Boolean =
|
||||
url(res).exists(u => slowReposBase.exists(u.startsWith))
|
||||
|
||||
def reorderResolvers(resolvers: Seq[Resolver]): Seq[Resolver] =
|
||||
if (resolvers.exists(fastRepo) && resolvers.exists(slowRepo)) {
|
||||
val (slow, other) = resolvers.partition(slowRepo)
|
||||
other ++ slow
|
||||
} else
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
def coursierResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] =
|
||||
Def.taskDyn {
|
||||
|
||||
val bootResOpt = bootResolvers.value
|
||||
val overrideFlag = overrideBuildResolvers.value
|
||||
|
||||
Def.task {
|
||||
val result = resultTask(bootResOpt, overrideFlag).value
|
||||
val reorderResolvers = coursierReorderResolvers.value
|
||||
val keepPreloaded = coursierKeepPreloaded.value
|
||||
|
||||
val result0 =
|
||||
if (reorderResolvers)
|
||||
Resolvers.reorderResolvers(result)
|
||||
else
|
||||
result
|
||||
|
||||
if (keepPreloaded)
|
||||
result0
|
||||
else
|
||||
result0.filter { r =>
|
||||
!r.name.startsWith("local-preloaded")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def coursierRecursiveResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] =
|
||||
Def.taskDyn {
|
||||
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
|
||||
val projects = allRecursiveInterDependencies(state, projectRef)
|
||||
|
||||
val t = coursierResolvers
|
||||
.forAllProjects(state, projectRef +: projects)
|
||||
.map(_.values.toVector.flatten)
|
||||
|
||||
Def.task(t.value)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import java.io.File
|
||||
|
||||
import coursier.{Credentials => LegacyCredentials}
|
||||
import lmcoursier.credentials.Credentials
|
||||
import lmcoursier.{CoursierDependencyResolution, FallbackDependency}
|
||||
import lmcoursier.definitions.{CacheLogger, Configuration, Project, Publication}
|
||||
import lmcoursier.internal.SbtCoursierCache
|
||||
import lmcoursier.syntax._
|
||||
import sbt.{AutoPlugin, Classpaths, Compile, Setting, TaskKey, Test, settingKey, taskKey}
|
||||
import sbt.Keys._
|
||||
import sbt.librarymanagement.DependencyBuilders.OrganizationArtifactName
|
||||
import sbt.librarymanagement.{ModuleID, Resolver, URLRepository}
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
object SbtCoursierShared extends AutoPlugin {
|
||||
|
||||
override def trigger = allRequirements
|
||||
|
||||
override def requires = sbt.plugins.JvmPlugin
|
||||
|
||||
object autoImport {
|
||||
val coursierGenerateIvyXml = settingKey[Boolean]("")
|
||||
val coursierWriteIvyXml = taskKey[File]("")
|
||||
val coursierProject = TaskKey[Project]("coursier-project")
|
||||
val coursierInterProjectDependencies = TaskKey[Seq[Project]]("coursier-inter-project-dependencies", "Projects the current project depends on, possibly transitively")
|
||||
val coursierExtraProjects = TaskKey[Seq[Project]]("coursier-extra-projects", "")
|
||||
val coursierPublications = TaskKey[Seq[(Configuration, Publication)]]("coursier-publications")
|
||||
|
||||
val coursierKeepPreloaded = settingKey[Boolean]("Whether to take into account sbt preloaded repositories or not")
|
||||
val coursierReorderResolvers = settingKey[Boolean](
|
||||
"Whether resolvers should be re-ordered so that typically slow ones are given a lower priority"
|
||||
)
|
||||
val coursierResolvers = taskKey[Seq[Resolver]]("")
|
||||
val coursierRecursiveResolvers = taskKey[Seq[Resolver]]("Resolvers of the current project, plus those of all from its inter-dependency projects")
|
||||
val coursierSbtResolvers = taskKey[Seq[Resolver]]("")
|
||||
|
||||
val coursierFallbackDependencies = taskKey[Seq[FallbackDependency]]("")
|
||||
|
||||
val mavenProfiles = settingKey[Set[String]]("")
|
||||
val versionReconciliation = taskKey[Seq[ModuleID]]("")
|
||||
|
||||
private[coursier] val actualCoursierCredentials = TaskKey[Map[String, LegacyCredentials]]("coursierCredentials", "")
|
||||
|
||||
val coursierUseSbtCredentials = settingKey[Boolean]("")
|
||||
@deprecated("Use coursierExtraCredentials rather than coursierCredentials", "1.1.0-M14")
|
||||
val coursierCredentials = actualCoursierCredentials
|
||||
val coursierExtraCredentials = taskKey[Seq[Credentials]]("")
|
||||
|
||||
val coursierLogger = taskKey[Option[CacheLogger]]("")
|
||||
|
||||
val coursierCache = settingKey[File]("")
|
||||
|
||||
val sbtCoursierVersion = Properties.version
|
||||
|
||||
val coursierRetry = taskKey[Option[(FiniteDuration, Int)]]("Retry for downloading dependencies")
|
||||
}
|
||||
|
||||
import autoImport._
|
||||
|
||||
def publicationsSetting(packageConfigs: Seq[(sbt.Configuration, Configuration)]): Setting[_] =
|
||||
coursierPublications := ArtifactsTasks.coursierPublicationsTask(packageConfigs: _*).value
|
||||
|
||||
override def globalSettings: Seq[Setting[_]] =
|
||||
Seq(
|
||||
coursierUseSbtCredentials := true,
|
||||
actualCoursierCredentials := Map.empty,
|
||||
coursierExtraCredentials := Nil
|
||||
)
|
||||
|
||||
override def buildSettings: Seq[Setting[_]] =
|
||||
Seq(
|
||||
coursierReorderResolvers := true,
|
||||
coursierKeepPreloaded := false,
|
||||
coursierLogger := None,
|
||||
coursierCache := CoursierDependencyResolution.defaultCacheLocation,
|
||||
coursierRetry := None
|
||||
)
|
||||
|
||||
private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots"
|
||||
|
||||
override def projectSettings = settings(pubSettings = true)
|
||||
|
||||
def settings(pubSettings: Boolean) =
|
||||
Seq[Setting[_]](
|
||||
clean := {
|
||||
val noWarningPlz = clean.value
|
||||
SbtCoursierCache.default.clear()
|
||||
},
|
||||
onUnload := {
|
||||
SbtCoursierCache.default.clear()
|
||||
onUnload.value
|
||||
},
|
||||
coursierGenerateIvyXml := true,
|
||||
coursierWriteIvyXml := IvyXmlGeneration.writeIvyXml.value,
|
||||
coursierProject := InputsTasks.coursierProjectTask.value,
|
||||
coursierInterProjectDependencies := InputsTasks.coursierInterProjectDependenciesTask.value,
|
||||
coursierExtraProjects := InputsTasks.coursierExtraProjectsTask.value
|
||||
) ++ {
|
||||
if (pubSettings)
|
||||
Seq(
|
||||
publicationsSetting(Seq(Compile, Test).map(c => c -> Configuration(c.name)))
|
||||
)
|
||||
else
|
||||
Nil
|
||||
} ++ Seq(
|
||||
// Tests artifacts from Maven repositories are given this type.
|
||||
// Adding it here so that these work straightaway.
|
||||
classpathTypes += "test-jar", // FIXME Should this go in buildSettings?
|
||||
coursierResolvers := RepositoriesTasks.coursierResolversTask.value,
|
||||
coursierRecursiveResolvers := RepositoriesTasks.coursierRecursiveResolversTask.value,
|
||||
coursierSbtResolvers := {
|
||||
|
||||
// TODO Add docker-based integration test for that, see https://github.com/coursier/coursier/issues/632
|
||||
|
||||
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 (SbtCoursierShared.autoImport.coursierKeepPreloaded.value)
|
||||
resolvers0
|
||||
else
|
||||
resolvers0.filter { r =>
|
||||
!r.name.startsWith("local-preloaded")
|
||||
}
|
||||
},
|
||||
coursierFallbackDependencies := InputsTasks.coursierFallbackDependenciesTask.value,
|
||||
ivyConfigurations := {
|
||||
val confs = ivyConfigurations.value
|
||||
val names = confs.map(_.name).toSet
|
||||
|
||||
// Yes, adding those back in sbt 1.0. Can't distinguish between config test (whose jars with classifier tests ought to
|
||||
// be added), and sources / docs else (if their JARs are in compile, they would get added too then).
|
||||
|
||||
val extraSources =
|
||||
if (names("sources"))
|
||||
None
|
||||
else
|
||||
Some(
|
||||
sbt.Configuration.of(
|
||||
id = "Sources",
|
||||
name = "sources",
|
||||
description = "",
|
||||
isPublic = true,
|
||||
extendsConfigs = Vector.empty,
|
||||
transitive = false
|
||||
)
|
||||
)
|
||||
|
||||
val extraDocs =
|
||||
if (names("docs"))
|
||||
None
|
||||
else
|
||||
Some(
|
||||
sbt.Configuration.of(
|
||||
id = "Docs",
|
||||
name = "docs",
|
||||
description = "",
|
||||
isPublic = true,
|
||||
extendsConfigs = Vector.empty,
|
||||
transitive = false
|
||||
)
|
||||
)
|
||||
|
||||
confs ++ extraSources.toSeq ++ extraDocs.toSeq
|
||||
},
|
||||
mavenProfiles := Set.empty,
|
||||
versionReconciliation := Seq.empty,
|
||||
coursierRetry := None
|
||||
) ++ {
|
||||
if (pubSettings)
|
||||
IvyXmlGeneration.generateIvyXmlSettings
|
||||
else
|
||||
Nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
package coursier.sbtcoursiershared
|
||||
|
||||
import sbt._
|
||||
|
||||
object Structure {
|
||||
|
||||
def allRecursiveInterDependencies(state: sbt.State, projectRef: sbt.ProjectRef) = {
|
||||
|
||||
def dependencies(map: Map[String, Seq[String]], id: String): Set[String] = {
|
||||
|
||||
def helper(map: Map[String, Seq[String]], acc: Set[String]): Set[String] =
|
||||
if (acc.exists(map.contains)) {
|
||||
val (kept, rem) = map.partition { case (k, _) => acc(k) }
|
||||
helper(rem, acc ++ kept.valuesIterator.flatten)
|
||||
} else
|
||||
acc
|
||||
|
||||
helper(map - id, map.getOrElse(id, Nil).toSet)
|
||||
}
|
||||
|
||||
val allProjectsDeps =
|
||||
for (p <- structure(state).allProjects)
|
||||
yield p.id -> p.dependencies.map(_.project.project)
|
||||
|
||||
val deps = dependencies(allProjectsDeps.toMap, projectRef.project)
|
||||
|
||||
structure(state).allProjectRefs.filter(p => deps(p.project))
|
||||
}
|
||||
|
||||
// vv things from sbt-structure vv
|
||||
|
||||
def structure(state: State) =
|
||||
sbt.Project.structure(state)
|
||||
|
||||
implicit class `enrich SettingKey`[T](key: SettingKey[T]) {
|
||||
def find(state: State): Option[T] =
|
||||
key.get(structure(state).data)
|
||||
|
||||
def get(state: State): T =
|
||||
find(state).get
|
||||
|
||||
def getOrElse(state: State, default: => T): T =
|
||||
find(state).getOrElse(default)
|
||||
}
|
||||
|
||||
implicit class `enrich TaskKey`[T](key: TaskKey[T]) {
|
||||
def find(state: State): Option[sbt.Task[T]] =
|
||||
key.get(structure(state).data)
|
||||
|
||||
def get(state: State): sbt.Task[T] =
|
||||
find(state).get
|
||||
|
||||
def forAllProjects(state: State, projects: Seq[ProjectRef]): sbt.Task[Map[ProjectRef, T]] = {
|
||||
val tasks = projects.flatMap(p => key.in(p).get(structure(state).data).map(_.map(it => (p, it))))
|
||||
std.TaskExtra.joinTasks(tasks).join.map(_.toMap)
|
||||
}
|
||||
|
||||
// ^^ things from sbt-structure ^^
|
||||
|
||||
def forAllProjectsOpt(state: State, projects: Seq[ProjectRef]): sbt.Task[Map[ProjectRef, Option[T]]] = {
|
||||
val settings = structure(state).data
|
||||
val tasks = projects.map { p =>
|
||||
val taskOpt = key.in(p).get(settings)
|
||||
taskOpt match {
|
||||
case None =>
|
||||
Def.task(p -> Option.empty[T]).evaluate(settings)
|
||||
case Some(t) =>
|
||||
t.map(p -> Option(_))
|
||||
}
|
||||
}
|
||||
std.TaskExtra.joinTasks(tasks).join.map(_.toMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import java.io.File
|
||||
|
||||
import coursier.cache.FileCache
|
||||
import coursier.core._
|
||||
import coursier.util.Artifact
|
||||
import lmcoursier.internal.{ArtifactsParams, ArtifactsRun}
|
||||
import coursier.sbtcoursier.Keys._
|
||||
import coursier.sbtcoursiershared.InputsTasks.credentialsTask
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport.{coursierCache, coursierLogger}
|
||||
import lmcoursier.definitions.ToCoursier
|
||||
import sbt.Def
|
||||
import sbt.Keys._
|
||||
|
||||
object ArtifactsTasks {
|
||||
|
||||
def artifactsTask(
|
||||
withClassifiers: Boolean,
|
||||
sbtClassifiers: Boolean = false,
|
||||
ignoreArtifactErrors: Boolean = false,
|
||||
includeSignatures: Boolean = false
|
||||
): Def.Initialize[sbt.Task[Map[Artifact, File]]] = {
|
||||
|
||||
val resTask: sbt.Def.Initialize[sbt.Task[Seq[Resolution]]] =
|
||||
if (withClassifiers && sbtClassifiers)
|
||||
Def.task(coursierSbtClassifiersResolutions.value.values.toVector)
|
||||
else
|
||||
Def.task(coursierResolutions.value.values.toVector)
|
||||
|
||||
val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[Classifier]]]] =
|
||||
if (withClassifiers) {
|
||||
if (sbtClassifiers)
|
||||
Def.task(Some(coursierSbtClassifiersModule.value.classifiers.map(Classifier(_))))
|
||||
else
|
||||
Def.task(Some(transitiveClassifiers.value.map(Classifier(_))))
|
||||
} else
|
||||
Def.task(None)
|
||||
|
||||
Def.task {
|
||||
|
||||
val projectName = thisProjectRef.value.project
|
||||
|
||||
val parallelDownloads = coursierParallelDownloads.value
|
||||
val artifactsChecksums = coursierArtifactsChecksums.value
|
||||
val cachePolicies = coursierCachePolicies.value
|
||||
val ttl = coursierTtl.value
|
||||
val cache = coursierCache.value
|
||||
val createLogger = coursierLogger.value.map(ToCoursier.cacheLogger)
|
||||
val credentials = credentialsTask.value.map(ToCoursier.credentials)
|
||||
|
||||
val log = streams.value.log
|
||||
|
||||
val verbosityLevel = coursierVerbosity.value
|
||||
|
||||
val classifiers = classifiersTask.value
|
||||
val res = resTask.value
|
||||
|
||||
val params = ArtifactsParams(
|
||||
classifiers = classifiers,
|
||||
resolutions = res,
|
||||
includeSignatures = includeSignatures,
|
||||
loggerOpt = createLogger,
|
||||
projectName = projectName,
|
||||
sbtClassifiers = sbtClassifiers,
|
||||
cache = FileCache()
|
||||
.withLocation(cache)
|
||||
.withChecksums(artifactsChecksums)
|
||||
.withTtl(ttl)
|
||||
.withCachePolicies(cachePolicies)
|
||||
.withCredentials(credentials)
|
||||
.withFollowHttpToHttpsRedirections(true),
|
||||
parallel = parallelDownloads,
|
||||
classpathOrder = true,
|
||||
missingOk = sbtClassifiers
|
||||
)
|
||||
|
||||
val resOrError = ArtifactsRun(
|
||||
params,
|
||||
verbosityLevel,
|
||||
log
|
||||
)
|
||||
|
||||
resOrError match {
|
||||
case Left(err) =>
|
||||
throw err
|
||||
case Right(res0) =>
|
||||
res0.artifacts.toMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import coursier.cache.CacheDefaults
|
||||
import coursier.core.{Configuration, ResolutionProcess}
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared
|
||||
import sbt.{Cache => _, Configuration => _, _}
|
||||
import sbt.Keys._
|
||||
|
||||
object CoursierPlugin extends AutoPlugin {
|
||||
|
||||
override def trigger = allRequirements
|
||||
|
||||
override def requires = SbtCoursierShared
|
||||
|
||||
import SbtCoursierShared.autoImport._
|
||||
|
||||
object autoImport {
|
||||
val coursierParallelDownloads = Keys.coursierParallelDownloads
|
||||
val coursierMaxIterations = Keys.coursierMaxIterations
|
||||
val coursierChecksums = Keys.coursierChecksums
|
||||
val coursierArtifactsChecksums = Keys.coursierArtifactsChecksums
|
||||
val coursierCachePolicies = Keys.coursierCachePolicies
|
||||
val coursierTtl = Keys.coursierTtl
|
||||
val coursierVerbosity = Keys.coursierVerbosity
|
||||
val coursierConfigGraphs = Keys.coursierConfigGraphs
|
||||
val coursierSbtClassifiersModule = Keys.coursierSbtClassifiersModule
|
||||
|
||||
val coursierConfigurations = Keys.coursierConfigurations
|
||||
|
||||
val coursierParentProjectCache = Keys.coursierParentProjectCache
|
||||
val coursierResolutions = Keys.coursierResolutions
|
||||
|
||||
val coursierSbtClassifiersResolutions = Keys.coursierSbtClassifiersResolutions
|
||||
|
||||
val coursierDependencyTree = Keys.coursierDependencyTree
|
||||
val coursierDependencyInverseTree = Keys.coursierDependencyInverseTree
|
||||
val coursierWhatDependsOn = Keys.coursierWhatDependsOn
|
||||
|
||||
val coursierArtifacts = Keys.coursierArtifacts
|
||||
val coursierSignedArtifacts = Keys.coursierSignedArtifacts
|
||||
val coursierClassifiersArtifacts = Keys.coursierClassifiersArtifacts
|
||||
val coursierSbtClassifiersArtifacts = Keys.coursierSbtClassifiersArtifacts
|
||||
|
||||
@deprecated("Use sbtCoursierVersion instead", "1.1.0-M9")
|
||||
val coursierVersion = sbtCoursierVersion
|
||||
|
||||
val addSbtCoursier: Seq[Def.Setting[_]] = {
|
||||
import sbt._
|
||||
Seq(
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % sbtCoursierVersion),
|
||||
// seems needed for some sbt plugins (https://github.com/coursier/coursier/issues/450)
|
||||
classpathTypes += "maven-plugin"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import autoImport._
|
||||
|
||||
lazy val treeSettings = Seq(
|
||||
coursierDependencyTree := DisplayTasks.coursierDependencyTreeTask(
|
||||
inverse = false
|
||||
).value,
|
||||
coursierDependencyInverseTree := DisplayTasks.coursierDependencyTreeTask(
|
||||
inverse = true
|
||||
).value,
|
||||
coursierWhatDependsOn := Def.inputTaskDyn {
|
||||
import sbt.complete.DefaultParsers._
|
||||
val input = token(SpaceClass ~ NotQuoted, "<arg>").parsed._2
|
||||
DisplayTasks.coursierWhatDependsOnTask(input)
|
||||
}.evaluated
|
||||
)
|
||||
|
||||
// allows to get the actual repo list when sbt starts up
|
||||
private val hackHack = Seq(
|
||||
// TODO Add docker-based non reg test for that, with sbt-assembly 0.14.5 in ~/.sbt/1.0/plugins/plugins.sbt
|
||||
// along with the required extra repo https://repository.jboss.org/nexus/content/repositories/public
|
||||
// (required for coursier, because of bad checksums on central)
|
||||
appConfiguration.in(updateSbtClassifiers) := {
|
||||
val app = appConfiguration.in(updateSbtClassifiers).value
|
||||
|
||||
// hack to trigger https://github.com/sbt/sbt/blob/v1.0.1/main/src/main/scala/sbt/Defaults.scala#L2856,
|
||||
// to have the third case be used instead of the second one, at https://github.com/sbt/sbt/blob/v1.0.1/main/src/main/scala/sbt/Defaults.scala#L2069
|
||||
new xsbti.AppConfiguration {
|
||||
def provider() = {
|
||||
import scala.language.reflectiveCalls
|
||||
val prov = app.provider()
|
||||
val noWarningForDeprecatedStuffProv = prov.asInstanceOf[{
|
||||
def mainClass(): Class[_ <: xsbti.AppMain]
|
||||
}]
|
||||
new xsbti.AppProvider {
|
||||
def newMain() = prov.newMain()
|
||||
def components() = prov.components()
|
||||
def mainClass() = noWarningForDeprecatedStuffProv.mainClass()
|
||||
def mainClasspath() = prov.mainClasspath()
|
||||
def loader() = prov.loader()
|
||||
def scalaProvider() = {
|
||||
val scalaProv = prov.scalaProvider()
|
||||
val noWarningForDeprecatedStuffScalaProv = scalaProv.asInstanceOf[{
|
||||
def libraryJar(): File
|
||||
def compilerJar(): File
|
||||
}]
|
||||
|
||||
new xsbti.ScalaProvider {
|
||||
def app(id: xsbti.ApplicationID) = scalaProv.app(id)
|
||||
def loader() = scalaProv.loader()
|
||||
def jars() = scalaProv.jars()
|
||||
def libraryJar() = noWarningForDeprecatedStuffScalaProv.libraryJar()
|
||||
def version() = scalaProv.version()
|
||||
def compilerJar() = noWarningForDeprecatedStuffScalaProv.compilerJar()
|
||||
def launcher() = {
|
||||
val launch = scalaProv.launcher()
|
||||
new xsbti.Launcher {
|
||||
def app(id: xsbti.ApplicationID, version: String) = launch.app(id, version)
|
||||
def checksums() = launch.checksums()
|
||||
def globalLock() = launch.globalLock()
|
||||
def bootDirectory() = launch.bootDirectory()
|
||||
def appRepositories() = launch.appRepositories()
|
||||
def topLoader() = launch.topLoader()
|
||||
def getScala(version: String) = launch.getScala(version)
|
||||
def getScala(version: String, reason: String) = launch.getScala(version, reason)
|
||||
def getScala(version: String, reason: String, scalaOrg: String) = launch.getScala(version, reason, scalaOrg)
|
||||
def isOverrideRepositories = launch.isOverrideRepositories
|
||||
def ivyRepositories() =
|
||||
throw new NoSuchMethodError("nope")
|
||||
def ivyHome() = launch.ivyHome()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
def entryPoint() = prov.entryPoint()
|
||||
def id() = prov.id()
|
||||
}
|
||||
}
|
||||
def arguments() = app.arguments()
|
||||
def baseDirectory() = app.baseDirectory()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def coursierSettings: Seq[Setting[_]] = hackHack ++ Seq(
|
||||
coursierArtifacts := ArtifactsTasks.artifactsTask(withClassifiers = false).value,
|
||||
coursierSignedArtifacts := ArtifactsTasks.artifactsTask(withClassifiers = false, includeSignatures = true).value,
|
||||
coursierClassifiersArtifacts := ArtifactsTasks.artifactsTask(
|
||||
withClassifiers = true
|
||||
).value,
|
||||
coursierSbtClassifiersArtifacts := ArtifactsTasks.artifactsTask(
|
||||
withClassifiers = true,
|
||||
sbtClassifiers = true
|
||||
).value,
|
||||
update := UpdateTasks.updateTask(withClassifiers = false).value,
|
||||
updateClassifiers := UpdateTasks.updateTask(withClassifiers = true).value,
|
||||
updateSbtClassifiers.in(Defaults.TaskGlobal) := UpdateTasks.updateTask(withClassifiers = true, sbtClassifiers = true).value,
|
||||
coursierConfigGraphs := InputsTasks.ivyGraphsTask.value,
|
||||
coursierSbtClassifiersModule := classifiersModule.in(updateSbtClassifiers).value,
|
||||
coursierConfigurations := InputsTasks.coursierConfigurationsTask.value,
|
||||
coursierParentProjectCache := InputsTasks.parentProjectCacheTask.value,
|
||||
coursierResolutions := (Def.taskDyn {
|
||||
val missingOk = updateConfiguration.value.missingOk
|
||||
ResolutionTasks.resolutionsTask(missingOk = missingOk)
|
||||
}).value,
|
||||
Keys.actualCoursierResolution := {
|
||||
|
||||
val config = Configuration(Compile.name)
|
||||
|
||||
coursierResolutions
|
||||
.value
|
||||
.getOrElse(
|
||||
config,
|
||||
sys.error(s"Resolution for configuration $config not found")
|
||||
)
|
||||
},
|
||||
coursierSbtClassifiersResolutions := (Def.taskDyn {
|
||||
val missingOk = (updateConfiguration in updateSbtClassifiers).value.missingOk
|
||||
ResolutionTasks.resolutionsTask(
|
||||
sbtClassifiers = true,
|
||||
missingOk = missingOk,
|
||||
)
|
||||
}).value
|
||||
)
|
||||
|
||||
override lazy val buildSettings = super.buildSettings ++ Seq(
|
||||
coursierParallelDownloads := 6,
|
||||
coursierMaxIterations := ResolutionProcess.defaultMaxIterations,
|
||||
coursierChecksums := Seq(Some("SHA-1"), None),
|
||||
coursierArtifactsChecksums := Seq(None),
|
||||
coursierCachePolicies := CacheDefaults.cachePolicies,
|
||||
coursierTtl := CacheDefaults.ttl,
|
||||
coursierVerbosity := Settings.defaultVerbosityLevel(sLog.value)
|
||||
)
|
||||
|
||||
override lazy val projectSettings = coursierSettings ++
|
||||
inConfig(Compile)(treeSettings) ++
|
||||
inConfig(Test)(treeSettings)
|
||||
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import coursier.core._
|
||||
import lmcoursier.definitions.ToCoursier
|
||||
import coursier.parse.ModuleParser
|
||||
import coursier.sbtcoursier.Keys._
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
|
||||
import coursier.util.Print
|
||||
import sbt.Def
|
||||
import sbt.Keys._
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object DisplayTasks {
|
||||
|
||||
private case class ResolutionResult(config: Configuration, resolution: Resolution, dependencies: Seq[Dependency])
|
||||
|
||||
private def coursierResolutionTask(
|
||||
sbtClassifiers: Boolean = false,
|
||||
ignoreArtifactErrors: Boolean = false
|
||||
): Def.Initialize[sbt.Task[Seq[ResolutionResult]]] = {
|
||||
|
||||
val currentProjectTask =
|
||||
if (sbtClassifiers)
|
||||
Def.task {
|
||||
val sv = scalaVersion.value
|
||||
val sbv = scalaBinaryVersion.value
|
||||
val cm = coursierSbtClassifiersModule.value
|
||||
SbtCoursierFromSbt.sbtClassifiersProject(cm, sv, sbv)
|
||||
}
|
||||
else
|
||||
Def.task {
|
||||
val proj = coursierProject.value
|
||||
val publications = coursierPublications.value
|
||||
proj.withPublications(publications)
|
||||
}
|
||||
|
||||
val resolutionsTask =
|
||||
if (sbtClassifiers)
|
||||
coursierSbtClassifiersResolutions
|
||||
else
|
||||
coursierResolutions
|
||||
|
||||
Def.task {
|
||||
|
||||
val currentProject = ToCoursier.project(currentProjectTask.value)
|
||||
|
||||
val config = Configuration(configuration.value.name)
|
||||
val configs = coursierConfigurations.value
|
||||
|
||||
val includedConfigs = configs.getOrElse(config, Set.empty) + config
|
||||
|
||||
val resolutions = resolutionsTask.value
|
||||
|
||||
for {
|
||||
(subGraphConfig, res) <- resolutions.toSeq
|
||||
if includedConfigs(subGraphConfig)
|
||||
} yield {
|
||||
|
||||
val dependencies0 = currentProject
|
||||
.dependencies
|
||||
.collect {
|
||||
case (`subGraphConfig`, dep) =>
|
||||
dep
|
||||
}
|
||||
.sortBy { dep =>
|
||||
(dep.module.organization, dep.module.name, dep.version)
|
||||
}
|
||||
|
||||
val subRes = res.subset(dependencies0)
|
||||
|
||||
ResolutionResult(subGraphConfig, subRes, dependencies0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def coursierDependencyTreeTask(
|
||||
inverse: Boolean,
|
||||
sbtClassifiers: Boolean = false,
|
||||
ignoreArtifactErrors: Boolean = false
|
||||
) = Def.task {
|
||||
val projectName = thisProjectRef.value.project
|
||||
|
||||
val resolutions = coursierResolutionTask(sbtClassifiers, ignoreArtifactErrors).value
|
||||
for (ResolutionResult(subGraphConfig, resolution, dependencies) <- resolutions) {
|
||||
streams.value.log.info(
|
||||
s"$projectName (configuration ${subGraphConfig.value})" + "\n" +
|
||||
Print.dependencyTree(
|
||||
resolution,
|
||||
dependencies,
|
||||
printExclusions = true,
|
||||
inverse,
|
||||
colors = !sys.props.get("sbt.log.noformat").toSeq.contains("true")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def coursierWhatDependsOnTask(
|
||||
moduleName: String,
|
||||
sbtClassifiers: Boolean = false,
|
||||
ignoreArtifactErrors: Boolean = false
|
||||
) = Def.task {
|
||||
val module = ModuleParser.module(moduleName, scalaVersion.value)
|
||||
.right
|
||||
.getOrElse(throw new RuntimeException(s"Could not parse module `$moduleName`"))
|
||||
|
||||
val projectName = thisProjectRef.value.project
|
||||
|
||||
val resolutions = coursierResolutionTask(sbtClassifiers, ignoreArtifactErrors).value
|
||||
val result = new mutable.StringBuilder
|
||||
for (ResolutionResult(subGraphConfig, resolution, _) <- resolutions) {
|
||||
val roots = resolution
|
||||
.minDependencies
|
||||
.filter(f => f.module == module)
|
||||
.toVector
|
||||
.sortBy(_.toString) // elements already have the same module, there's not much left for sorting…
|
||||
val strToPrint = s"$projectName (configurations ${subGraphConfig.value})" + "\n" +
|
||||
Print.dependencyTree(
|
||||
resolution,
|
||||
roots,
|
||||
printExclusions = true,
|
||||
reverse = true,
|
||||
colors = !sys.props.get("sbt.log.noformat").toSeq.contains("true")
|
||||
)
|
||||
streams.value.log.info(strToPrint)
|
||||
result.append(strToPrint)
|
||||
result.append("\n")
|
||||
}
|
||||
|
||||
result.toString
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import coursier.ProjectCache
|
||||
import coursier.core._
|
||||
import lmcoursier._
|
||||
import lmcoursier.definitions.ToCoursier
|
||||
import coursier.sbtcoursier.Keys._
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
|
||||
import coursier.sbtcoursiershared.Structure._
|
||||
import sbt.librarymanagement.{Configuration => _, _}
|
||||
import sbt.Def
|
||||
import sbt.Keys._
|
||||
|
||||
object InputsTasks {
|
||||
|
||||
def coursierConfigurationsTask: Def.Initialize[sbt.Task[Map[Configuration, Set[Configuration]]]] =
|
||||
Def.task {
|
||||
Inputs.coursierConfigurationsMap(ivyConfigurations.value).map {
|
||||
case (k, v) =>
|
||||
ToCoursier.configuration(k) -> v.map(ToCoursier.configuration)
|
||||
}
|
||||
}
|
||||
|
||||
def ivyGraphsTask: Def.Initialize[sbt.Task[Seq[(Configuration, Seq[Configuration])]]] =
|
||||
Def.task {
|
||||
val p = coursierProject.value
|
||||
Inputs.orderedConfigurations(p.configurations.toSeq).map {
|
||||
case (config, extends0) =>
|
||||
(ToCoursier.configuration(config), extends0.map(ToCoursier.configuration))
|
||||
}
|
||||
}
|
||||
|
||||
def parentProjectCacheTask: Def.Initialize[sbt.Task[Map[Seq[sbt.librarymanagement.Resolver], Seq[coursier.ProjectCache]]]] =
|
||||
Def.taskDyn {
|
||||
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
|
||||
val projectDeps = structure(state).allProjects
|
||||
.find(_.id == projectRef.project)
|
||||
.map(_.dependencies.map(_.project.project).toSet)
|
||||
.getOrElse(Set.empty)
|
||||
|
||||
val projects = structure(state).allProjectRefs.filter(p => projectDeps(p.project))
|
||||
|
||||
val t =
|
||||
for {
|
||||
m <- coursierRecursiveResolvers.forAllProjects(state, projects)
|
||||
n <- coursierResolutions.forAllProjects(state, m.keys.toSeq)
|
||||
} yield
|
||||
n.foldLeft(Map.empty[Seq[Resolver], Seq[ProjectCache]]) {
|
||||
case (caches, (ref, resolutions)) =>
|
||||
val mainResOpt = resolutions.collectFirst {
|
||||
case (Configuration.compile, v) => v
|
||||
}
|
||||
|
||||
val r = for {
|
||||
resolvers <- m.get(ref)
|
||||
resolution <- mainResOpt
|
||||
} yield
|
||||
caches.updated(resolvers, resolution.projectCache +: caches.getOrElse(resolvers, Seq.empty))
|
||||
|
||||
r.getOrElse(caches)
|
||||
}
|
||||
|
||||
Def.task(t.value)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import java.io.File
|
||||
|
||||
import coursier.cache.CachePolicy
|
||||
import coursier.ProjectCache
|
||||
import coursier.core._
|
||||
import coursier.util.Artifact
|
||||
import sbt.librarymanagement.{GetClassifiersModule, Resolver}
|
||||
import sbt.{InputKey, SettingKey, TaskKey}
|
||||
|
||||
import scala.concurrent.duration.{Duration, FiniteDuration}
|
||||
|
||||
object Keys {
|
||||
val coursierParallelDownloads = SettingKey[Int]("coursier-parallel-downloads")
|
||||
val coursierMaxIterations = SettingKey[Int]("coursier-max-iterations")
|
||||
val coursierChecksums = SettingKey[Seq[Option[String]]]("coursier-checksums")
|
||||
val coursierArtifactsChecksums = SettingKey[Seq[Option[String]]]("coursier-artifacts-checksums")
|
||||
val coursierCachePolicies = SettingKey[Seq[CachePolicy]]("coursier-cache-policies")
|
||||
val coursierTtl = SettingKey[Option[Duration]]("coursier-ttl")
|
||||
|
||||
val coursierVerbosity = SettingKey[Int]("coursier-verbosity")
|
||||
|
||||
val coursierConfigGraphs = TaskKey[Seq[(Configuration, Seq[Configuration])]]("coursier-config-graphs")
|
||||
|
||||
val coursierSbtClassifiersModule = TaskKey[GetClassifiersModule]("coursier-sbt-classifiers-module")
|
||||
|
||||
val coursierConfigurations = TaskKey[Map[Configuration, Set[Configuration]]]("coursier-configurations")
|
||||
|
||||
|
||||
val coursierParentProjectCache = TaskKey[Map[Seq[Resolver], Seq[ProjectCache]]]("coursier-parent-project-cache")
|
||||
val coursierResolutions = TaskKey[Map[Configuration, Resolution]]("coursier-resolutions")
|
||||
|
||||
private[coursier] val actualCoursierResolution = TaskKey[Resolution]("coursier-resolution")
|
||||
|
||||
val coursierSbtClassifiersResolutions = TaskKey[Map[Configuration, Resolution]]("coursier-sbt-classifiers-resolution")
|
||||
|
||||
val coursierDependencyTree = TaskKey[Unit](
|
||||
"coursier-dependency-tree",
|
||||
"Prints dependencies and transitive dependencies as a tree"
|
||||
)
|
||||
val coursierDependencyInverseTree = TaskKey[Unit](
|
||||
"coursier-dependency-inverse-tree",
|
||||
"Prints dependencies and transitive dependencies as an inverted tree (dependees as children)"
|
||||
)
|
||||
|
||||
val coursierWhatDependsOn = InputKey[String](
|
||||
"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, 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")
|
||||
}
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import coursier.ProjectCache
|
||||
import coursier.cache.FileCache
|
||||
import coursier.core._
|
||||
import coursier.internal.Typelevel
|
||||
import lmcoursier.definitions.ToCoursier
|
||||
import lmcoursier.{FallbackDependency, FromSbt, Inputs}
|
||||
import lmcoursier.internal.{InterProjectRepository, ResolutionParams, ResolutionRun, Resolvers}
|
||||
import coursier.sbtcoursier.Keys._
|
||||
import coursier.sbtcoursiershared.InputsTasks.{credentialsTask, strictTask}
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
|
||||
import coursier.util.{ModuleMatcher, ModuleMatchers}
|
||||
import sbt.Def
|
||||
import sbt.Keys._
|
||||
|
||||
object ResolutionTasks {
|
||||
|
||||
def resolutionsTask(
|
||||
sbtClassifiers: Boolean = false,
|
||||
missingOk: Boolean = false,
|
||||
): Def.Initialize[sbt.Task[Map[Configuration, coursier.Resolution]]] = {
|
||||
|
||||
val currentProjectTask: sbt.Def.Initialize[sbt.Task[(Project, Seq[FallbackDependency], Seq[(Configuration, Seq[Configuration])])]] =
|
||||
if (sbtClassifiers)
|
||||
Def.task {
|
||||
val sv = scalaVersion.value
|
||||
val sbv = scalaBinaryVersion.value
|
||||
val cm = coursierSbtClassifiersModule.value
|
||||
val proj = ToCoursier.project(SbtCoursierFromSbt.sbtClassifiersProject(cm, sv, sbv))
|
||||
|
||||
val fallbackDeps = FromSbt.fallbackDependencies(
|
||||
cm.dependencies,
|
||||
sv,
|
||||
sbv
|
||||
)
|
||||
|
||||
(proj, fallbackDeps, cm.configurations.map(c => Configuration(c.name) -> Nil))
|
||||
}
|
||||
else
|
||||
Def.task {
|
||||
val baseConfigGraphs = coursierConfigGraphs.value
|
||||
val publications = coursierPublications.value
|
||||
(ToCoursier.project(coursierProject.value.withPublications(publications)), coursierFallbackDependencies.value, baseConfigGraphs)
|
||||
}
|
||||
|
||||
val resolversTask =
|
||||
if (sbtClassifiers)
|
||||
Def.task(coursierSbtResolvers.value)
|
||||
else
|
||||
Def.task(coursierRecursiveResolvers.value.distinct)
|
||||
|
||||
val retrySettings = Def.task(coursierRetry.value)
|
||||
|
||||
Def.task {
|
||||
val projectName = thisProjectRef.value.project
|
||||
|
||||
val sv = scalaVersion.value
|
||||
val sbv = scalaBinaryVersion.value
|
||||
|
||||
val interProjectDependencies = coursierInterProjectDependencies.value.map(ToCoursier.project)
|
||||
val extraProjects = coursierExtraProjects.value.map(ToCoursier.project)
|
||||
|
||||
val parallelDownloads = coursierParallelDownloads.value
|
||||
val checksums = coursierChecksums.value
|
||||
val maxIterations = coursierMaxIterations.value
|
||||
val cachePolicies = coursierCachePolicies.value
|
||||
val ttl = coursierTtl.value
|
||||
val cache = coursierCache.value
|
||||
val createLogger = coursierLogger.value.map(ToCoursier.cacheLogger)
|
||||
|
||||
val log = streams.value.log
|
||||
|
||||
// are these always defined? (e.g. for Java only projects?)
|
||||
val so = Organization(scalaOrganization.value)
|
||||
|
||||
val userForceVersions = Inputs.forceVersions(dependencyOverrides.value, sv, sbv)
|
||||
|
||||
val verbosityLevel = coursierVerbosity.value
|
||||
|
||||
val userEnabledProfiles = mavenProfiles.value
|
||||
val versionReconciliations0 = versionReconciliation.value.map { mod =>
|
||||
Reconciliation(mod.revision) match {
|
||||
case Some(rec) =>
|
||||
val (mod0, _) = FromSbt.moduleVersion(mod, sv, sbv)
|
||||
val matcher = ModuleMatchers.only(Organization(mod0.organization.value), ModuleName(mod0.name.value))
|
||||
matcher -> rec
|
||||
case None =>
|
||||
throw new Exception(s"Unrecognized reconciliation: '${mod.revision}'")
|
||||
}
|
||||
}
|
||||
|
||||
val typelevel = Organization(scalaOrganization.value) == Typelevel.typelevelOrg
|
||||
|
||||
val interProjectRepo = InterProjectRepository(interProjectDependencies)
|
||||
val extraProjectsRepo = InterProjectRepository(extraProjects)
|
||||
|
||||
val ivyProperties = ResolutionParams.defaultIvyProperties(ivyPaths.value.ivyHome)
|
||||
|
||||
val authenticationByRepositoryId = actualCoursierCredentials.value.mapValues(_.authentication)
|
||||
|
||||
val (currentProject, fallbackDependencies, orderedConfigs) = currentProjectTask.value
|
||||
|
||||
val autoScalaLib = autoScalaLibrary.value && scalaModuleInfo.value.forall(_.overrideScalaVersion)
|
||||
|
||||
val resolvers = resolversTask.value
|
||||
|
||||
// TODO Warn about possible duplicated modules from source repositories?
|
||||
|
||||
val credentials = credentialsTask.value.map(ToCoursier.credentials)
|
||||
|
||||
val strictOpt = strictTask.value.map(ToCoursier.strict)
|
||||
|
||||
val parentProjectCache: ProjectCache = coursierParentProjectCache.value
|
||||
.get(resolvers)
|
||||
.map(_.foldLeft[ProjectCache](Map.empty)(_ ++ _))
|
||||
.getOrElse(Map.empty)
|
||||
|
||||
val excludeDeps = Inputs.exclusions(
|
||||
coursier.sbtcoursiershared.InputsTasks.actualExcludeDependencies.value,
|
||||
sv,
|
||||
sbv,
|
||||
log
|
||||
).map {
|
||||
case (org, name) =>
|
||||
(Organization(org.value), ModuleName(name.value))
|
||||
}
|
||||
|
||||
val mainRepositories = resolvers
|
||||
.flatMap { resolver =>
|
||||
Resolvers.repository(
|
||||
resolver,
|
||||
ivyProperties,
|
||||
log,
|
||||
authenticationByRepositoryId.get(resolver.name).map { a =>
|
||||
Authentication(a.user, a.password)
|
||||
.withOptional(a.optional)
|
||||
.withRealmOpt(a.realmOpt)
|
||||
},
|
||||
Seq(),
|
||||
)
|
||||
}
|
||||
|
||||
val resOrError = ResolutionRun.resolutions(
|
||||
ResolutionParams(
|
||||
dependencies = currentProject.dependencies,
|
||||
fallbackDependencies = fallbackDependencies,
|
||||
orderedConfigs = orderedConfigs,
|
||||
autoScalaLibOpt = if (autoScalaLib) Some((so, sv)) else None,
|
||||
mainRepositories = mainRepositories,
|
||||
parentProjectCache = parentProjectCache,
|
||||
interProjectDependencies = interProjectDependencies,
|
||||
internalRepositories = Seq(interProjectRepo, extraProjectsRepo),
|
||||
sbtClassifiers = sbtClassifiers,
|
||||
projectName = projectName,
|
||||
loggerOpt = createLogger,
|
||||
cache = FileCache()
|
||||
.withLocation(cache)
|
||||
.withCachePolicies(cachePolicies)
|
||||
.withTtl(ttl)
|
||||
.withChecksums(checksums)
|
||||
.withCredentials(credentials)
|
||||
.withFollowHttpToHttpsRedirections(true),
|
||||
parallel = parallelDownloads,
|
||||
params = coursier.params.ResolutionParams()
|
||||
.withMaxIterations(maxIterations)
|
||||
.withProfiles(userEnabledProfiles)
|
||||
.withForceVersion(userForceVersions.map { case (k, v) => (ToCoursier.module(k), v) }.toMap)
|
||||
.withTypelevel(typelevel)
|
||||
.addReconciliation(versionReconciliations0: _*)
|
||||
.withExclusions(excludeDeps),
|
||||
strictOpt = strictOpt,
|
||||
missingOk = missingOk,
|
||||
retry = retrySettings.value.getOrElse(ResolutionParams.defaultRetry)
|
||||
),
|
||||
verbosityLevel,
|
||||
log
|
||||
)
|
||||
|
||||
resOrError match {
|
||||
case Left(err) =>
|
||||
throw err
|
||||
case Right(res) =>
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import lmcoursier.FromSbt
|
||||
import lmcoursier.definitions.Configuration
|
||||
import sbt.librarymanagement.GetClassifiersModule
|
||||
|
||||
object SbtCoursierFromSbt {
|
||||
|
||||
def sbtClassifiersProject(
|
||||
cm: GetClassifiersModule,
|
||||
scalaVersion: String,
|
||||
scalaBinaryVersion: String
|
||||
) = {
|
||||
|
||||
val p = FromSbt.project(
|
||||
cm.id,
|
||||
cm.dependencies,
|
||||
cm.configurations.map(cfg => Configuration(cfg.name) -> cfg.extendsConfigs.map(c => Configuration(c.name))).toMap,
|
||||
scalaVersion,
|
||||
scalaBinaryVersion
|
||||
)
|
||||
|
||||
// for w/e reasons, the dependencies sometimes don't land in the right config above
|
||||
// this is a loose attempt at fixing that
|
||||
cm.configurations match {
|
||||
case Seq(cfg) =>
|
||||
p.withDependencies(
|
||||
p.dependencies.map {
|
||||
case (_, d) => (Configuration(cfg.name), d)
|
||||
}
|
||||
)
|
||||
case _ =>
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import sbt.Logger
|
||||
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
||||
object Settings {
|
||||
|
||||
private val baseDefaultVerbosityLevel =
|
||||
if (System.console() == null) // non interactive mode
|
||||
0
|
||||
else
|
||||
1
|
||||
|
||||
def defaultVerbosityLevel(logger: Logger): Int = {
|
||||
|
||||
def fromOption(value: Option[String], description: String): Option[Int] =
|
||||
value
|
||||
.filter(_.nonEmpty)
|
||||
.flatMap { str =>
|
||||
Try(str.toInt) match {
|
||||
case Success(level) => Some(level)
|
||||
case Failure(_) =>
|
||||
logger.warn(
|
||||
s"unrecognized $description value (should be an integer), ignoring it."
|
||||
)
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
val fromEnv = fromOption(
|
||||
sys.env.get("COURSIER_VERBOSITY"),
|
||||
"COURSIER_VERBOSITY environment variable"
|
||||
)
|
||||
|
||||
def fromProps = fromOption(
|
||||
sys.props.get("coursier.verbosity"),
|
||||
"Java property coursier.verbosity"
|
||||
)
|
||||
|
||||
fromEnv
|
||||
.orElse(fromProps)
|
||||
.getOrElse(baseDefaultVerbosityLevel)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
package coursier.sbtcoursier
|
||||
|
||||
import coursier.core._
|
||||
import coursier.sbtcoursier.Keys._
|
||||
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
|
||||
import lmcoursier.definitions.ToCoursier
|
||||
import lmcoursier.Inputs
|
||||
import lmcoursier.internal.{SbtBootJars, SbtCoursierCache, UpdateParams, UpdateRun}
|
||||
import sbt.Def
|
||||
import sbt.Keys._
|
||||
import sbt.librarymanagement.UpdateReport
|
||||
|
||||
object UpdateTasks {
|
||||
|
||||
def updateTask(
|
||||
withClassifiers: Boolean,
|
||||
sbtClassifiers: Boolean = false,
|
||||
includeSignatures: Boolean = false
|
||||
): Def.Initialize[sbt.Task[UpdateReport]] = {
|
||||
|
||||
val currentProjectTask =
|
||||
if (sbtClassifiers)
|
||||
Def.task {
|
||||
val sv = scalaVersion.value
|
||||
val sbv = scalaBinaryVersion.value
|
||||
SbtCoursierFromSbt.sbtClassifiersProject(coursierSbtClassifiersModule.value, sv, sbv)
|
||||
}
|
||||
else
|
||||
Def.task {
|
||||
val proj = coursierProject.value
|
||||
val publications = coursierPublications.value
|
||||
proj.withPublications(publications)
|
||||
}
|
||||
|
||||
val resTask =
|
||||
if (withClassifiers && sbtClassifiers)
|
||||
coursierSbtClassifiersResolutions
|
||||
else
|
||||
coursierResolutions
|
||||
|
||||
// we should be able to call .value on that one here, its conditions don't originate from other tasks
|
||||
val artifactFilesOrErrors0Task =
|
||||
if (withClassifiers) {
|
||||
if (sbtClassifiers)
|
||||
Keys.coursierSbtClassifiersArtifacts
|
||||
else
|
||||
Keys.coursierClassifiersArtifacts
|
||||
} else if (includeSignatures)
|
||||
Keys.coursierSignedArtifacts
|
||||
else
|
||||
Keys.coursierArtifacts
|
||||
|
||||
val configsTask: sbt.Def.Initialize[sbt.Task[Map[Configuration, Set[Configuration]]]] =
|
||||
if (withClassifiers && sbtClassifiers)
|
||||
Def.task {
|
||||
val cm = coursierSbtClassifiersModule.value
|
||||
cm.configurations.map(c => Configuration(c.name) -> Set(Configuration(c.name))).toMap
|
||||
}
|
||||
else
|
||||
coursierConfigurations
|
||||
|
||||
val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[Classifier]]]] =
|
||||
if (withClassifiers) {
|
||||
if (sbtClassifiers)
|
||||
Def.task {
|
||||
val cm = coursierSbtClassifiersModule.value
|
||||
Some(cm.classifiers.map(Classifier(_)))
|
||||
}
|
||||
else
|
||||
Def.task(Some(transitiveClassifiers.value.map(Classifier(_))))
|
||||
} else
|
||||
Def.task(None)
|
||||
|
||||
Def.taskDyn {
|
||||
|
||||
val so = Organization(scalaOrganization.value)
|
||||
val internalSbtScalaProvider = appConfiguration.value.provider.scalaProvider
|
||||
val sbtBootJarOverrides = SbtBootJars(
|
||||
so, // this seems plain wrong - this assumes that the scala org of the project is the same
|
||||
// as the one that started SBT. This will scrap the scala org specific JARs by the ones
|
||||
// that booted SBT, even if the latter come from the standard org.scala-lang org.
|
||||
// But SBT itself does it this way, and not doing so may make two different versions
|
||||
// of the scala JARs land in the classpath...
|
||||
internalSbtScalaProvider.version(),
|
||||
internalSbtScalaProvider.jars()
|
||||
)
|
||||
|
||||
val log = streams.value.log
|
||||
|
||||
val verbosityLevel = coursierVerbosity.value
|
||||
val p = ToCoursier.project(currentProjectTask.value)
|
||||
val dependencies = p.dependencies
|
||||
val res = resTask.value
|
||||
|
||||
val key = SbtCoursierCache.ReportKey(
|
||||
dependencies,
|
||||
res,
|
||||
withClassifiers,
|
||||
sbtClassifiers,
|
||||
includeSignatures
|
||||
)
|
||||
|
||||
val interProjectDependencies = coursierInterProjectDependencies.value.map(ToCoursier.project)
|
||||
|
||||
SbtCoursierCache.default.reportOpt(key) match {
|
||||
case Some(report) =>
|
||||
Def.task(report)
|
||||
case None =>
|
||||
Def.task {
|
||||
|
||||
val artifactFilesOrErrors0 = artifactFilesOrErrors0Task.value
|
||||
val classifiers = classifiersTask.value
|
||||
val configs = configsTask.value
|
||||
val sv = scalaVersion.value
|
||||
val sbv = scalaBinaryVersion.value
|
||||
val forceVersions = Inputs.forceVersions(dependencyOverrides.value, sv, sbv)
|
||||
.map {
|
||||
case (m, v) =>
|
||||
(ToCoursier.module(m), v)
|
||||
}
|
||||
.toMap
|
||||
|
||||
val params = UpdateParams(
|
||||
(p.module, p.version),
|
||||
artifactFilesOrErrors0,
|
||||
None,
|
||||
classifiers,
|
||||
configs,
|
||||
dependencies,
|
||||
forceVersions,
|
||||
interProjectDependencies,
|
||||
res,
|
||||
includeSignatures,
|
||||
sbtBootJarOverrides,
|
||||
classpathOrder = true,
|
||||
missingOk = sbtClassifiers,
|
||||
classLoaders = Nil,
|
||||
)
|
||||
|
||||
val rep = UpdateRun.update(params, verbosityLevel, log)
|
||||
SbtCoursierCache.default.putReport(key, rep)
|
||||
rep
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
package coursier.sbtlmcoursier
|
||||
|
||||
import lmcoursier.definitions.{Authentication, ModuleMatchers, Reconciliation}
|
||||
import lmcoursier.{CoursierConfiguration, CoursierDependencyResolution, Inputs}
|
||||
import lmcoursier.syntax._
|
||||
import coursier.sbtcoursiershared.InputsTasks.{credentialsTask, strictTask}
|
||||
import coursier.sbtcoursiershared.{InputsTasks, SbtCoursierShared}
|
||||
import sbt.{AutoPlugin, Classpaths, Def, Setting, Task, taskKey}
|
||||
import sbt.Project.inTask
|
||||
import sbt.KeyRanks.DTask
|
||||
import sbt.Keys.{appConfiguration, autoScalaLibrary, classpathTypes, dependencyOverrides, dependencyResolution, ivyPaths, scalaBinaryVersion, scalaModuleInfo, scalaOrganization, scalaVersion, streams, updateClassifiers, updateConfiguration, updateSbtClassifiers}
|
||||
import sbt.librarymanagement.DependencyResolution
|
||||
|
||||
import scala.language.reflectiveCalls
|
||||
import sbt.TaskKey
|
||||
|
||||
object LmCoursierPlugin extends AutoPlugin {
|
||||
|
||||
import SbtCoursierShared.autoImport._
|
||||
|
||||
object autoImport {
|
||||
val coursierConfiguration = taskKey[CoursierConfiguration]("General dependency management (Coursier) settings, such as the resolvers and options to use.").withRank(DTask)
|
||||
|
||||
val addSbtCoursier: Seq[Def.Setting[_]] = {
|
||||
import sbt._
|
||||
Seq(
|
||||
addSbtPlugin("io.get-coursier" % "sbt-lm-coursier" % sbtCoursierVersion),
|
||||
// seems needed for some sbt plugins (https://github.com/coursier/coursier/issues/450)
|
||||
classpathTypes += "maven-plugin"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import autoImport._
|
||||
|
||||
|
||||
override def trigger = allRequirements
|
||||
|
||||
// this transitively requires IvyPlugin… which is needed to override it,
|
||||
// so that it doesn't override us :|
|
||||
override def requires = SbtCoursierShared
|
||||
|
||||
private lazy val scalaCompilerBridgeScopeOpt: Option[TaskKey[Unit]] =
|
||||
try {
|
||||
// only added in sbt 1.3.x
|
||||
val key = sbt.Keys
|
||||
.asInstanceOf[{ def scalaCompilerBridgeScope: TaskKey[Unit] }]
|
||||
.scalaCompilerBridgeScope
|
||||
Some(key)
|
||||
}
|
||||
catch {
|
||||
case _: NoSuchMethodError | _: NoSuchMethodException =>
|
||||
None
|
||||
}
|
||||
|
||||
// putting this in projectSettings like sbt.plugins.IvyPlugin does :|
|
||||
override def projectSettings: Seq[Setting[_]] =
|
||||
Seq(
|
||||
dependencyResolution := mkDependencyResolution.value,
|
||||
coursierConfiguration := mkCoursierConfiguration().value,
|
||||
updateClassifiers := Def.taskDyn {
|
||||
val lm = dependencyResolution.in(updateClassifiers).value
|
||||
Def.task(sbt.hack.Foo.updateTask(lm).value)
|
||||
}.value
|
||||
) ++
|
||||
setCsrConfiguration ++
|
||||
inTask(updateClassifiers)(
|
||||
Seq(
|
||||
dependencyResolution := mkDependencyResolution.value,
|
||||
coursierConfiguration := mkCoursierConfiguration(withClassifiers = true).value
|
||||
)
|
||||
) ++
|
||||
inTask(updateSbtClassifiers)(
|
||||
Seq(
|
||||
dependencyResolution := mkDependencyResolution.value,
|
||||
coursierConfiguration := mkCoursierConfiguration(sbtClassifiers = true).value
|
||||
)
|
||||
) ++ {
|
||||
scalaCompilerBridgeScopeOpt match {
|
||||
case None => Nil
|
||||
case Some(scalaCompilerBridgeScopeKey) =>
|
||||
inTask(scalaCompilerBridgeScopeKey)(
|
||||
Seq(
|
||||
dependencyResolution := mkDependencyResolution.value,
|
||||
coursierConfiguration := mkCoursierConfiguration().value
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def setCsrConfiguration: Seq[Setting[_]] = {
|
||||
val csrConfigurationOpt = try {
|
||||
val key = sbt.Keys.asInstanceOf[{
|
||||
def csrConfiguration: TaskKey[CoursierConfiguration]
|
||||
}].csrConfiguration
|
||||
Some(key)
|
||||
} catch {
|
||||
case _: NoSuchMethodException =>
|
||||
None
|
||||
}
|
||||
|
||||
csrConfigurationOpt.toSeq.map { csrConfiguration =>
|
||||
csrConfiguration := coursierConfiguration.value
|
||||
}
|
||||
}
|
||||
|
||||
private def mkCoursierConfiguration(withClassifiers: Boolean = false, sbtClassifiers: Boolean = false): Def.Initialize[Task[CoursierConfiguration]] =
|
||||
Def.taskDyn {
|
||||
val resolversTask =
|
||||
if (sbtClassifiers)
|
||||
coursierSbtResolvers
|
||||
else
|
||||
coursierRecursiveResolvers
|
||||
val interProjectDependenciesTask: sbt.Def.Initialize[sbt.Task[Seq[lmcoursier.definitions.Project]]] =
|
||||
if (sbtClassifiers)
|
||||
Def.task(Seq.empty[lmcoursier.definitions.Project])
|
||||
else
|
||||
Def.task(coursierInterProjectDependencies.value)
|
||||
val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[String]]]] =
|
||||
if (withClassifiers && !sbtClassifiers)
|
||||
Def.task(Some(sbt.Keys.transitiveClassifiers.value))
|
||||
else
|
||||
Def.task(None)
|
||||
Def.task {
|
||||
val rs = resolversTask.value
|
||||
val scalaOrg = scalaOrganization.value
|
||||
val scalaVer = scalaVersion.value
|
||||
val sbv = scalaBinaryVersion.value
|
||||
val interProjectDependencies = interProjectDependenciesTask.value
|
||||
val extraProjects = coursierExtraProjects.value
|
||||
val excludeDeps = Inputs.exclusions(
|
||||
InputsTasks.actualExcludeDependencies.value,
|
||||
scalaVer,
|
||||
scalaBinaryVersion.value,
|
||||
streams.value.log
|
||||
)
|
||||
val fallbackDeps = coursierFallbackDependencies.value
|
||||
val autoScalaLib = autoScalaLibrary.value && scalaModuleInfo.value.forall(_.overrideScalaVersion)
|
||||
val profiles = mavenProfiles.value
|
||||
val versionReconciliations0 = versionReconciliation.value.map { mod =>
|
||||
Reconciliation(mod.revision) match {
|
||||
case Some(rec) =>
|
||||
val (mod0, _) = lmcoursier.FromSbt.moduleVersion(mod, scalaVer, sbv)
|
||||
val matcher = ModuleMatchers.only(mod0)
|
||||
matcher -> rec
|
||||
case None =>
|
||||
throw new Exception(s"Unrecognized reconciliation: '${mod.revision}'")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val userForceVersions = Inputs.forceVersions(dependencyOverrides.value, scalaVer, sbv)
|
||||
|
||||
val authenticationByRepositoryId = actualCoursierCredentials.value.mapValues { c =>
|
||||
val a = c.authentication
|
||||
Authentication(a.user, a.password, a.optional, a.realmOpt, headers = Nil, httpsOnly = true, passOnRedirect = false)
|
||||
}
|
||||
val credentials = credentialsTask.value
|
||||
val strict = strictTask.value
|
||||
|
||||
val createLogger = coursierLogger.value
|
||||
|
||||
val cache = coursierCache.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
|
||||
val updateConfig = updateConfiguration.value
|
||||
val s = streams.value
|
||||
Classpaths.warnResolversConflict(rs, s.log)
|
||||
CoursierConfiguration()
|
||||
.withResolvers(rs.toVector)
|
||||
.withInterProjectDependencies(interProjectDependencies.toVector)
|
||||
.withExtraProjects(extraProjects.toVector)
|
||||
.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)
|
||||
.withHasClassifiers(classifiers.nonEmpty)
|
||||
.withMavenProfiles(profiles.toVector.sorted)
|
||||
.withReconciliation(versionReconciliations0.toVector)
|
||||
.withScalaOrganization(scalaOrg)
|
||||
.withScalaVersion(scalaVer)
|
||||
.withAuthenticationByRepositoryId(authenticationByRepositoryId.toVector.sortBy(_._1))
|
||||
.withCredentials(credentials)
|
||||
.withLogger(createLogger)
|
||||
.withCache(cache)
|
||||
.withLog(s.log)
|
||||
.withIvyHome(ivyPaths.value.ivyHome)
|
||||
.withStrict(strict)
|
||||
.withForceVersions(userForceVersions.toVector)
|
||||
.withSbtClassifiers(sbtClassifiers)
|
||||
// seems missingOk is false in the updateConfig of updateSbtClassifiers?
|
||||
.withUpdateConfiguration(updateConfig.withMissingOk(updateConfig.missingOk || sbtClassifiers))
|
||||
}
|
||||
}
|
||||
private def mkDependencyResolution: Def.Initialize[Task[DependencyResolution]] =
|
||||
Def.task {
|
||||
CoursierDependencyResolution(coursierConfiguration.value, None)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
package sbt.hack
|
||||
|
||||
import sbt._
|
||||
import sbt.Keys._
|
||||
import sbt.internal.LibraryManagement
|
||||
import sbt.librarymanagement.DependencyResolution
|
||||
|
||||
import scala.language.reflectiveCalls
|
||||
|
||||
object Foo {
|
||||
|
||||
// same implementation as update in sbt, except DependencyResolution is passed as argument
|
||||
// and the unmanagedJarsTask stuff was removed (already handled in lm-coursier via
|
||||
// SbtBootJars and all)
|
||||
def updateTask(lm: DependencyResolution): Def.Initialize[Task[UpdateReport]] = Def.task {
|
||||
val s = streams.value
|
||||
val cacheDirectory = streams.value.cacheDirectory
|
||||
|
||||
val isRoot = executionRoots.value contains resolvedScoped.value
|
||||
val shouldForce = isRoot || {
|
||||
forceUpdatePeriod.value match {
|
||||
case None => false
|
||||
case Some(period) =>
|
||||
val fullUpdateOutput = cacheDirectory / "out"
|
||||
val now = System.currentTimeMillis
|
||||
val diff = now - fullUpdateOutput.lastModified()
|
||||
val elapsedDuration = new scala.concurrent.duration.FiniteDuration(diff, java.util.concurrent.TimeUnit.MILLISECONDS)
|
||||
fullUpdateOutput.exists() && elapsedDuration > period
|
||||
}
|
||||
}
|
||||
|
||||
val state0 = state.value
|
||||
val updateConf = {
|
||||
// Log captures log messages at all levels, except ivy logs.
|
||||
// Use full level when debug is enabled so that ivy logs are shown.
|
||||
import UpdateLogging.{ Full, DownloadOnly, Default }
|
||||
val conf = updateConfiguration.value
|
||||
val maybeUpdateLevel = (logLevel in update).?.value
|
||||
val conf1 = maybeUpdateLevel.orElse(state0.get(logLevel.key)) match {
|
||||
case Some(Level.Debug) if conf.logging == Default => conf.withLogging(logging = Full)
|
||||
case Some(_) if conf.logging == Default => conf.withLogging(logging = DownloadOnly)
|
||||
case _ => conf
|
||||
}
|
||||
|
||||
// logical clock is folded into UpdateConfiguration
|
||||
conf1.withLogicalClock(LogicalClock(state0.hashCode))
|
||||
}
|
||||
|
||||
val evictionOptions = Def.taskDyn {
|
||||
if (executionRoots.value.exists(_.key == evicted.key))
|
||||
Def.task(EvictionWarningOptions.empty)
|
||||
else Def.task((evictionWarningOptions in update).value)
|
||||
}.value
|
||||
|
||||
try {
|
||||
LibraryManagement.cachedUpdate(
|
||||
// LM API
|
||||
lm = lm,
|
||||
// Ivy-free ModuleDescriptor
|
||||
module = ivyModule.value,
|
||||
s.cacheStoreFactory.sub(updateCacheName.value),
|
||||
Reference.display(thisProjectRef.value),
|
||||
updateConf,
|
||||
identity,
|
||||
skip = (skip in update).value,
|
||||
force = shouldForce,
|
||||
depsUpdated = transitiveUpdate.value.exists(!_.stats.cached),
|
||||
uwConfig = (unresolvedWarningConfiguration in update).value,
|
||||
ewo = evictionOptions,
|
||||
mavenStyle = publishMavenStyle.value,
|
||||
compatWarning = compatibilityWarningOptions.value,
|
||||
log = s.log
|
||||
)
|
||||
} catch {
|
||||
case _: NoSuchMethodError =>
|
||||
// cachedUpdate method changed in https://github.com/sbt/sbt/commit/6c7faf2b8611f122a37b824c6e08e950855d939f
|
||||
import sbt.internal.librarymanagement.CompatibilityWarningOptions
|
||||
import sbt.librarymanagement.{DependencyResolution, ModuleDescriptor, UnresolvedWarningConfiguration, UpdateConfiguration}
|
||||
import sbt.util.CacheStoreFactory
|
||||
LibraryManagement.asInstanceOf[{
|
||||
def cachedUpdate(
|
||||
lm: DependencyResolution,
|
||||
module: ModuleDescriptor,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
label: String,
|
||||
updateConfig: UpdateConfiguration,
|
||||
transform: UpdateReport => UpdateReport,
|
||||
skip: Boolean,
|
||||
force: Boolean,
|
||||
depsUpdated: Boolean,
|
||||
uwConfig: UnresolvedWarningConfiguration,
|
||||
ewo: EvictionWarningOptions,
|
||||
mavenStyle: Boolean,
|
||||
compatWarning: CompatibilityWarningOptions,
|
||||
includeCallers: Boolean,
|
||||
includeDetails: Boolean,
|
||||
log: Logger
|
||||
): UpdateReport
|
||||
}].cachedUpdate(
|
||||
// LM API
|
||||
lm = lm,
|
||||
// Ivy-free ModuleDescriptor
|
||||
module = ivyModule.value,
|
||||
s.cacheStoreFactory.sub(updateCacheName.value),
|
||||
Reference.display(thisProjectRef.value),
|
||||
updateConf,
|
||||
identity,
|
||||
skip = (skip in update).value,
|
||||
force = shouldForce,
|
||||
depsUpdated = transitiveUpdate.value.exists(!_.stats.cached),
|
||||
uwConfig = (unresolvedWarningConfiguration in update).value,
|
||||
ewo = evictionOptions,
|
||||
mavenStyle = publishMavenStyle.value,
|
||||
compatWarning = compatibilityWarningOptions.value,
|
||||
includeCallers = false,
|
||||
includeDetails = false,
|
||||
log = s.log
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue