Merge pull request #525 from coursier/topic/sbt-1.0

Cross-compile plugins for sbt 1.0.0-M5
This commit is contained in:
Alexandre Archambault 2017-05-05 15:29:28 +02:00 committed by GitHub
commit e978795e8e
41 changed files with 496 additions and 155 deletions

View File

@ -10,28 +10,42 @@ script:
# - bash <(curl -s https://codecov.io/bash) # - bash <(curl -s https://codecov.io/bash)
matrix: matrix:
include: include:
- env: TRAVIS_SCALA_VERSION=2.12.1 PUBLISH=1 - env: SCALA_VERSION=2.12.1 PUBLISH=1
os: linux os: linux
jdk: oraclejdk8 jdk: oraclejdk8
- env: TRAVIS_SCALA_VERSION=2.11.11 PUBLISH=1 - env: SCALA_VERSION=2.11.11 PUBLISH=1
os: linux os: linux
jdk: oraclejdk8 jdk: oraclejdk8
sudo: required sudo: required
services: services:
- docker - docker
- env: TRAVIS_SCALA_VERSION=2.10.6 PUBLISH=1 - env: SCALA_VERSION=2.10.6 PUBLISH=1
os: linux os: linux
jdk: oraclejdk8 jdk: oraclejdk8
sudo: required sudo: required
services: services:
- docker - docker
- env: TRAVIS_SCALA_VERSION=2.12.1 PUBLISH=1 SCALA_JS=1 - env: SCALA_VERSION=2.12.1 SBT_COURSIER=1
os: linux os: linux
jdk: oraclejdk8 jdk: oraclejdk8
- env: TRAVIS_SCALA_VERSION=2.11.11 PUBLISH=1 SCALA_JS=1 - env: SCALA_VERSION=2.12.1 SBT_SHADING=1
os: linux os: linux
jdk: oraclejdk8 jdk: oraclejdk8
- env: TRAVIS_SCALA_VERSION=2.10.6 PUBLISH=1 SCALA_JS=1 - env: SCALA_VERSION=2.10.6 SBT_COURSIER=1
os: linux
jdk: oraclejdk8
services:
- docker
- env: SCALA_VERSION=2.10.6 SBT_SHADING=1
os: linux
jdk: oraclejdk8
- env: SCALA_VERSION=2.12.1 SCALA_JS=1
os: linux
jdk: oraclejdk8
- env: SCALA_VERSION=2.11.11 SCALA_JS=1
os: linux
jdk: oraclejdk8
- env: SCALA_VERSION=2.10.6 SCALA_JS=1
os: linux os: linux
jdk: oraclejdk8 jdk: oraclejdk8
env: env:

View File

@ -24,14 +24,17 @@ install:
build_script: build_script:
- sbt ++2.11.11 clean compile coreJVM/publishLocal http-server/publishLocal - sbt ++2.11.11 clean compile coreJVM/publishLocal http-server/publishLocal
- sbt ++2.10.6 clean compile - sbt ++2.10.6 clean compile
- sbt ++2.10.6 coreJVM/publishLocal cache/publishLocal # to make the scripted tests happy - sbt ++2.12.1 coreJVM/publishLocal cache/publishLocal # to make the scripted sbt 1.0 tests happy
- sbt ++2.10.6 coreJVM/publishLocal cache/publishLocal # to make the scripted sbt 0.13 tests happy
test_script: test_script:
- ps: Start-Job -filepath .\scripts\start-it-auth-server.ps1 -ArgumentList $pwd - ps: Start-Job -filepath .\scripts\start-it-auth-server.ps1 -ArgumentList $pwd
- ps: Start-Sleep -s 15 # wait for the first server to have downloaded its dependencies - ps: Start-Sleep -s 15 # wait for the first server to have downloaded its dependencies
- ps: Start-Job -filepath .\scripts\start-it-no-listing-server.ps1 -ArgumentList $pwd - ps: Start-Job -filepath .\scripts\start-it-no-listing-server.ps1 -ArgumentList $pwd
- sbt ++2.12.1 testsJVM/test testsJVM/it:test # Would node be around for testsJS/test? - sbt ++2.12.1 testsJVM/test testsJVM/it:test # Would node be around for testsJS/test?
- sbt ++2.11.11 testsJVM/test testsJVM/it:test - sbt ++2.11.11 testsJVM/test testsJVM/it:test
- sbt ++2.10.6 testsJVM/test testsJVM/it:test sbt-coursier/scripted sbt-coursier/publishLocal sbt-shading/scripted - sbt ++2.10.6 testsJVM/test testsJVM/it:test
- sbt ++2.12.1 "sbt-coursier/scripted sbt-coursier/*" sbt-coursier/publishLocal "sbt-shading/scripted sbt-shading/*" # for sbt 1.0
- sbt ++2.10.6 "sbt-coursier/scripted sbt-coursier/*" "sbt-coursier/scripted sbt-coursier-0.13/*" sbt-coursier/publishLocal "sbt-shading/scripted sbt-shading/*" "sbt-shading/scripted sbt-shading-0.13/*" # for sbt 0.13
cache: cache:
- C:\Users\appveyor\.ivy2\cache - C:\Users\appveyor\.ivy2\cache
- C:\Users\appveyor\.m2 - C:\Users\appveyor\.m2

View File

