Merge pull request #9 from alexarchambault/develop

Various stuff
This commit is contained in:
Alexandre Archambault 2018-11-22 12:39:53 +01:00 committed by GitHub
commit 7daa367e43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
105 changed files with 831 additions and 614 deletions

View File

@ -12,11 +12,12 @@ stages:
if: (branch = master AND type = push) OR (tag IS present)
jobs:
include:
- env: SBT_COURSIER=1 SBT_COURSIER_TEST_GROUP=1
- env: SBT_COURSIER=1 SBT_COURSIER_TEST_GROUP=2
- env: SBT_COURSIER=1 TEST_GROUP=1
- env: SBT_COURSIER=1 TEST_GROUP=2
- env: SBT_SHADING=1
- env: SBT_PGP_COURSIER=1
- env: LM_COURSIER=1
- env: LM_COURSIER=1 TEST_GROUP=1
- env: LM_COURSIER=1 TEST_GROUP=2
- stage: release
script: sbt ci-release
branches:

View File

@ -19,7 +19,7 @@ val coursierVersion = "1.1.0-M8"
lazy val `lm-coursier` = project
.in(file("modules/lm-coursier"))
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.enablePlugins(ContrabandPlugin)
.settings(
shared,
libraryDependencies ++= Seq(
@ -40,10 +40,20 @@ lazy val `lm-coursier` = project
contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats
)
lazy val `sbt-coursier-shared` = project
.in(file("modules/sbt-coursier-shared"))
.enablePlugins(ScriptedPlugin)
.dependsOn(`lm-coursier`)
.settings(
plugin,
libraryDependencies += "com.lihaoyi" %% "utest" % "0.6.4" % Test,
testFrameworks += new TestFramework("utest.runner.Framework")
)
lazy val `sbt-lm-coursier` = project
.in(file("modules/sbt-lm-coursier"))
.enablePlugins(ScriptedPlugin)
.dependsOn(`lm-coursier`)
.dependsOn(`sbt-coursier-shared`)
.settings(
plugin,
sbtTestDirectory := sbtTestDirectory.in(`sbt-coursier`).value,
@ -53,17 +63,16 @@ lazy val `sbt-lm-coursier` = project
// TODO Get those automatically
// (but shouldn't scripted itself handle that…?)
publishLocal.in(`lm-coursier`).value
publishLocal.in(`sbt-coursier-shared`).value
}
)
lazy val `sbt-coursier` = project
.in(file("modules/sbt-coursier"))
.enablePlugins(ScriptedPlugin)
.dependsOn(`lm-coursier`)
.dependsOn(`sbt-coursier-shared`)
.settings(
plugin,
libraryDependencies += "com.lihaoyi" %% "utest" % "0.6.4" % Test,
testFrameworks += new TestFramework("utest.runner.Framework"),
libraryDependencies +="io.get-coursier" %% "coursier-scalaz-interop" % coursierVersion,
scriptedDependencies := {
scriptedDependencies.value
@ -71,6 +80,7 @@ lazy val `sbt-coursier` = project
// TODO Get dependency projects automatically
// (but shouldn't scripted itself handle that…?)
publishLocal.in(`lm-coursier`).value
publishLocal.in(`sbt-coursier-shared`).value
}
)
@ -120,6 +130,7 @@ lazy val `sbt-coursier-root` = project
.aggregate(
`lm-coursier`,
`sbt-coursier`,
`sbt-coursier-shared`,
`sbt-lm-coursier`,
`sbt-pgp-coursier`,
`sbt-shading`

View File

@ -7,28 +7,33 @@ package coursier.lmcoursier
final class CoursierConfiguration private (
val log: Option[xsbti.Logger],
val resolvers: Vector[sbt.librarymanagement.Resolver],
val otherResolvers: Vector[sbt.librarymanagement.Resolver],
val reorderResolvers: Boolean,
val parallelDownloads: Int,
val maxIterations: Int,
val sbtScalaOrganization: Option[String],
val sbtScalaVersion: Option[String],
val sbtScalaJars: Vector[java.io.File]) extends Serializable {
val sbtScalaJars: Vector[java.io.File],
val interProjectDependencies: Vector[coursier.core.Project],
val excludeDependencies: Vector[(String, String)],
val fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency],
val autoScalaLibrary: Boolean,
val hasClassifiers: Boolean,
val classifiers: Vector[String]) extends Serializable {
private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100, None, None, Vector.empty)
private def this() = this(None, sbt.librarymanagement.Resolver.defaults, true, 6, 100, None, None, Vector.empty, Vector.empty, Vector.empty, Vector.empty, true, false, Vector.empty)
override def equals(o: Any): Boolean = o match {
case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.sbtScalaOrganization == x.sbtScalaOrganization) && (this.sbtScalaVersion == x.sbtScalaVersion) && (this.sbtScalaJars == x.sbtScalaJars)
case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.sbtScalaOrganization == x.sbtScalaOrganization) && (this.sbtScalaVersion == x.sbtScalaVersion) && (this.sbtScalaJars == x.sbtScalaJars) && (this.interProjectDependencies == x.interProjectDependencies) && (this.excludeDependencies == x.excludeDependencies) && (this.fallbackDependencies == x.fallbackDependencies) && (this.autoScalaLibrary == x.autoScalaLibrary) && (this.hasClassifiers == x.hasClassifiers) && (this.classifiers == x.classifiers)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "coursier.lmcoursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + sbtScalaOrganization.##) + sbtScalaVersion.##) + sbtScalaJars.##)
37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "coursier.lmcoursier.CoursierConfiguration".##) + log.##) + resolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + sbtScalaOrganization.##) + sbtScalaVersion.##) + sbtScalaJars.##) + interProjectDependencies.##) + excludeDependencies.##) + fallbackDependencies.##) + autoScalaLibrary.##) + hasClassifiers.##) + classifiers.##)
}
override def toString: String = {
"CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + sbtScalaOrganization + ", " + sbtScalaVersion + ", " + sbtScalaJars + ")"
"CoursierConfiguration(" + log + ", " + resolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + sbtScalaOrganization + ", " + sbtScalaVersion + ", " + sbtScalaJars + ", " + interProjectDependencies + ", " + excludeDependencies + ", " + fallbackDependencies + ", " + autoScalaLibrary + ", " + hasClassifiers + ", " + classifiers + ")"
}
private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, sbtScalaOrganization: Option[String] = sbtScalaOrganization, sbtScalaVersion: Option[String] = sbtScalaVersion, sbtScalaJars: Vector[java.io.File] = sbtScalaJars): CoursierConfiguration = {
new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars)
private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, sbtScalaOrganization: Option[String] = sbtScalaOrganization, sbtScalaVersion: Option[String] = sbtScalaVersion, sbtScalaJars: Vector[java.io.File] = sbtScalaJars, interProjectDependencies: Vector[coursier.core.Project] = interProjectDependencies, excludeDependencies: Vector[(String, String)] = excludeDependencies, fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency] = fallbackDependencies, autoScalaLibrary: Boolean = autoScalaLibrary, hasClassifiers: Boolean = hasClassifiers, classifiers: Vector[String] = classifiers): CoursierConfiguration = {
new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers)
}
def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = {
copy(log = log)
@ -39,9 +44,6 @@ final class CoursierConfiguration private (
def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = {
copy(resolvers = resolvers)
}
def withOtherResolvers(otherResolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = {
copy(otherResolvers = otherResolvers)
}
def withReorderResolvers(reorderResolvers: Boolean): CoursierConfiguration = {
copy(reorderResolvers = reorderResolvers)
}
@ -66,10 +68,28 @@ final class CoursierConfiguration private (
def withSbtScalaJars(sbtScalaJars: Vector[java.io.File]): CoursierConfiguration = {
copy(sbtScalaJars = sbtScalaJars)
}
def withInterProjectDependencies(interProjectDependencies: Vector[coursier.core.Project]): CoursierConfiguration = {
copy(interProjectDependencies = interProjectDependencies)
}
def withExcludeDependencies(excludeDependencies: Vector[(String, String)]): CoursierConfiguration = {
copy(excludeDependencies = excludeDependencies)
}
def withFallbackDependencies(fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency]): CoursierConfiguration = {
copy(fallbackDependencies = fallbackDependencies)
}
def withAutoScalaLibrary(autoScalaLibrary: Boolean): CoursierConfiguration = {
copy(autoScalaLibrary = autoScalaLibrary)
}
def withHasClassifiers(hasClassifiers: Boolean): CoursierConfiguration = {
copy(hasClassifiers = hasClassifiers)
}
def withClassifiers(classifiers: Vector[String]): CoursierConfiguration = {
copy(classifiers = classifiers)
}
}
object CoursierConfiguration {
def apply(): CoursierConfiguration = new CoursierConfiguration()
def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: Option[String], sbtScalaVersion: Option[String], sbtScalaJars: Vector[java.io.File]): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars)
def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: String, sbtScalaVersion: String, sbtScalaJars: Vector[java.io.File]): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, Option(sbtScalaOrganization), Option(sbtScalaVersion), sbtScalaJars)
def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: Option[String], sbtScalaVersion: Option[String], sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String]): CoursierConfiguration = new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers)
def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: String, sbtScalaVersion: String, sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String]): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, reorderResolvers, parallelDownloads, maxIterations, Option(sbtScalaOrganization), Option(sbtScalaVersion), sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers)
}

View File

@ -1,43 +0,0 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package coursier.lmcoursier
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait CoursierConfigurationFormats { self: sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val CoursierConfigurationFormat: JsonFormat[coursier.lmcoursier.CoursierConfiguration] = new JsonFormat[coursier.lmcoursier.CoursierConfiguration] {
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): coursier.lmcoursier.CoursierConfiguration = {
jsOpt match {
case Some(js) =>
unbuilder.beginObject(js)
val log = unbuilder.readField[Option[xsbti.Logger]]("log")
val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers")
val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers")
val reorderResolvers = unbuilder.readField[Boolean]("reorderResolvers")
val parallelDownloads = unbuilder.readField[Int]("parallelDownloads")
val maxIterations = unbuilder.readField[Int]("maxIterations")
val sbtScalaOrganization = unbuilder.readField[Option[String]]("sbtScalaOrganization")
val sbtScalaVersion = unbuilder.readField[Option[String]]("sbtScalaVersion")
val sbtScalaJars = unbuilder.readField[Vector[java.io.File]]("sbtScalaJars")
unbuilder.endObject()
coursier.lmcoursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: coursier.lmcoursier.CoursierConfiguration, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("log", obj.log)
builder.addField("resolvers", obj.resolvers)
builder.addField("otherResolvers", obj.otherResolvers)
builder.addField("reorderResolvers", obj.reorderResolvers)
builder.addField("parallelDownloads", obj.parallelDownloads)
builder.addField("maxIterations", obj.maxIterations)
builder.addField("sbtScalaOrganization", obj.sbtScalaOrganization)
builder.addField("sbtScalaVersion", obj.sbtScalaVersion)
builder.addField("sbtScalaJars", obj.sbtScalaJars)
builder.endObject()
}
}
}

View File