@ -138,9 +138,48 @@ object CoursierSettings {
} }
} }
lazy val divertThingsPlugin = {
val actualSbtBinaryVersion = Def.setting(
sbtBinaryVersion.in(pluginCrossBuild).value.split('.').take(2).mkString(".")
)
val sbtPluginScalaVersions = Map(
"0.13" -> "2.10",
"1.0" -> "2.12"
)
val sbtScalaVersionMatch = Def.setting {
val sbtVer = actualSbtBinaryVersion.value
val scalaVer = scalaBinaryVersion.value
sbtPluginScalaVersions.get(sbtVer).toSeq.contains(scalaVer)
}
Seq(
baseDirectory := {
if (sbtScalaVersionMatch.value)
baseDirectory.value
else
baseDirectory.value / "dummy"
},
publish := {
if (sbtScalaVersionMatch.value)
publish.value
},
publishLocal := {
if (sbtScalaVersionMatch.value)
publishLocal.value
},
publishArtifact := {
sbtScalaVersionMatch.value && publishArtifact.value
}
)
}
lazy val plugin = lazy val plugin =
javaScalaPluginShared ++ javaScalaPluginShared ++
Publish.dontPublishIn("2.11", "2.12") ++ divertThingsPlugin ++
withScriptedTests ++ withScriptedTests ++
Seq( Seq(
scriptedLaunchOpts ++= Seq( scriptedLaunchOpts ++= Seq(
@ -150,7 +189,20 @@ object CoursierSettings {
"-Dsbttest.base=" + (sourceDirectory.value / "sbt-test").getAbsolutePath "-Dsbttest.base=" + (sourceDirectory.value / "sbt-test").getAbsolutePath
), ),
scriptedBufferLog := false, scriptedBufferLog := false,
sbtPlugin := (scalaBinaryVersion.value == "2.10"), sbtPlugin := {
scalaBinaryVersion.value match {
case "2.10" | "2.12" => true
case _ => false
}
},
scalaVersion := appConfiguration.value.provider.scalaProvider.version, // required with sbt 0.13.16-M1, to avoid cyclic references
sbtVersion := {
scalaBinaryVersion.value match {
case "2.10" => "0.13.8"
case "2.12" => "1.0.0-M5"
case _ => sbtVersion.value
}
},
resolvers ++= Seq( resolvers ++= Seq(
// added so that 2.10 artifacts of the other modules can be found by // added so that 2.10 artifacts of the other modules can be found by
// the too-naive-for-now inter-project resolver of the coursier SBT plugin // the too-naive-for-now inter-project resolver of the coursier SBT plugin

View File

@ -1 +1 @@
sbt.version=0.13.15 sbt.version=0.13.16-M1

View File

@ -0,0 +1,120 @@
package coursier
import scala.language.implicitConversions
object SbtCompatibility {
val GetClassifiersModule = sbt.GetClassifiersModule
type GetClassifiersModule = sbt.GetClassifiersModule
object SbtPomExtraProperties {
def POM_INFO_KEY_PREFIX = sbt.mavenint.SbtPomExtraProperties.POM_INFO_KEY_PREFIX
}
type MavenRepository = sbt.MavenRepository
type IvySbt = sbt.IvySbt
type Binary = sbt.CrossVersion.Binary
type Disabled = sbt.CrossVersion.Disabled.type
type Full = sbt.CrossVersion.Full
implicit class ModuleIDOps(val id: sbt.ModuleID) extends AnyVal {
def withConfigurations(configurations: Option[String]): sbt.ModuleID =
id.copy(configurations = configurations)
def withExtraAttributes(extraAttributes: Map[String, String]): sbt.ModuleID =
id.copy(extraAttributes = extraAttributes)
}
implicit class ArtifactOps(val artifact: sbt.Artifact) extends AnyVal {
def withType(`type`: String): sbt.Artifact =
artifact.copy(`type` = `type`)
def withExtension(extension: String): sbt.Artifact =
artifact.copy(extension = extension)
def withClassifier(classifier: Option[String]): sbt.Artifact =
artifact.copy(classifier = classifier)
def withUrl(url: Option[sbt.URL]): sbt.Artifact =
artifact.copy(url = url)
def withExtraAttributes(extraAttributes: Map[String, String]): sbt.Artifact =
artifact.copy(extraAttributes = extraAttributes)
}
implicit def toModuleReportOps(report: sbt.ModuleReport): sbt.ModuleReportOps =
new sbt.ModuleReportOps(report)
implicit class ConfigurationOps(val config: sbt.Configuration) extends AnyVal {
def withExtendsConfigs(extendsConfigs: Vector[sbt.Configuration]): sbt.Configuration =
config.copy(extendsConfigs = extendsConfigs.toList)
}
implicit class CallerCompanionOps(val companion: sbt.Caller.type) extends AnyVal {
def apply(
caller: sbt.ModuleID,
callerConfigurations: Vector[String],
callerExtraAttributes: Map[String, String],
isForceDependency: Boolean,
isChangingDependency: Boolean,
isTransitiveDependency: Boolean,
isDirectlyForceDependency: Boolean
): sbt.Caller =
new sbt.Caller(
caller,
callerConfigurations,
callerExtraAttributes,
isForceDependency,
isChangingDependency,
isTransitiveDependency,
isDirectlyForceDependency
)
}
implicit class ConfigurationReportCompanionOps(val companion: sbt.ConfigurationReport.type) extends AnyVal {
def apply(
configuration: String,
modules: Seq[sbt.ModuleReport],
details: Seq[sbt.OrganizationArtifactReport]
): sbt.ConfigurationReport =
new sbt.ConfigurationReport(
configuration,
modules,
details,
Nil
)
}
implicit class UpdateReportCompanionOps(val companion: sbt.UpdateReport.type) extends AnyVal {
def apply(
cachedDescriptor: java.io.File,
configurations: Seq[sbt.ConfigurationReport],
stats: sbt.UpdateStats,
stamps: Map[java.io.File, Long]
): sbt.UpdateReport =
new sbt.UpdateReport(
cachedDescriptor,
configurations,
stats,
stamps
)
}
implicit class UpdateStatsCompanionOps(val companion: sbt.UpdateStats.type) extends AnyVal {
def apply(
resolveTime: Long,
downloadTime: Long,
downloadSize: Long,
cached: Boolean
): sbt.UpdateStats =
new sbt.UpdateStats(
resolveTime,
downloadTime,
downloadSize,
cached
)
}
implicit def configVectorToList(configs: Vector[sbt.Configuration]): List[sbt.Configuration] =
configs.toList
implicit def configListToVector(configs: List[sbt.Configuration]): Vector[sbt.Configuration] =
configs.toVector
}

View File

@ -0,0 +1,18 @@
package sbt
// put under the sbt namespace to access private[sbt] things (the copy method used below)
class ModuleReportOps(val report: sbt.ModuleReport) extends AnyVal {
def withPublicationDate(publicationDate: Option[java.util.Calendar]): sbt.ModuleReport =
report.copy(publicationDate = publicationDate.map(_.getTime))
def withHomepage(homepage: Option[String]): sbt.ModuleReport =
report.copy(homepage = homepage)
def withExtraAttributes(extraAttributes: Map[String, String]): sbt.ModuleReport =
report.copy(extraAttributes = extraAttributes)
def withConfigurations(configurations: Vector[String]): sbt.ModuleReport =
report.copy(configurations = configurations)
def withLicenses(licenses: Vector[(String, Option[String])]): sbt.ModuleReport =
report.copy(licenses = licenses)
def withCallers(callers: Vector[sbt.Caller]): sbt.ModuleReport =
report.copy(callers = callers)
}

View File

@ -0,0 +1,30 @@
package coursier
object SbtCompatibility {
val GetClassifiersModule = sbt.internal.librarymanagement.GetClassifiersModule
type GetClassifiersModule = sbt.internal.librarymanagement.GetClassifiersModule
object SbtPomExtraProperties {
def POM_INFO_KEY_PREFIX = sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties.POM_INFO_KEY_PREFIX
}
type MavenRepository = sbt.librarymanagement.MavenRepository
type IvySbt = sbt.internal.librarymanagement.IvySbt
type Binary = sbt.librarymanagement.Binary
type Disabled = sbt.librarymanagement.Disabled
type Full = sbt.librarymanagement.Full
implicit class BinaryOps(private val binary: Binary) extends AnyVal {
def remapVersion(scalaBinaryVersion: String): String =
scalaBinaryVersion
}
implicit class FullOps(private val full: Full) extends AnyVal {
def remapVersion(scalaVersion: String): String =
scalaVersion
}
}

View File

@ -3,6 +3,8 @@ package coursier
import sbt._ import sbt._
import sbt.Keys._ import sbt.Keys._
import SbtCompatibility._
object CoursierPlugin extends AutoPlugin { object CoursierPlugin extends AutoPlugin {
override def trigger = allRequirements override def trigger = allRequirements
@ -47,12 +49,12 @@ object CoursierPlugin extends AutoPlugin {
import autoImport._ import autoImport._
lazy val treeSettings = Seq( lazy val treeSettings = Seq(
coursierDependencyTree <<= Tasks.coursierDependencyTreeTask( coursierDependencyTree := Tasks.coursierDependencyTreeTask(
inverse = false inverse = false
), ).value,
coursierDependencyInverseTree <<= Tasks.coursierDependencyTreeTask( coursierDependencyInverseTree := Tasks.coursierDependencyTreeTask(
inverse = true inverse = true
) ).value
) )
def makeIvyXmlBefore[T]( def makeIvyXmlBefore[T](
@ -82,48 +84,69 @@ object CoursierPlugin extends AutoPlugin {
coursierTtl := Cache.defaultTtl, coursierTtl := Cache.defaultTtl,
coursierVerbosity := Settings.defaultVerbosityLevel(sLog.value), coursierVerbosity := Settings.defaultVerbosityLevel(sLog.value),
mavenProfiles := Set.empty, mavenProfiles := Set.empty,
coursierResolvers <<= Tasks.coursierResolversTask, coursierResolvers := Tasks.coursierResolversTask.value,
coursierRecursiveResolvers <<= Tasks.coursierRecursiveResolversTask, coursierRecursiveResolvers := Tasks.coursierRecursiveResolversTask.value,
coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers, coursierSbtResolvers := externalResolvers.in(updateSbtClassifiers).value,
coursierUseSbtCredentials := true, coursierUseSbtCredentials := true,
coursierCredentials := Map.empty, coursierCredentials := Map.empty,
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask, coursierFallbackDependencies := Tasks.coursierFallbackDependenciesTask.value,
coursierCache := Cache.default, coursierCache := Cache.default,
coursierArtifacts <<= Tasks.artifactFilesOrErrors(withClassifiers = false), coursierArtifacts := Tasks.artifactFilesOrErrors(withClassifiers = false).value,
coursierClassifiersArtifacts <<= Tasks.artifactFilesOrErrors( coursierClassifiersArtifacts := Tasks.artifactFilesOrErrors(
withClassifiers = true withClassifiers = true
), ).value,
coursierSbtClassifiersArtifacts <<= Tasks.artifactFilesOrErrors( coursierSbtClassifiersArtifacts := Tasks.artifactFilesOrErrors(
withClassifiers = true, withClassifiers = true,
sbtClassifiers = true sbtClassifiers = true
), ).value,
makeIvyXmlBefore(deliverLocalConfiguration, shadedConfigOpt), makeIvyXmlBefore(deliverLocalConfiguration, shadedConfigOpt),
makeIvyXmlBefore(deliverConfiguration, shadedConfigOpt), makeIvyXmlBefore(deliverConfiguration, shadedConfigOpt),
update <<= Tasks.updateTask( update := Tasks.updateTask(
shadedConfigOpt, shadedConfigOpt,
withClassifiers = false withClassifiers = false
), ).value,
updateClassifiers <<= Tasks.updateTask( updateClassifiers := Tasks.updateTask(
shadedConfigOpt, shadedConfigOpt,
withClassifiers = true, withClassifiers = true,
ignoreArtifactErrors = true ignoreArtifactErrors = true
), ).value,
updateSbtClassifiers in Defaults.TaskGlobal <<= Tasks.updateTask( updateSbtClassifiers.in(Defaults.TaskGlobal) := Tasks.updateTask(
shadedConfigOpt, shadedConfigOpt,
withClassifiers = true, withClassifiers = true,
sbtClassifiers = true, sbtClassifiers = true,
ignoreArtifactErrors = true ignoreArtifactErrors = true
), ).value,
coursierProject <<= Tasks.coursierProjectTask, coursierProject := Tasks.coursierProjectTask.value,
coursierInterProjectDependencies <<= Tasks.coursierInterProjectDependenciesTask, coursierInterProjectDependencies := Tasks.coursierInterProjectDependenciesTask.value,
coursierPublications <<= Tasks.coursierPublicationsTask(packageConfigs: _*), coursierPublications := Tasks.coursierPublicationsTask(packageConfigs: _*).value,
coursierSbtClassifiersModule <<= classifiersModule in updateSbtClassifiers, coursierSbtClassifiersModule := classifiersModule.in(updateSbtClassifiers).value,
coursierConfigurations <<= Tasks.coursierConfigurationsTask(None), coursierConfigurations := Tasks.coursierConfigurationsTask(None).value,
coursierParentProjectCache <<= Tasks.parentProjectCacheTask, coursierParentProjectCache := Tasks.parentProjectCacheTask.value,
coursierResolution <<= Tasks.resolutionTask(), coursierResolution := Tasks.resolutionTask().value,
coursierSbtClassifiersResolution <<= Tasks.resolutionTask( coursierSbtClassifiersResolution := Tasks.resolutionTask(
sbtClassifiers = true sbtClassifiers = true
) ).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(Configuration("sources", "", isPublic = true, extendsConfigs = Vector.empty, transitive = false))
val extraDocs =
if (names("docs"))
None
else
Some(Configuration("docs", "", isPublic = true, extendsConfigs = Vector.empty, transitive = false))
confs ++ extraSources.toSeq ++ extraDocs.toSeq
}
) )
override lazy val projectSettings = coursierSettings(None, Seq(Compile, Test).map(c => c -> c.name)) ++ override lazy val projectSettings = coursierSettings(None, Seq(Compile, Test).map(c => c -> c.name)) ++

View File

@ -2,12 +2,12 @@ package coursier
import coursier.ivy.IvyRepository import coursier.ivy.IvyRepository
import coursier.ivy.IvyXml.{mappings => ivyXmlMappings} import coursier.ivy.IvyXml.{mappings => ivyXmlMappings}
import java.net.{MalformedURLException, URL} import java.net.{MalformedURLException, URL}
import coursier.core.Authentication import coursier.core.Authentication
import sbt.{ Resolver, CrossVersion, ModuleID } import sbt.{CrossVersion, ModuleID, Resolver}
import sbt.mavenint.SbtPomExtraProperties
import SbtCompatibility._
object FromSbt { object FromSbt {
@ -24,9 +24,9 @@ object FromSbt {
scalaVersion: => String, scalaVersion: => String,
scalaBinaryVersion: => String scalaBinaryVersion: => String
): String = crossVersion match { ): String = crossVersion match {
case CrossVersion.Disabled => name case _: Disabled => name
case f: CrossVersion.Full => name + "_" + f.remapVersion(scalaVersion) case f: Full => name + "_" + f.remapVersion(scalaVersion)
case f: CrossVersion.Binary => name + "_" + f.remapVersion(scalaBinaryVersion) case b: Binary => name + "_" + b.remapVersion(scalaBinaryVersion)
} }
def attributes(attr: Map[String, String]): Map[String, String] = def attributes(attr: Map[String, String]): Map[String, String] =
@ -178,20 +178,20 @@ object FromSbt {
authentication: Option[Authentication] authentication: Option[Authentication]
): Option[Repository] = ): Option[Repository] =
resolver match { resolver match {
case sbt.MavenRepository(_, root) => case r: SbtCompatibility.MavenRepository =>
mavenRepositoryOpt(root, log, authentication) mavenRepositoryOpt(r.root, log, authentication)
case sbt.FileRepository(_, _, patterns) case r: sbt.FileRepository
if patterns.ivyPatterns.lengthCompare(1) == 0 && if r.patterns.ivyPatterns.lengthCompare(1) == 0 &&
patterns.artifactPatterns.lengthCompare(1) == 0 => r.patterns.artifactPatterns.lengthCompare(1) == 0 =>
val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(patterns) val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns)
mavenCompatibleBaseOpt0 match { mavenCompatibleBaseOpt0 match {
case None => case None =>
Some(IvyRepository( Some(IvyRepository(
"file://" + patterns.artifactPatterns.head, "file://" + r.patterns.artifactPatterns.head,
metadataPatternOpt = Some("file://" + patterns.ivyPatterns.head), metadataPatternOpt = Some("file://" + r.patterns.ivyPatterns.head),
changing = Some(true), changing = Some(true),
properties = ivyProperties, properties = ivyProperties,
dropInfoAttributes = true, dropInfoAttributes = true,
@ -201,17 +201,17 @@ object FromSbt {
mavenRepositoryOpt("file://" + mavenCompatibleBase, log, authentication) mavenRepositoryOpt("file://" + mavenCompatibleBase, log, authentication)
} }
case sbt.URLRepository(_, patterns) case r: sbt.URLRepository
if patterns.ivyPatterns.lengthCompare(1) == 0 && if r.patterns.ivyPatterns.lengthCompare(1) == 0 &&
patterns.artifactPatterns.lengthCompare(1) == 0 => r.patterns.artifactPatterns.lengthCompare(1) == 0 =>
val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(patterns) val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns)
mavenCompatibleBaseOpt0 match { mavenCompatibleBaseOpt0 match {
case None => case None =>
Some(IvyRepository( Some(IvyRepository(
patterns.artifactPatterns.head, r.patterns.artifactPatterns.head,
metadataPatternOpt = Some(patterns.ivyPatterns.head), metadataPatternOpt = Some(r.patterns.ivyPatterns.head),
changing = None, changing = None,
properties = ivyProperties, properties = ivyProperties,
dropInfoAttributes = true, dropInfoAttributes = true,

View File

@ -6,13 +6,15 @@ import org.apache.ivy.core.module.id.ModuleRevisionId
import scala.collection.JavaConverters._ import scala.collection.JavaConverters._
import scala.xml.{Node, PrefixedAttribute} import scala.xml.{Node, PrefixedAttribute}
import SbtCompatibility._
object IvyXml { object IvyXml {
// These are required for publish to be fine, later on. // These are required for publish to be fine, later on.
def writeFiles( def writeFiles(
currentProject: Project, currentProject: Project,
shadedConfigOpt: Option[(String, String)], shadedConfigOpt: Option[(String, String)],
ivySbt: sbt.IvySbt, ivySbt: IvySbt,
log: sbt.Logger log: sbt.Logger
): Unit = { ): Unit = {

View File

@ -4,12 +4,13 @@ import java.io.File
import java.net.URL import java.net.URL
import coursier.core.Publication import coursier.core.Publication
import sbt.{Resolver, SettingKey, TaskKey}
import sbt.{ GetClassifiersModule, Resolver, SettingKey, TaskKey }
import scala.concurrent.duration.Duration import scala.concurrent.duration.Duration
import scalaz.\/ import scalaz.\/
import SbtCompatibility._
object Keys { object Keys {
val coursierParallelDownloads = SettingKey[Int]("coursier-parallel-downloads") val coursierParallelDownloads = SettingKey[Int]("coursier-parallel-downloads")
val coursierMaxIterations = SettingKey[Int]("coursier-max-iterations") val coursierMaxIterations = SettingKey[Int]("coursier-max-iterations")

View File

@ -7,7 +7,7 @@ import scala.language.implicitConversions
// things from sbt-structure // things from sbt-structure
object Structure { object Structure {
def structure(state: State): BuildStructure = def structure(state: State) =
sbt.Project.structure(state) sbt.Project.structure(state)
implicit class `enrich SettingKey`[T](key: SettingKey[T]) { implicit class `enrich SettingKey`[T](key: SettingKey[T]) {

View File

@ -146,9 +146,7 @@ object Tasks {
allDependencies <- allDependenciesTask allDependencies <- allDependenciesTask
} yield { } yield {
val configMap = configurations val configMap = configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap
.map { cfg => cfg.name -> cfg.extendsConfigs.map(_.name) }
.toMap
val proj = FromSbt.project( val proj = FromSbt.project(
projId, projId,
@ -178,15 +176,29 @@ object Tasks {
coursierProject.forAllProjects(state, projects).map(_.values.toVector) coursierProject.forAllProjects(state, projects).map(_.values.toVector)
} }
def coursierPublicationsTask(configsMap: (sbt.Configuration, String)*): Def.Initialize[sbt.Task[Seq[(String, Publication)]]] = def coursierPublicationsTask(
( configsMap: (sbt.Configuration, String)*
sbt.Keys.state, ): Def.Initialize[sbt.Task[Seq[(String, Publication)]]] =
sbt.Keys.thisProjectRef, Def.task {
sbt.Keys.projectID,
sbt.Keys.scalaVersion, val state = sbt.Keys.state.value
sbt.Keys.scalaBinaryVersion, val projectRef = sbt.Keys.thisProjectRef.value
sbt.Keys.ivyConfigurations val projId = sbt.Keys.projectID.value
).map { (state, projectRef, projId, sv, sbv, ivyConfs) => 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("sources")
else
None
val docsConfigOpt =
if (ivyConfigurations.value.exists(_.name == "docs"))
Some("docs")
else
None
val sbtBinArtifacts = val sbtBinArtifacts =
for ((config, targetConfig) <- configsMap) yield { for ((config, targetConfig) <- configsMap) yield {
@ -209,7 +221,7 @@ object Tasks {
} }
val sbtSourceArtifacts = val sbtSourceArtifacts =
for ((config, _) <- configsMap) yield { for ((config, targetConfig) <- configsMap) yield {
val publish = publishArtifact val publish = publishArtifact
.in(projectRef) .in(projectRef)
@ -223,13 +235,13 @@ object Tasks {
.in(packageSrc) .in(packageSrc)
.in(config) .in(config)
.find(state) .find(state)
.map("sources" -> _) .map(sourcesConfigOpt.getOrElse(targetConfig) -> _)
else else
None None
} }
val sbtDocArtifacts = val sbtDocArtifacts =
for ((config, _) <- configsMap) yield { for ((config, targetConfig) <- configsMap) yield {
val publish = publishArtifact val publish = publishArtifact
.in(projectRef) .in(projectRef)
@ -243,7 +255,7 @@ object Tasks {
.in(packageDoc) .in(packageDoc)
.in(config) .in(config)
.find(state) .find(state)
.map("docs" -> _) .map(docsConfigOpt.getOrElse(targetConfig) -> _)
else else
None None
} }
@ -418,7 +430,7 @@ object Tasks {
def resolutionTask( def resolutionTask(
sbtClassifiers: Boolean = false sbtClassifiers: Boolean = false
) = Def.task { ): Def.Initialize[sbt.Task[coursier.Resolution]] = Def.task {
// let's update only one module at once, for a better output // let's update only one module at once, for a better output
// Downloads are already parallel, no need to parallelize further anyway // Downloads are already parallel, no need to parallelize further anyway

View File

@ -7,6 +7,8 @@ import coursier.maven.MavenSource
import sbt._ import sbt._
import SbtCompatibility._
object ToSbt { object ToSbt {
private def caching[K, V](f: K => V): K => V = { private def caching[K, V](f: K => V): K => V = {
@ -28,26 +30,28 @@ object ToSbt {
sbt.ModuleID( sbt.ModuleID(
dependency.module.organization, dependency.module.organization,
dependency.module.name, dependency.module.name,
dependency.version, dependency.version
configurations = Some(dependency.configuration), ).withConfigurations(
extraAttributes = dependency.module.attributes ++ extraProperties Some(dependency.configuration)
).withExtraAttributes(
dependency.module.attributes ++ extraProperties
) )
} }
val artifact = caching[(Module, Map[String, String], Artifact), sbt.Artifact] { val artifact = caching[(Module, Map[String, String], Artifact), sbt.Artifact] {
case (module, extraProperties, artifact) => case (module, extraProperties, artifact) =>
sbt.Artifact( sbt.Artifact(module.name)
module.name,
// FIXME Get these two from publications // FIXME Get these two from publications
artifact.attributes.`type`, .withType(artifact.attributes.`type`)
MavenSource.typeExtension(artifact.attributes.`type`), .withExtension(MavenSource.typeExtension(artifact.attributes.`type`))
.withClassifier(
Some(artifact.attributes.classifier) Some(artifact.attributes.classifier)
.filter(_.nonEmpty) .filter(_.nonEmpty)
.orElse(MavenSource.typeDefaultClassifierOpt(artifact.attributes.`type`)), .orElse(MavenSource.typeDefaultClassifierOpt(artifact.attributes.`type`))
Nil,
Some(url(artifact.url)),
module.attributes ++ extraProperties
) )
// .withConfigurations(Vector())
.withUrl(Some(url(artifact.url)))
.withExtraAttributes(module.attributes ++ extraProperties)
} }
val moduleReport = caching[(Dependency, Seq[(Dependency, Project)], Project, Seq[(Artifact, Option[File])]), sbt.ModuleReport] { val moduleReport = caching[(Dependency, Seq[(Dependency, Project)], Project, Seq[(Artifact, Option[File])]), sbt.ModuleReport] {
@ -63,12 +67,12 @@ object ToSbt {
} }
val publicationDate = project.info.publication.map { dt => val publicationDate = project.info.publication.map { dt =>
new GregorianCalendar(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second).getTime new GregorianCalendar(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
} }
val callers = dependees.map { val callers = dependees.map {
case (dependee, dependeeProj) => case (dependee, dependeeProj) =>
new Caller( Caller(
ToSbt.moduleId(dependee, dependeeProj.properties.toMap), ToSbt.moduleId(dependee, dependeeProj.properties.toMap),
dependeeProj.configurations.keys.toVector, dependeeProj.configurations.keys.toVector,
dependee.module.attributes ++ dependeeProj.properties, dependee.module.attributes ++ dependeeProj.properties,
@ -80,26 +84,26 @@ object ToSbt {
) )
} }
new sbt.ModuleReport( sbt.ModuleReport(
module = ToSbt.moduleId(dependency, project.properties.toMap), ToSbt.moduleId(dependency, project.properties.toMap),
artifacts = sbtArtifacts, sbtArtifacts.toVector,
missingArtifacts = sbtMissingArtifacts, sbtMissingArtifacts.toVector
status = None,
publicationDate = publicationDate,
resolver = None,
artifactResolver = None,
evicted = false,
evictedData = None,
evictedReason = None,
problem = None,
homepage = Some(project.info.homePage).filter(_.nonEmpty),
extraAttributes = dependency.module.attributes ++ project.properties,
isDefault = None,
branch = None,
configurations = project.configurations.keys.toVector,
licenses = project.info.licenses,
callers = callers
) )
// .withStatus(None)
.withPublicationDate(publicationDate)
// .withResolver(None)
// .withArtifactResolver(None)
// .withEvicted(false)
// .withEvictedData(None)
// .withEvictedReason(None)
// .withProblem(None)
.withHomepage(Some(project.info.homePage).filter(_.nonEmpty))
.withExtraAttributes(dependency.module.attributes ++ project.properties)
// .withIsDefault(None)
// .withBranch(None)
.withConfigurations(project.configurations.keys.toVector)
.withLicenses(project.info.licenses.toVector)
.withCallers(callers.toVector)
} }
private def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] = private def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] =
@ -190,18 +194,17 @@ object ToSbt {
val reports = ToSbt.moduleReports(subRes, classifiersOpt, artifactFileOpt, keepPomArtifact) val reports = ToSbt.moduleReports(subRes, classifiersOpt, artifactFileOpt, keepPomArtifact)
new ConfigurationReport( ConfigurationReport(
config, config,
reports.toVector, reports.toVector,
Nil, Vector()
Nil
) )
} }
new UpdateReport( UpdateReport(
null, null,
configReports.toVector, configReports.toVector,
new UpdateStats(-1L, -1L, -1L, cached = false), UpdateStats(-1L, -1L, -1L, cached = false),
Map.empty Map.empty
) )
} }

View File

@ -1,3 +1,7 @@
// for SbtExclusionRule with sbt 1.0
import sbt.internal.librarymanagement._
scalaVersion := "2.11.8" scalaVersion := "2.11.8"
organization := "io.get-coursier.test" organization := "io.get-coursier.test"

View File

@ -0,0 +1,8 @@
package sbt.internal.librarymanagement
// dummy object, to be able to do
// import sbt.internal.librarymanagement._
// from build.sbt, even in 0.13
// That import is required in 1.0 for SbtExclusionRule
object Dummy

View File

@ -16,7 +16,9 @@ resolvers += Resolver.url(
Patterns( Patterns(
Resolver.ivyStylePatterns.ivyPatterns, Resolver.ivyStylePatterns.ivyPatterns,
Resolver.ivyStylePatterns.artifactPatterns, Resolver.ivyStylePatterns.artifactPatterns,
isMavenCompatible = true isMavenCompatible = true,
descriptorOptional = false,
skipConsistencyCheck = false
) )
) )

View File

@ -57,10 +57,22 @@ lazy val shared = Seq(
val compileDocArtifacts = artifacts("compile", Some("javadoc")) val compileDocArtifacts = artifacts("compile", Some("javadoc"))
val docArtifacts = artifacts("compile", Some("javadoc"), useClassifiersReport = true) val docArtifacts = artifacts("compile", Some("javadoc"), useClassifiersReport = true)
assert(compileSourceArtifacts.isEmpty) assert(
assert(sourceArtifacts.length == 2) compileSourceArtifacts.isEmpty,
assert(compileDocArtifacts.isEmpty) "Expected no source artifact in main update report"
assert(docArtifacts.length == 2) )
assert(
sourceArtifacts.length == 2,
"Expected 2 source artifacts in classifier report"
)
assert(
compileDocArtifacts.isEmpty,
"Expected no doc artifact in main update report"
)
assert(
docArtifacts.length == 2,
"Expected 2 doc artifacts in classifier report"
)
} }
) )

View File

@ -6,6 +6,8 @@ import coursier.ivy.IvyXml.{mappings => ivyXmlMappings}
import sbt.Keys._ import sbt.Keys._
import sbt.{AutoPlugin, Compile, Configuration, TaskKey, inConfig} import sbt.{AutoPlugin, Compile, Configuration, TaskKey, inConfig}
import SbtCompatibility._
object ShadingPlugin extends AutoPlugin { object ShadingPlugin extends AutoPlugin {
override def trigger = noTrigger override def trigger = noTrigger
@ -13,10 +15,10 @@ object ShadingPlugin extends AutoPlugin {
override def requires = sbt.plugins.IvyPlugin override def requires = sbt.plugins.IvyPlugin
private val baseSbtConfiguration = Compile private val baseSbtConfiguration = Compile
val Shading = Configuration("shading", "", isPublic = false, List(baseSbtConfiguration), transitive = true) val Shading = Configuration("shading", "", isPublic = false, Vector(baseSbtConfiguration), transitive = true)
private val baseDependencyConfiguration = "compile" private val baseDependencyConfiguration = "compile"
val Shaded = Configuration("shaded", "", isPublic = true, List(), transitive = true) val Shaded = Configuration("shaded", "", isPublic = true, Vector(), transitive = true)
// make that a setting? // make that a setting?
val shadingNamespace = TaskKey[String]("shading-namespace") val shadingNamespace = TaskKey[String]("shading-namespace")
@ -53,17 +55,17 @@ object ShadingPlugin extends AutoPlugin {
lazy val shadingDefaultArtifactTasks = lazy val shadingDefaultArtifactTasks =
makePom +: Seq(packageBin, packageSrc, packageDoc).map(_.in(Shading)) makePom +: Seq(packageBin, packageSrc, packageDoc).map(_.in(Shading))
lazy val shadingJvmPublishSettings = Seq( lazy val shadingJvmPublishSettings = Seq(
artifacts <<= sbt.Classpaths.artifactDefs(shadingDefaultArtifactTasks), artifacts := sbt.Classpaths.artifactDefs(shadingDefaultArtifactTasks).value,
packagedArtifacts <<= sbt.Classpaths.packaged(shadingDefaultArtifactTasks) packagedArtifacts := sbt.Classpaths.packaged(shadingDefaultArtifactTasks).value
) )
import CoursierPlugin.autoImport._ import CoursierPlugin.autoImport._
override lazy val projectSettings = override lazy val projectSettings =
Seq( Seq(
coursierConfigurations <<= Tasks.coursierConfigurationsTask( coursierConfigurations := Tasks.coursierConfigurationsTask(
Some(baseDependencyConfiguration -> Shaded.name) Some(baseDependencyConfiguration -> Shaded.name)
), ).value,
ivyConfigurations := Shaded +: ivyConfigurations.value.map { ivyConfigurations := Shaded +: ivyConfigurations.value.map {
conf => conf =>
if (conf.name == "compile") if (conf.name == "compile")
@ -87,7 +89,7 @@ object ShadingPlugin extends AutoPlugin {
configuration := baseSbtConfiguration, // wuw configuration := baseSbtConfiguration, // wuw
ivyConfigurations := ivyConfigurations.in(baseSbtConfiguration).value ivyConfigurations := ivyConfigurations.in(baseSbtConfiguration).value
.filter(_.name != Shaded.name) .filter(_.name != Shaded.name)
.map(c => c.copy(extendsConfigs = c.extendsConfigs.filter(_.name != Shaded.name))), .map(c => c.withExtendsConfigs(c.extendsConfigs.filter(_.name != Shaded.name))),
libraryDependencies := libraryDependencies.in(baseSbtConfiguration).value.filter { dep => libraryDependencies := libraryDependencies.in(baseSbtConfiguration).value.filter { dep =>
val isShaded = dep.configurations.exists { mappings => val isShaded = dep.configurations.exists { mappings =>
ivyXmlMappings(mappings).exists(_._1 == Shaded.name) ivyXmlMappings(mappings).exists(_._1 == Shaded.name)

View File

@ -1,4 +1,7 @@
// for SbtExclusionRule with sbt 1.0
import sbt.internal.librarymanagement._
enablePlugins(coursier.ShadingPlugin) enablePlugins(coursier.ShadingPlugin)
shadingNamespace := "test.shaded" shadingNamespace := "test.shaded"
shadeNamespaces += "argonaut" shadeNamespaces += "argonaut"

View File

@ -0,0 +1,8 @@
package sbt.internal.librarymanagement
// dummy object, to be able to do
// import sbt.internal.librarymanagement._
// from build.sbt, even in 0.13
// That import is required in 1.0 for SbtExclusionRule
object Dummy

View File

@ -1,10 +1,10 @@
#!/bin/bash #!/bin/bash
set -ev set -ev
TRAVIS_SCALA_VERSION="$1" SCALA_VERSION="$1"
shift shift
sbt ++${TRAVIS_SCALA_VERSION} web/fastOptJS sbt ++${SCALA_VERSION} web/fastOptJS
HELPER="$(readlink -f "$(dirname "$0")/push-gh-pages-helper.sh")" HELPER="$(readlink -f "$(dirname "$0")/push-gh-pages-helper.sh")"

View File

@ -54,6 +54,14 @@ isScalaJs() {
[ "$SCALA_JS" = 1 ] [ "$SCALA_JS" = 1 ]
} }
sbtCoursier() {
[ "$SBT_COURSIER" = 1 ]
}
sbtShading() {
[ "$SBT_SHADING" = 1 ]
}
is210() { is210() {
echo "$SCALA_VERSION" | grep -q "^2\.10" echo "$SCALA_VERSION" | grep -q "^2\.10"
} }
@ -62,12 +70,22 @@ is211() {
echo "$SCALA_VERSION" | grep -q "^2\.11" echo "$SCALA_VERSION" | grep -q "^2\.11"
} }
is212() {
echo "$SCALA_VERSION" | grep -q "^2\.12"
}
runSbtCoursierTests() { runSbtCoursierTests() {
sbt ++$SCALA_VERSION coreJVM/publishLocal cache/publishLocal sbt-coursier/scripted sbt ++$SCALA_VERSION coreJVM/publishLocal cache/publishLocal "sbt-coursier/scripted sbt-coursier/*"
if [ "$SCALA_VERSION" = "2.10" ]; then
sbt ++$SCALA_VERSION "sbt-coursier/scripted sbt-coursier-0.13/*"
fi
} }
runSbtShadingTests() { runSbtShadingTests() {
sbt ++$SCALA_VERSION sbt-coursier/publishLocal sbt-shading/scripted sbt ++$SCALA_VERSION coreJVM/publishLocal cache/publishLocal sbt-coursier/publishLocal "sbt-shading/scripted sbt-shading/*"
if [ "$SCALA_VERSION" = "2.10" ]; then
sbt ++$SCALA_VERSION "sbt-shading/scripted sbt-shading-0.13/*"
fi
} }
jsCompile() { jsCompile() {
@ -172,27 +190,33 @@ if isScalaJs; then
else else
integrationTestsRequirements integrationTestsRequirements
jvmCompile jvmCompile
runJvmTests
if is210; then if sbtCoursier; then
if is210 || is212; then
runSbtCoursierTests runSbtCoursierTests
runSbtShadingTests
fi
validateReadme
checkBinaryCompatibility
# We're not using a jdk6 matrix entry with Travis here as some sources of coursier require Java 7 to compile
# (even though it won't try to call Java 7 specific methods if it detects it runs under Java 6).
# The tests here check that coursier is nonetheless fine when run under Java 6.
if is211; then
testLauncherJava6
fi fi
if is210; then if is210; then
testSbtCoursierJava6 testSbtCoursierJava6
fi fi
elif sbtShading; then
if is210 || is212; then
runSbtShadingTests
fi
else
runJvmTests
validateReadme
checkBinaryCompatibility
if is211; then
testLauncherJava6
fi
fi
# Not using a jdk6 matrix entry with Travis as some sources of coursier require Java 7 to compile
# (even though it won't try to call Java 7 specific methods if it detects it runs under Java 6).
# The tests here check that coursier is nonetheless fine when run under Java 6.
fi fi