@ -19,12 +19,6 @@
"default": "sbt.librarymanagement.Resolver.defaults",
"since": "0.0.1"
},
{
"name": "otherResolvers",
"type": "sbt.librarymanagement.Resolver*",
"default": "Vector.empty",
"since": "0.0.1"
},
{
"name": "reorderResolvers",
"type": "Boolean",
@ -60,6 +54,42 @@
"type": "java.io.File*",
"default": "Vector.empty",
"since": "0.0.1"
},
{
"name": "interProjectDependencies",
"type": "coursier.core.Project*",
"default": "Vector.empty",
"since": "0.0.1"
},
{
"name": "excludeDependencies",
"type": "(String, String)*",
"default": "Vector.empty",
"since": "0.0.1"
},
{
"name": "fallbackDependencies",
"type": "coursier.lmcoursier.FallbackDependency*",
"default": "Vector.empty",
"since": "0.0.1"
},
{
"name": "autoScalaLibrary",
"type": "Boolean",
"default": "true",
"since": "0.0.1"
},
{
"name": "hasClassifiers",
"type": "Boolean",
"default": "false",
"since": "0.0.1"
},
{
"name": "classifiers",
"type": "String*",
"default": "Vector.empty",
"since": "0.0.1"
}
]
}

View File

@ -2,8 +2,8 @@ package coursier.lmcoursier
import java.io.{File, OutputStreamWriter}
import _root_.coursier.{Artifact, Cache, CachePolicy, FileError, Organization, Project, Resolution, TermDisplay, organizationString}
import _root_.coursier.core.Configuration
import _root_.coursier.{Artifact, Cache, CachePolicy, FileError, Organization, Resolution, TermDisplay, organizationString}
import _root_.coursier.core.{Classifier, Configuration, ModuleName}
import _root_.coursier.ivy.IvyRepository
import sbt.internal.librarymanagement.IvySbt
import sbt.librarymanagement._
@ -19,6 +19,14 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
else
conf.resolvers
private lazy val excludeDependencies = conf
.excludeDependencies
.map {
case (strOrg, strName) =>
(Organization(strOrg), ModuleName(strName))
}
.toSet
def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): CoursierModuleDescriptor =
CoursierModuleDescriptor(moduleSetting, conf)
@ -66,6 +74,12 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
val ivyProperties = ResolutionParams.defaultIvyProperties()
val classifiers =
if (conf.hasClassifiers)
Some(conf.classifiers.map(Classifier(_)))
else
None
val mainRepositories = resolvers
.flatMap { resolver =>
FromSbt.repository(
@ -85,16 +99,24 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
withArtifacts = false
)
val interProjectDependencies: Seq[Project] = Nil // TODO Don't use Nil here
val interProjectRepo = InterProjectRepository(interProjectDependencies)
val interProjectRepo = InterProjectRepository(conf.interProjectDependencies)
val internalRepositories = globalPluginsRepos :+ interProjectRepo
val dependencies = module0.dependencies.flatMap { d =>
// crossVersion already taken into account, wiping it here
val d0 = d.withCrossVersion(CrossVersion.Disabled())
FromSbt.dependencies(d0, sv, sbv)
}
val dependencies = module0
.dependencies
.flatMap { d =>
// crossVersion already taken into account, wiping it here
val d0 = d.withCrossVersion(CrossVersion.Disabled())
FromSbt.dependencies(d0, sv, sbv)
}
.map {
case (config, dep) =>
val dep0 = dep.copy(
exclusions = dep.exclusions ++ excludeDependencies
)
(config, dep0)
}
val configGraphs = Inputs.ivyGraphs(
Inputs.configExtends(module0.configurations)
@ -102,12 +124,12 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
val resolutionParams = ResolutionParams(
dependencies = dependencies,
fallbackDependencies = Nil,
fallbackDependencies = conf.fallbackDependencies,
configGraphs = configGraphs,
autoScalaLib = true,
autoScalaLib = conf.autoScalaLibrary,
mainRepositories = mainRepositories,
parentProjectCache = Map.empty,
interProjectDependencies = interProjectDependencies,
interProjectDependencies = conf.interProjectDependencies,
internalRepositories = internalRepositories,
userEnabledProfiles = Set.empty,
userForceVersions = Map.empty,
@ -127,7 +149,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
def artifactsParams(resolutions: Map[Set[Configuration], Resolution]) =
ArtifactsParams(
classifiers = None,
classifiers = classifiers,
res = resolutions.values.toSeq,
includeSignatures = false,
parallelDownloads = conf.parallelDownloads,
@ -155,7 +177,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
UpdateParams(
shadedConfigOpt = None,
artifacts = artifacts,
classifiers = None,
classifiers = classifiers,
configs = configs,
dependencies = dependencies,
res = resolutions,

View File

@ -1,13 +0,0 @@
package coursier.lmcoursier
import sbt.librarymanagement.LibraryManagementCodec
trait CoursierLibraryManagementCodec
extends sjsonnew.BasicJsonProtocol
with LibraryManagementCodec
// with sbt.internal.librarymanagement.formats.GlobalLockFormat
with sbt.internal.librarymanagement.formats.LoggerFormat
with sbt.librarymanagement.ResolverFormats
with CoursierConfigurationFormats
object CoursierLibraryManagementCodec extends CoursierLibraryManagementCodec

View File

@ -1,7 +1,6 @@
package coursier.lmcoursier
import sbt.librarymanagement._
import sjsonnew.support.murmurhash.Hasher
final case class CoursierModuleDescriptor(
descriptor: ModuleDescriptorConfiguration,
@ -17,8 +16,6 @@ final case class CoursierModuleDescriptor(
def moduleSettings: CoursierModuleSettings =
CoursierModuleSettings()
lazy val extraInputHash: Long = {
import CustomLibraryManagementCodec._
Hasher.hash(conf).toOption.fold(0L)(_.toLong)
}
lazy val extraInputHash: Long =
conf.##
}

View File

@ -1,37 +0,0 @@
package coursier.lmcoursier
import sbt.librarymanagement.Resolver
import sjsonnew.JsonFormat
object CustomLibraryManagementCodec extends CoursierLibraryManagementCodec {
private type ConfFormat = (
Vector[Resolver],
Vector[Resolver],
Boolean,
Int,
Int
)
private def from(c: CoursierConfiguration): ConfFormat =
(
c.resolvers,
c.otherResolvers,
c.reorderResolvers,
c.parallelDownloads,
c.maxIterations
)
private def to(c: ConfFormat): CoursierConfiguration =
CoursierConfiguration()
.withResolvers(c._1)
.withOtherResolvers(c._2)
.withReorderResolvers(c._3)
.withParallelDownloads(c._4)
.withMaxIterations(c._5)
// Redefine to use a subset of properties, that are serializable
override implicit lazy val CoursierConfigurationFormat: JsonFormat[CoursierConfiguration] =
projectFormat[CoursierConfiguration, ConfFormat](from, to)
}

View File

@ -0,0 +1,13 @@
package coursier.lmcoursier
import java.net.URL
import coursier.core.Module
// FIXME Handle that via the contraband thing?
final case class FallbackDependency(
module: Module,
version: String,
url: URL,
changing: Boolean
)

View File

@ -94,14 +94,14 @@ object FromSbt {
allDependencies: Seq[ModuleID],
scalaVersion: String,
scalaBinaryVersion: String
): Seq[(Module, String, URL, Boolean)] =
): Seq[FallbackDependency] =
for {
module <- allDependencies
artifact <- module.explicitArtifacts
url <- artifact.url.toSeq
} yield {
val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion)
(module0, version, url, module.isChanging)
FallbackDependency(module0, version, url, module.isChanging)
}
def sbtClassifiersProject(

View File

@ -88,6 +88,34 @@ object Inputs {
sets.values.toVector.distinct.map(_.set.toSet)
}
def exclusions(
excludeDeps: Seq[InclExclRule],
sv: String,
sbv: String,
log: Logger
): Set[(Organization, ModuleName)] = {
var anyNonSupportedExclusionRule = false
val res = excludeDeps
.flatMap { rule =>
if (rule.artifact != "*" || rule.configurations.nonEmpty) {
log.warn(s"Unsupported exclusion rule $rule")
anyNonSupportedExclusionRule = true
Nil
} else
Seq(
(Organization(rule.organization), ModuleName(FromSbt.sbtCrossVersionName(rule.name, rule.crossVersion, sv, sbv)))
)
}
.toSet
if (anyNonSupportedExclusionRule)
log.warn("Only supported exclusion rule fields: organization, name")
res
}
def coursierProject(
projId: ModuleID,
dependencies: Seq[ModuleID],
@ -98,28 +126,7 @@ object Inputs {
log: Logger
): Project = {
val exclusions = {
var anyNonSupportedExclusionRule = false
val res = excludeDeps
.flatMap { rule =>
if (rule.artifact != "*" || rule.configurations.nonEmpty) {
log.warn(s"Unsupported exclusion rule $rule")
anyNonSupportedExclusionRule = true
Nil
} else
Seq(
(Organization(rule.organization), ModuleName(FromSbt.sbtCrossVersionName(rule.name, rule.crossVersion, sv, sbv)))
)
}
.toSet
if (anyNonSupportedExclusionRule)
log.warn("Only supported exclusion rule fields: organization, name")
res
}
val exclusions0 = exclusions(excludeDeps, sv, sbv, log)
val configMap = configExtends(configurations)
@ -134,7 +141,7 @@ object Inputs {
proj.copy(
dependencies = proj.dependencies.map {
case (config, dep) =>
(config, dep.copy(exclusions = dep.exclusions ++ exclusions))
(config, dep.copy(exclusions = dep.exclusions ++ exclusions0))
}
)
}

View File

@ -14,7 +14,7 @@ import scala.concurrent.duration.Duration
final case class ResolutionParams(
dependencies: Seq[(Configuration, Dependency)],
fallbackDependencies: Seq[(Module, String, URL, Boolean)],
fallbackDependencies: Seq[FallbackDependency],
configGraphs: Seq[Set[Configuration]],
autoScalaLib: Boolean,
mainRepositories: Seq[Repository],
@ -42,7 +42,7 @@ final case class ResolutionParams(
Nil
else {
val map = fallbackDependencies.map {
case (mod, ver, url, changing) =>
case FallbackDependency(mod, ver, url, changing) =>
(mod, ver) -> ((url, changing))
}.toMap

View File

@ -254,7 +254,7 @@ object ToSbt {
}
UpdateReport(
new File("."),
new File("."), // dummy value
configReports.toVector,
UpdateStats(-1L, -1L, -1L, cached = false),
Map.empty

View File

@ -15,4 +15,44 @@ final case class UpdateParams(
ignoreArtifactErrors: Boolean,
includeSignatures: Boolean,
sbtBootJarOverrides: Map[(Module, String), File]
)
) {
lazy val artifactFiles = artifacts.collect {
case (artifact, Right(file)) =>
artifact -> file
}
// can be non empty only if ignoreArtifactErrors is true or some optional artifacts are not found
lazy val erroredArtifacts = artifacts
.collect {
case (artifact, Left(_)) =>
artifact
}
.toSet
def artifactFileOpt(
module: Module,
version: String,
attributes: Attributes,
artifact: Artifact
): Option[File] = {
// Under some conditions, SBT puts the scala JARs of its own classpath
// in the application classpath. Ensuring we return SBT's jars rather than
// JARs from the coursier cache, so that a same JAR doesn't land twice in the
// application classpath (once via SBT jars, once via coursier cache).
val fromBootJars =
if (attributes.classifier.isEmpty && attributes.`type` == Type.jar)
sbtBootJarOverrides.get((module, version))
else
None
val res = fromBootJars.orElse(artifactFiles.get(artifact))
if (res.isEmpty && !erroredArtifacts(artifact))
sys.error(s"${artifact.url} not downloaded (should not happen)")
res
}
}

View File

@ -1,7 +1,5 @@
package coursier.lmcoursier
import java.io.File
import coursier.core.Resolution.ModuleVersion
import coursier.core._
import coursier.util.Print
@ -10,35 +8,6 @@ import sbt.util.Logger
object UpdateRun {
private def artifactFileOpt(
sbtBootJarOverrides: Map[(Module, String), File],
artifactFiles: Map[Artifact, File],
erroredArtifacts: Set[Artifact]
)(
module: Module,
version: String,
attributes: Attributes,
artifact: Artifact
): Option[File] = {
// Under some conditions, SBT puts the scala JARs of its own classpath
// in the application classpath. Ensuring we return SBT's jars rather than
// JARs from the coursier cache, so that a same JAR doesn't land twice in the
// application classpath (once via SBT jars, once via coursier cache).
val fromBootJars =
if (attributes.classifier.isEmpty && attributes.`type` == Type.jar)
sbtBootJarOverrides.get((module, version))
else
None
val res = fromBootJars.orElse(artifactFiles.get(artifact))
if (res.isEmpty && !erroredArtifacts(artifact))
sys.error(s"${artifact.url} not downloaded (should not happen)")
res
}
// Move back to coursier.util (in core module) after 1.0?
private def allDependenciesByConfig(
res: Map[Configuration, Resolution],
@ -114,11 +83,6 @@ object UpdateRun {
log.info(repr.split('\n').map(" " + _).mkString("\n"))
}
val artifactFiles = params.artifacts.collect {
case (artifact, Right(file)) =>
artifact -> file
}
val artifactErrors = params
.artifacts
.toVector
@ -127,26 +91,13 @@ object UpdateRun {
a -> err
}
// can be non empty only if ignoreArtifactErrors is true or some optional artifacts are not found
val erroredArtifacts = params
.artifacts
.collect {
case (artifact, Left(_)) =>
artifact
}
.toSet
def report =
ToSbt.updateReport(
depsByConfig,
configResolutions,
params.configs,
params.classifiers,
artifactFileOpt(
params.sbtBootJarOverrides,
artifactFiles,
erroredArtifacts
),
params.artifactFileOpt,
log,
includeSignatures = params.includeSignatures
)

View File

@ -0,0 +1,143 @@
package coursier.sbtcoursiershared
import coursier.core._
import coursier.lmcoursier._
import coursier.sbtcoursiershared.Structure._
import sbt.librarymanagement.{Artifact => _, Configuration => _, _}
import sbt.Def
import sbt.Keys._
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 = FromSbt.sbtCrossVersionName(
artifact.name,
projId.crossVersion,
sv,
sbv
)
Publication(
name,
Type(artifact.`type`),
Extension(artifact.extension),
artifact.classifier.fold(Classifier.empty)(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
}
}

View File

@ -0,0 +1,70 @@
package coursier.sbtcoursiershared
import coursier.core._
import coursier.lmcoursier._
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
import coursier.sbtcoursiershared.Structure._
import sbt.Def
import sbt.Keys._
object InputsTasks {
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 {
Inputs.coursierProject(
projectID.in(projectRef).get(state),
allDependenciesTask.value,
excludeDependencies.in(projectRef).get(state),
// should projectID.configurations be used instead?
ivyConfigurations.in(projectRef).get(state),
scalaVersion.in(projectRef).get(state),
scalaBinaryVersion.in(projectRef).get(state),
state.log
)
}
}
def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] =
Def.taskDyn {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projects = Structure.allRecursiveInterDependencies(state, projectRef)
val t = coursierProject.forAllProjects(state, projects).map(_.values.toVector)
Def.task(t.value)
}
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)
)
}
}
}

View File

@ -1,20 +1,22 @@
package coursier.sbtcoursier
package coursier.sbtcoursiershared
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Files
import coursier.core.{Configuration, Project}
import org.apache.ivy.core.module.id.ModuleRevisionId
import sbt.{Def, Setting, Task, TaskKey}
import sbt.internal.librarymanagement.IvySbt
import sbt.librarymanagement.PublishConfiguration
import scala.collection.JavaConverters._
import scala.xml.{Node, PrefixedAttribute}
import sbt.internal.librarymanagement.IvySbt
object IvyXml {
def rawContent(
currentProject: Project,
shadedConfigOpt: Option[(String, Configuration)]
shadedConfigOpt: Option[Configuration]
): String = {
// Important: width = Int.MaxValue, so that no tag gets truncated.
@ -26,15 +28,15 @@ object IvyXml {
val printer = new scala.xml.PrettyPrinter(Int.MaxValue, 2)
"""<?xml version="1.0" encoding="UTF-8"?>""" + '\n' +
printer.format(content(currentProject, shadedConfigOpt.map(_._2)))
printer.format(content(currentProject, shadedConfigOpt))
}
// These are required for publish to be fine, later on.
def writeFiles(
currentProject: Project,
shadedConfigOpt: Option[(String, Configuration)],
shadedConfigOpt: Option[Configuration],
ivySbt: IvySbt,
log: sbt.Logger
log: sbt.util.Logger
): Unit = {
val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
@ -153,4 +155,45 @@ object IvyXml {
</ivy-module>
}
def makeIvyXmlBefore[T](
task: TaskKey[T],
shadedConfigOpt: Option[Configuration]
): Setting[Task[T]] =
task := task.dependsOn {
Def.taskDyn {
import SbtCoursierShared.autoImport._
val doGen = coursierGenerateIvyXml.value
if (doGen)
Def.task {
val currentProject = {
val proj = coursierProject.value
val publications = coursierPublications.value
proj.copy(publications = publications)
}
IvyXml.writeFiles(currentProject, shadedConfigOpt, sbt.Keys.ivySbt.value, sbt.Keys.streams.value.log)
}
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(
shadedConfigOpt: Option[Configuration] = None
): Seq[Setting[_]] =
(needsIvyXml ++ needsIvyXmlLocal).map(IvyXml.makeIvyXmlBefore(_, shadedConfigOpt))
}

View File

@ -1,8 +1,8 @@
package coursier.sbtcoursier
package coursier.sbtcoursiershared
import coursier.lmcoursier._
import coursier.sbtcoursier.Keys._
import coursier.sbtcoursier.Structure._
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
import coursier.sbtcoursiershared.Structure._
import sbt.{Classpaths, Def}
import sbt.Keys._
import sbt.librarymanagement.Resolver
@ -60,7 +60,7 @@ object RepositoriesTasks {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projects = Structure.allRecursiveInterDependencies(state, projectRef)
val projects = allRecursiveInterDependencies(state, projectRef)
val t = coursierResolvers
.forAllProjects(state, projectRef +: projects)

View File

@ -0,0 +1,147 @@
package coursier.sbtcoursiershared
import coursier.core.{Configuration, Project, Publication}
import coursier.lmcoursier.{FallbackDependency, SbtCoursierCache}
import sbt.{AutoPlugin, Classpaths, Compile, Setting, TaskKey, Test, settingKey, taskKey}
import sbt.Keys._
import sbt.librarymanagement.{Resolver, URLRepository}
object SbtCoursierShared extends AutoPlugin {
override def trigger = allRequirements
override def requires = sbt.plugins.JvmPlugin
object autoImport {
val coursierGenerateIvyXml = settingKey[Boolean]("")
val coursierProject = TaskKey[Project]("coursier-project")
val coursierInterProjectDependencies = TaskKey[Seq[Project]]("coursier-inter-project-dependencies", "Projects the current project depends on, possibly transitively")
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]]("")
}
import autoImport._
def publicationsSetting(packageConfigs: Seq[(sbt.Configuration, Configuration)]): Setting[_] =
coursierPublications := ArtifactsTasks.coursierPublicationsTask(packageConfigs: _*).value
override def buildSettings: Seq[Setting[_]] =
Seq(
coursierReorderResolvers := true,
coursierKeepPreloaded := false
)
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()
},
coursierGenerateIvyXml := true,
coursierProject := InputsTasks.coursierProjectTask.value,
coursierInterProjectDependencies := InputsTasks.coursierInterProjectDependenciesTask.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
}
) ++ {
if (pubSettings)
IvyXml.generateIvyXmlSettings()
else
Nil
}
}

View File

@ -1,4 +1,4 @@
package coursier.sbtcoursier
package coursier.sbtcoursiershared
import coursier.core.Configuration
import coursier.{Info, Module, Project, moduleNameString, organizationString}

View File

@ -6,144 +6,11 @@ import coursier.{Artifact, FileError}
import coursier.core._
import coursier.lmcoursier._
import coursier.sbtcoursier.Keys._
import coursier.sbtcoursier.Structure._
import sbt.librarymanagement.{Artifact => _, Configuration => _, _}
import sbt.Def
import sbt.Keys._
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 = FromSbt.sbtCrossVersionName(
artifact.name,
projId.crossVersion,
sv,
sbv
)
Publication(
name,
Type(artifact.`type`),
Extension(artifact.extension),
artifact.classifier.fold(Classifier.empty)(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
}
def artifactsTask(
withClassifiers: Boolean,
sbtClassifiers: Boolean = false,

View File

@ -4,8 +4,7 @@ import java.io.OutputStreamWriter
import coursier.{Cache, CachePolicy, TermDisplay}
import coursier.core.{Configuration, ResolutionProcess}
import coursier.lmcoursier.SbtCoursierCache
import sbt.librarymanagement.{Configuration => _, Resolver => _, _}
import coursier.sbtcoursiershared.SbtCoursierShared
import sbt.{Cache => _, Configuration => _, _}
import sbt.Keys._
@ -13,7 +12,7 @@ object CoursierPlugin extends AutoPlugin {
override def trigger = allRequirements
override def requires = sbt.plugins.JvmPlugin
override def requires = SbtCoursierShared
object autoImport {
val coursierParallelDownloads = Keys.coursierParallelDownloads
@ -22,21 +21,12 @@ object CoursierPlugin extends AutoPlugin {
val coursierArtifactsChecksums = Keys.coursierArtifactsChecksums
val coursierCachePolicies = Keys.coursierCachePolicies
val coursierTtl = Keys.coursierTtl
val coursierKeepPreloaded = Keys.coursierKeepPreloaded
val coursierVerbosity = Keys.coursierVerbosity
val mavenProfiles = Keys.mavenProfiles
val coursierResolvers = Keys.coursierResolvers
val coursierReorderResolvers = Keys.coursierReorderResolvers
val coursierRecursiveResolvers = Keys.coursierRecursiveResolvers
val coursierSbtResolvers = Keys.coursierSbtResolvers
val coursierUseSbtCredentials = Keys.coursierUseSbtCredentials
val coursierCredentials = Keys.coursierCredentials
val coursierFallbackDependencies = Keys.coursierFallbackDependencies
val coursierCache = Keys.coursierCache
val coursierProject = Keys.coursierProject
val coursierConfigGraphs = Keys.coursierConfigGraphs
val coursierInterProjectDependencies = Keys.coursierInterProjectDependencies
val coursierPublications = Keys.coursierPublications
val coursierSbtClassifiersModule = Keys.coursierSbtClassifiersModule
val coursierConfigurations = Keys.coursierConfigurations
@ -79,21 +69,6 @@ object CoursierPlugin extends AutoPlugin {
}.evaluated
)
def makeIvyXmlBefore[T](
task: TaskKey[T],
shadedConfigOpt: Option[(String, Configuration)]
): Setting[Task[T]] =
task := task.dependsOn(Def.task {
val currentProject = {
val proj = coursierProject.value
val publications = coursierPublications.value
proj.copy(publications = publications)
}
IvyXml.writeFiles(currentProject, shadedConfigOpt, ivySbt.value, streams.value.log)
}).value
private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots"
// 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
@ -162,47 +137,8 @@ object CoursierPlugin extends AutoPlugin {
)
def coursierSettings(
shadedConfigOpt: Option[(String, Configuration)],
packageConfigs: Seq[(sbt.Configuration, Configuration)]
) = hackHack ++ Seq(
clean := {
val noWarningPlz = clean.value
SbtCoursierCache.default.clear()
},
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 (coursierKeepPreloaded.value)
resolvers0
else
resolvers0.filter { r =>
!r.name.startsWith("local-preloaded")
}
},
coursierFallbackDependencies := InputsTasks.coursierFallbackDependenciesTask.value,
shadedConfigOpt: Option[(String, Configuration)] = None
): Seq[Setting[_]] = hackHack ++ Seq(
coursierArtifacts := ArtifactsTasks.artifactsTask(withClassifiers = false).value,
coursierSignedArtifacts := ArtifactsTasks.artifactsTask(withClassifiers = false, includeSignatures = true).value,
coursierClassifiersArtifacts := ArtifactsTasks.artifactsTask(
@ -227,10 +163,7 @@ object CoursierPlugin extends AutoPlugin {
sbtClassifiers = true,
ignoreArtifactErrors = true
).value,
coursierProject := InputsTasks.coursierProjectTask.value,
coursierConfigGraphs := InputsTasks.ivyGraphsTask.value,
coursierInterProjectDependencies := InputsTasks.coursierInterProjectDependenciesTask.value,
coursierPublications := ArtifactsTasks.coursierPublicationsTask(packageConfigs: _*).value,
coursierSbtClassifiersModule := classifiersModule.in(updateSbtClassifiers).value,
coursierConfigurations := InputsTasks.coursierConfigurationsTask(None).value,
coursierParentProjectCache := InputsTasks.parentProjectCacheTask.value,
@ -251,51 +184,8 @@ object CoursierPlugin extends AutoPlugin {
},
coursierSbtClassifiersResolution := ResolutionTasks.resolutionsTask(
sbtClassifiers = true
).value.head._2,
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
},
// Tests artifacts from Maven repositories are given this type.
// Adding it here so that these work straightaway.
classpathTypes += "test-jar"
) ++
(needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt))
).value.head._2
)
override lazy val buildSettings = super.buildSettings ++ Seq(
coursierParallelDownloads := 6,
@ -309,28 +199,11 @@ object CoursierPlugin extends AutoPlugin {
coursierUseSbtCredentials := true,
coursierCredentials := Map.empty,
coursierCache := Cache.default,
coursierReorderResolvers := true,
coursierKeepPreloaded := false,
coursierCreateLogger := { () => new TermDisplay(new OutputStreamWriter(System.err)) }
)
override lazy val projectSettings = coursierSettings(None, Seq(Compile, Test).map(c => c -> Configuration(c.name))) ++
override lazy val projectSettings = coursierSettings() ++
inConfig(Compile)(treeSettings) ++
inConfig(Test)(treeSettings)
private lazy val needsIvyXmlLocal = Seq(publishLocalConfiguration) ++ getPubConf("makeIvyXmlLocalConfiguration")
private lazy val needsIvyXml = Seq(publishConfiguration) ++ getPubConf("makeIvyXmlConfiguration")
private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
try {
val cls = Keys.getClass
val m = cls.getMethod(method)
val task = m.invoke(Keys).asInstanceOf[TaskKey[PublishConfiguration]]
List(task)
} catch {
case _: Throwable => // FIXME Too wide
Nil
}
}

View File

@ -3,6 +3,7 @@ package coursier.sbtcoursier
import coursier.core._
import coursier.lmcoursier._
import coursier.sbtcoursier.Keys._
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
import coursier.util.Print.Colors
import coursier.util.{Parse, Print}
import sbt.Def

View File

@ -6,71 +6,14 @@ import coursier.ProjectCache
import coursier.core._
import coursier.lmcoursier._
import coursier.sbtcoursier.Keys._
import coursier.sbtcoursier.Structure._
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
import coursier.sbtcoursiershared.Structure._
import sbt.librarymanagement.{Configuration => _, _}
import sbt.Def
import sbt.Keys._
object InputsTasks {
def coursierFallbackDependenciesTask: Def.Initialize[sbt.Task[Seq[(Module, String, URL, Boolean)]]] =
Def.taskDyn {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projects = Structure.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)
)
}
}
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 {
Inputs.coursierProject(
projectID.in(projectRef).get(state),
allDependenciesTask.value,
excludeDependencies.in(projectRef).get(state),
// should projectID.configurations be used instead?
ivyConfigurations.in(projectRef).get(state),
scalaVersion.in(projectRef).get(state),
scalaBinaryVersion.in(projectRef).get(state),
state.log
)
}
}
def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] =
Def.taskDyn {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projects = Structure.allRecursiveInterDependencies(state, projectRef)
val t = coursierProject.forAllProjects(state, projects).map(_.values.toVector)
Def.task(t.value)
}
def coursierConfigurationsTask(
shadedConfig: Option[(String, Configuration)]
): Def.Initialize[sbt.Task[Map[Configuration, Set[Configuration]]]] =

View File

@ -17,31 +17,18 @@ object Keys {
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 coursierKeepPreloaded = SettingKey[Boolean]("coursier-keep-preloaded", "Whether to take into account sbt preloaded repositories or not")
val coursierCreateLogger = TaskKey[() => Cache.Logger]("coursier-create-logger")
val coursierVerbosity = SettingKey[Int]("coursier-verbosity")
val mavenProfiles = SettingKey[Set[String]]("maven-profiles")
val coursierReorderResolvers = SettingKey[Boolean](
"coursier-reorder-resolvers",
"Whether resolvers should be re-ordered so that typically slow ones are given a lower priority"
)
val coursierResolvers = TaskKey[Seq[Resolver]]("coursier-resolvers")
val coursierRecursiveResolvers = TaskKey[Seq[Resolver]]("coursier-recursive-resolvers", "Resolvers of the current project, plus those of all from its inter-dependency projects")
val coursierSbtResolvers = TaskKey[Seq[Resolver]]("coursier-sbt-resolvers")
val coursierUseSbtCredentials = SettingKey[Boolean]("coursier-use-sbt-credentials")
val coursierCredentials = TaskKey[Map[String, Credentials]]("coursier-credentials")
val coursierCache = SettingKey[File]("coursier-cache")
val coursierFallbackDependencies = TaskKey[Seq[(Module, String, URL, Boolean)]]("coursier-fallback-dependencies")
val coursierProject = TaskKey[Project]("coursier-project")
val coursierConfigGraphs = TaskKey[Seq[Set[Configuration]]]("coursier-config-graphs")
val coursierInterProjectDependencies = TaskKey[Seq[Project]]("coursier-inter-project-dependencies", "Projects the current project depends on, possibly transitively")
val coursierPublications = TaskKey[Seq[(Configuration, Publication)]]("coursier-publications")
val coursierSbtClassifiersModule = TaskKey[GetClassifiersModule]("coursier-sbt-classifiers-module")

View File

@ -9,6 +9,7 @@ import coursier.ivy.IvyRepository
import coursier.lmcoursier._
import coursier.maven.MavenRepository
import coursier.sbtcoursier.Keys._
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
import sbt.Def
import sbt.Keys._
@ -20,7 +21,7 @@ object ResolutionTasks {
sbtClassifiers: Boolean = false
): Def.Initialize[sbt.Task[Map[Set[Configuration], coursier.Resolution]]] = {
val currentProjectTask: sbt.Def.Initialize[sbt.Task[(Project, Seq[(Module, String, URL, Boolean)], Seq[Set[Configuration]])]] =
val currentProjectTask: sbt.Def.Initialize[sbt.Task[(Project, Seq[FallbackDependency], Seq[Set[Configuration]])]] =
if (sbtClassifiers)
Def.task {
val sv = scalaVersion.value

View File

@ -3,6 +3,7 @@ package coursier.sbtcoursier
import coursier.core._
import coursier.lmcoursier._
import coursier.sbtcoursier.Keys._
import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._
import sbt.Def
import sbt.Keys._
import sbt.librarymanagement.UpdateReport

View File

@ -1,11 +0,0 @@
{
val pluginVersion = sys.props.getOrElse(
"plugin.version",
throw new RuntimeException(
"""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
)
)
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
}

View File

@ -11,7 +11,8 @@ object Main extends App {
.loadClass(clsName)
).toOption.nonEmpty
val classifierTest = classFound("org.jclouds.openstack.nova.functions.ParseServerFromJsonResponseTest")
val name = "org.jclouds.openstack.nova.functions.ParseServerFromJsonResponseTest"
val classifierTest = classFound(name)
assert(classifierTest, s"Couldn't find classifierTest")
assert(classifierTest, s"Couldn't find $name")
}

View File

@ -9,7 +9,7 @@ object MyPlugin extends AutoPlugin {
val FooConfig = config("foo")
override def projectSettings = Seq(
override def projectSettings = Seq[Setting[_]](
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % "1.7.0",
"ch.qos.logback" % "logback-classic" % "1.1.7"

View File

@ -2,11 +2,9 @@ scalaVersion := "2.11.8"
libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.41" from {
val f = file(sys.props("sbttest.base")) / "sbt-coursier-group-1" / "from" / "shapeless_2.11-2.3.0.jar"
val f = file("shapeless_2.11-2.3.0.jar")
if (!f.exists()) {
f.getParentFile.mkdirs()
val url0 = "https://repo1.maven.org/maven2/com/chuusai/shapeless_2.11/2.3.0/shapeless_2.11-2.3.0.jar"
sLog.value.warn(s"Fetching $url0")

View File

@ -40,5 +40,5 @@ updateSbtClassifiersCheck := {
ensureHasArtifact("org.scala-lang", "scala-library")
ensureHasArtifact("io.get-coursier", "coursier-core_" + scalaBinaryVersion.value)
ensureHasArtifact("io.get-coursier", "sbt-coursier")
ensureHasArtifact("io.get-coursier", "lm-coursier_" + scalaBinaryVersion.value)
}

View File

@ -0,0 +1,13 @@
addSbtPlugin {
val name = sys.props.getOrElse(
"plugin.name",
sys.error("plugin.name Java property not set")
)
val version = sys.props.getOrElse(
"plugin.version",
sys.error("plugin.version Java property not set")
)
"io.get-coursier" % name % version
}

Some files were not shown because too many files have changed in this diff Show More