mirror of https://github.com/sbt/sbt.git
rework cross versioning to account for prerelease Scala versions
This commit is contained in:
parent
2255bd5a62
commit
5e155900da
|
|
@ -0,0 +1,94 @@
|
|||
package sbt
|
||||
|
||||
final case class ScalaVersion(full: String, binary: String)
|
||||
|
||||
sealed trait CrossVersion
|
||||
object CrossVersion
|
||||
{
|
||||
val TransitionScalaVersion = "2.10"
|
||||
val TransitionSbtVersion = "0.12"
|
||||
|
||||
object Disabled extends CrossVersion { override def toString = "disabled" }
|
||||
final class Binary(val remapVersion: String => String) extends CrossVersion {
|
||||
override def toString = "Binary"
|
||||
}
|
||||
final class Full(val remapVersion: String => String) extends CrossVersion {
|
||||
override def toString = "Full"
|
||||
}
|
||||
|
||||
def full: CrossVersion = new Full(idFun)
|
||||
def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion)
|
||||
|
||||
def binary: CrossVersion = new Binary(idFun)
|
||||
def binaryMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion)
|
||||
|
||||
private[this] def idFun[T]: T => T = x => x
|
||||
def append(s: String): Option[String => String] = Some(x => crossName(x, s))
|
||||
|
||||
def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] =
|
||||
cross match
|
||||
{
|
||||
case Disabled => None
|
||||
case b: Binary => append(b.remapVersion(binaryVersion))
|
||||
case f: Full => append(f.remapVersion(fullVersion))
|
||||
}
|
||||
|
||||
def apply(module: ModuleID, is: IvyScala): Option[String => String] =
|
||||
CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion)
|
||||
|
||||
def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] =
|
||||
is flatMap { i => apply(module, i) }
|
||||
|
||||
def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] =
|
||||
cross match {
|
||||
case None => artifacts
|
||||
case Some(is) => substituteCrossA(artifacts, cross)
|
||||
}
|
||||
|
||||
def applyCross(s: String, fopt: Option[String => String]): String =
|
||||
fopt match {
|
||||
case None => s
|
||||
case Some(fopt) => fopt(s)
|
||||
}
|
||||
|
||||
def crossName(name: String, cross: String): String =
|
||||
name + "_" + cross
|
||||
def substituteCross(a: Artifact, cross: Option[String => String]): Artifact =
|
||||
a.copy(name = applyCross(a.name, cross))
|
||||
def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] =
|
||||
as.map(art => substituteCross(art, cross))
|
||||
|
||||
def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m =>
|
||||
{
|
||||
val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion)
|
||||
if(cross.isDefined)
|
||||
m.copy(name = applyCross(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross))
|
||||
else
|
||||
m
|
||||
}
|
||||
|
||||
def isStable(v: String): Boolean = !v.contains("-")
|
||||
def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full
|
||||
|
||||
val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r
|
||||
def partialVersion(s: String): Option[(Int,Int)] =
|
||||
s match {
|
||||
case PartialVersion(major, minor) => Some(major.toInt, minor.toInt)
|
||||
case _ => None
|
||||
}
|
||||
private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean =
|
||||
major > minMajor || (major == minMajor && minor >= minMinor)
|
||||
|
||||
def binaryScalaVersion(full: String): String = binaryVersion(full, TransitionScalaVersion)
|
||||
def binarySbtVersion(full: String): String = binaryVersion(full, TransitionSbtVersion)
|
||||
def binaryVersion(full: String, cutoff: String): String =
|
||||
{
|
||||
def sub(major: Int, minor: Int) = major + "." + minor
|
||||
(partialVersion(full), partialVersion(cutoff)) match {
|
||||
case (Some((major, minor)), None) => sub(major, minor)
|
||||
case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor)
|
||||
case _ => full
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,21 +27,28 @@ trait DependencyBuilders
|
|||
|
||||
final class GroupID private[sbt] (groupID: String)
|
||||
{
|
||||
def % (artifactID: String) = groupArtifact(artifactID, None)
|
||||
def %% (artifactID: String, crossVersion: String => String = identity) = groupArtifact(artifactID, Some(crossVersion))
|
||||
def %% (artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, Some(Map(alternatives: _*) orElse { case s => s }))
|
||||
private def groupArtifact(artifactID: String, cross: Option[String => String]) =
|
||||
def % (artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled)
|
||||
def %% (artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary)
|
||||
|
||||
@deprecated(deprecationMessage, "0.12.0")
|
||||
def %% (artifactID: String, crossVersion: String => String) = groupArtifact(artifactID, CrossVersion.binaryMapped(crossVersion))
|
||||
@deprecated(deprecationMessage, "0.12.0")
|
||||
def %% (artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, CrossVersion.binaryMapped(Map(alternatives: _*) orElse { case s => s }))
|
||||
|
||||
private def groupArtifact(artifactID: String, cross: CrossVersion) =
|
||||
{
|
||||
nonEmpty(artifactID, "Artifact ID")
|
||||
new GroupArtifactID(groupID, artifactID, cross)
|
||||
}
|
||||
|
||||
private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)"""
|
||||
}
|
||||
final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: Option[String => String])
|
||||
final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: CrossVersion)
|
||||
{
|
||||
def % (revision: String): ModuleID =
|
||||
{
|
||||
nonEmpty(revision, "Revision")
|
||||
ModuleID(groupID, artifactID, revision).cross(!crossVersion.isEmpty, crossVersion.getOrElse(identity))
|
||||
ModuleID(groupID, artifactID, revision).cross(crossVersion)
|
||||
}
|
||||
}
|
||||
final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID)
|
||||
|
|
|
|||
|
|
@ -299,24 +299,19 @@ private object IvySbt
|
|||
}
|
||||
|
||||
private def substituteCross(m: ModuleSettings): ModuleSettings =
|
||||
m.ivyScala match { case None => m; case Some(is) => substituteCross(m, is.substituteCross) }
|
||||
private def substituteCross(m: ModuleSettings, sub: ModuleID => ModuleID): ModuleSettings =
|
||||
m.ivyScala match {
|
||||
case None => m
|
||||
case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion)
|
||||
}
|
||||
private def substituteCross(m: ModuleSettings, scalaFullVersion: String, scalaBinaryVersion: String): ModuleSettings =
|
||||
{
|
||||
val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion)
|
||||
m match {
|
||||
case ec: EmptyConfiguration => ec.copy(module = sub(ec.module))
|
||||
case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub)
|
||||
case _ => m
|
||||
}
|
||||
def crossName(name: String, cross: String): String =
|
||||
name + "_" + cross
|
||||
def substituteCross(a: Artifact, cross: String): Artifact =
|
||||
a.copy(name = crossName(a.name, cross))
|
||||
def substituteCrossA(as: Seq[Artifact], cross: String): Seq[Artifact] =
|
||||
as.map(art => substituteCross(art, cross))
|
||||
def substituteCross(m: ModuleID, cross: String): ModuleID =
|
||||
if(m.crossVersion)
|
||||
m.copy(name = crossName(m.name, m.crossVersionRemap(cross)), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross))
|
||||
else
|
||||
m
|
||||
}
|
||||
|
||||
private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ object IvyActions
|
|||
val resolver = ivy.getSettings.getResolver(resolverName)
|
||||
if(resolver eq null) error("Undefined resolver '" + resolverName + "'")
|
||||
val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) }
|
||||
val is = crossIvyScala(module.moduleSettings)
|
||||
val as = mapArtifacts(md, is, artifacts) ++ ivyArtifact.toList
|
||||
val cross = crossVersionMap(module.moduleSettings)
|
||||
val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList
|
||||
withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = true) }
|
||||
}
|
||||
}
|
||||
|
|
@ -102,18 +102,16 @@ object IvyActions
|
|||
try { act }
|
||||
finally { resolver.setChecksums(previous mkString ",") }
|
||||
}
|
||||
private def crossIvyScala(moduleSettings: ModuleSettings): Option[IvyScala] =
|
||||
private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] =
|
||||
moduleSettings match {
|
||||
case i: InlineConfiguration if i.module.crossVersion => i.ivyScala
|
||||
case e: EmptyConfiguration if e.module.crossVersion => e.ivyScala
|
||||
case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala)
|
||||
case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala)
|
||||
case _ => None
|
||||
}
|
||||
def substituteCross(ivyScala: Option[IvyScala], artifacts: Seq[Artifact]): Seq[Artifact] =
|
||||
ivyScala match { case None => artifacts; case Some(is) => IvySbt.substituteCrossA(artifacts, is.scalaVersion) }
|
||||
def mapArtifacts(module: ModuleDescriptor, ivyScala: Option[IvyScala], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] =
|
||||
def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] =
|
||||
{
|
||||
val rawa = artifacts.keys.toSeq
|
||||
val seqa = substituteCross(ivyScala, rawa)
|
||||
val seqa = CrossVersion.substituteCross(rawa, cross)
|
||||
val zipped = rawa zip IvySbt.mapArtifacts(module, seqa)
|
||||
zipped map { case (a, ivyA) => (ivyA, artifacts(a)) }
|
||||
}
|
||||
|
|
@ -199,7 +197,7 @@ object IvyActions
|
|||
report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) }
|
||||
|
||||
private[this] def restrictedCopy(m: ModuleID, confs: Boolean) =
|
||||
ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, crossVersionRemap = m.crossVersionRemap, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None)
|
||||
ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None)
|
||||
private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) =
|
||||
{
|
||||
val resolveOptions = new ResolveOptions
|
||||
|
|
|
|||
|
|
@ -9,14 +9,21 @@ import scala.xml.NodeSeq
|
|||
import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver}
|
||||
import org.apache.ivy.util.url.CredentialsStore
|
||||
|
||||
final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false, crossVersionRemap: String => String = identity)
|
||||
final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled)
|
||||
{
|
||||
override def toString =
|
||||
organization + ":" + name + ":" + revision +
|
||||
(configurations match { case Some(s) => ":" + s; case None => "" }) +
|
||||
(if(extraAttributes.isEmpty) "" else " " + extraString)
|
||||
def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")")
|
||||
def cross(v: Boolean, verRemap: String => String = identity) = copy(crossVersion = v, crossVersionRemap = verRemap)
|
||||
|
||||
@deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0")
|
||||
def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled)
|
||||
@deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0")
|
||||
def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled)
|
||||
|
||||
def cross(v: CrossVersion): ModuleID = copy(crossVersion = v)
|
||||
|
||||
// () required for chaining
|
||||
def notTransitive() = intransitive()
|
||||
def intransitive() = copy(isTransitive = false)
|
||||
|
|
@ -418,14 +425,14 @@ object Artifact
|
|||
val base = if(i >= 0) name.substring(0, i) else name
|
||||
Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL))
|
||||
}
|
||||
def artifactName(scalaVersion: String, module: ModuleID, artifact: Artifact): String =
|
||||
def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String =
|
||||
{
|
||||
import artifact._
|
||||
val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c }
|
||||
val base = if(module.crossVersion) IvySbt.crossName(artifact.name, module.crossVersionRemap(scalaVersion)) else artifact.name
|
||||
val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary)
|
||||
val base = CrossVersion.applyCross(artifact.name, cross)
|
||||
base + "-" + module.revision + classifierStr + "." + artifact.extension
|
||||
}
|
||||
def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else ""
|
||||
|
||||
val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs)
|
||||
val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ object SbtArtifacts
|
|||
|
||||
import ScalaArtifacts._
|
||||
|
||||
final case class IvyScala(scalaVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, substituteCross: ModuleID => ModuleID)
|
||||
final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean)
|
||||
|
||||
private object IvyScala
|
||||
{
|
||||
|
|
@ -34,11 +34,11 @@ private object IvyScala
|
|||
def checkModule(module: DefaultModuleDescriptor, conf: String)(check: IvyScala)
|
||||
{
|
||||
if(check.checkExplicit)
|
||||
checkDependencies(module, check.scalaVersion, check.configurations)
|
||||
checkDependencies(module, check.scalaBinaryVersion, check.configurations)
|
||||
if(check.filterImplicit)
|
||||
excludeScalaJars(module, check.configurations)
|
||||
if(check.overrideScalaVersion)
|
||||
overrideScalaVersion(module, check.scalaVersion)
|
||||
overrideScalaVersion(module, check.scalaFullVersion)
|
||||
}
|
||||
def overrideScalaVersion(module: DefaultModuleDescriptor, version: String)
|
||||
{
|
||||
|
|
@ -54,14 +54,15 @@ private object IvyScala
|
|||
|
||||
/** Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the
|
||||
* dependencies matches scalaVersion. */
|
||||
private def checkDependencies(module: ModuleDescriptor, scalaVersion: String, configurations: Iterable[Configuration])
|
||||
private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration])
|
||||
{
|
||||
val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations)
|
||||
for(dep <- module.getDependencies.toList)
|
||||
{
|
||||
val id = dep.getDependencyRevisionId
|
||||
if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet))
|
||||
error("Version specified for dependency " + id + " differs from Scala version in project (" + scalaVersion + ").")
|
||||
val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision)
|
||||
if(id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet))
|
||||
error("Binary version for dependency " + id + " (" + depBinaryVersion + ") differs from Scala binary version in project (" + scalaBinaryVersion + ").")
|
||||
}
|
||||
}
|
||||
private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package sbt
|
|||
import Load.LoadedBuild
|
||||
import Artifact.{DocClassifier, SourceClassifier}
|
||||
import Configurations.{Compile, CompilerPlugin, IntegrationTest, names, Provided, Runtime, Test}
|
||||
import CrossVersion.{binarySbtVersion, binaryScalaVersion, isStable, selectVersion}
|
||||
import complete._
|
||||
import std.TaskExtra._
|
||||
import inc.{FileValueCache, Locate}
|
||||
|
|
@ -48,16 +49,16 @@ object Defaults extends BuildCommon
|
|||
def buildCore: Seq[Setting[_]] = thisBuildCore ++ globalCore
|
||||
def thisBuildCore: Seq[Setting[_]] = inScope(GlobalScope.copy(project = Select(ThisBuild)))(Seq(
|
||||
managedDirectory <<= baseDirectory(_ / "lib_managed")
|
||||
|
||||
))
|
||||
def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(Seq(
|
||||
crossVersion :== CrossVersion.Disabled,
|
||||
buildDependencies <<= buildDependencies or Classpaths.constructBuildDependencies,
|
||||
taskTemporaryDirectory := IO.createTemporaryDirectory,
|
||||
onComplete <<= taskTemporaryDirectory { dir => () => IO.delete(dir); IO.createDirectory(dir) },
|
||||
concurrentRestrictions <<= concurrentRestrictions or defaultRestrictions,
|
||||
parallelExecution :== true,
|
||||
sbtVersion <<= appConfiguration { _.provider.id.version },
|
||||
sbtBinaryVersion <<= sbtVersion(v => binaryVersion(v, "0.12")),
|
||||
sbtBinaryVersion <<= sbtVersion apply binarySbtVersion,
|
||||
sbtResolver <<= sbtVersion { sbtV => if(sbtV endsWith "-SNAPSHOT") Classpaths.typesafeSnapshots else Classpaths.typesafeResolver },
|
||||
pollInterval :== 500,
|
||||
logBuffered :== false,
|
||||
|
|
@ -190,7 +191,13 @@ object Defaults extends BuildCommon
|
|||
scalacOptions in GlobalScope :== Nil,
|
||||
scalaInstance <<= scalaInstanceSetting,
|
||||
scalaVersion in GlobalScope <<= appConfiguration( _.provider.scalaProvider.version),
|
||||
scalaBinaryVersion <<= scalaVersion(v => binaryVersion(v, "2.10")),
|
||||
scalaBinaryVersion in GlobalScope <<= scalaVersion apply binaryScalaVersion,
|
||||
crossVersion <<= (crossPaths, scalaVersion) { (enabled, sv) =>
|
||||
if(enabled)
|
||||
if(isStable(sv)) CrossVersion.binary else CrossVersion.full
|
||||
else
|
||||
CrossVersion.Disabled
|
||||
},
|
||||
crossScalaVersions in GlobalScope <<= Seq(scalaVersion).join,
|
||||
crossTarget <<= (target, scalaBinaryVersion, sbtBinaryVersion, sbtPlugin, crossPaths)(makeCrossTarget)
|
||||
)
|
||||
|
|
@ -379,7 +386,10 @@ object Defaults extends BuildCommon
|
|||
def collectFiles(dirs: ScopedTaskable[Seq[File]], filter: ScopedTaskable[FileFilter], excludes: ScopedTaskable[FileFilter]): Initialize[Task[Seq[File]]] =
|
||||
(dirs, filter, excludes) map { (d,f,excl) => d.descendantsExcept(f,excl).get }
|
||||
|
||||
def artifactPathSetting(art: SettingKey[Artifact]) = (crossTarget, projectID, art, scalaBinaryVersion in artifactName, artifactName) { (t, module, a, sv, toString) => t / toString(sv, module, a) asFile }
|
||||
def artifactPathSetting(art: SettingKey[Artifact]) = (crossTarget, projectID, art, scalaVersion in artifactName, scalaBinaryVersion in artifactName, artifactName) {
|
||||
(t, module, a, sv, sbv, toString) =>
|
||||
t / toString(ScalaVersion(sv, sbv), module, a) asFile
|
||||
}
|
||||
def artifactSetting = ((artifact, artifactClassifier).identity zipWith configuration.?) { case ((a,classifier),cOpt) =>
|
||||
val cPart = cOpt flatMap { c => if(c == Compile) None else Some(c.name) }
|
||||
val combined = cPart.toList ++ classifier.toList
|
||||
|
|
@ -511,7 +521,8 @@ object Defaults extends BuildCommon
|
|||
})
|
||||
}
|
||||
|
||||
def sbtPluginExtra(m: ModuleID, sbtV: String, scalaV: String): ModuleID = m.extra(CustomPomParser.SbtVersionKey -> sbtV, CustomPomParser.ScalaVersionKey -> scalaV).copy(crossVersion = false)
|
||||
def sbtPluginExtra(m: ModuleID, sbtV: String, scalaV: String): ModuleID =
|
||||
m.extra(CustomPomParser.SbtVersionKey -> sbtV, CustomPomParser.ScalaVersionKey -> scalaV).copy(crossVersion = CrossVersion.Disabled)
|
||||
def writePluginsDescriptor(plugins: Set[String], dir: File): Seq[File] =
|
||||
{
|
||||
val descriptor: File = dir / "sbt" / "sbt.plugins"
|
||||
|
|
@ -597,25 +608,6 @@ object Defaults extends BuildCommon
|
|||
(if(aggregate) p.aggregate else Nil)
|
||||
}
|
||||
|
||||
val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r
|
||||
def partialVersion(s: String): Option[(Int,Int)] =
|
||||
s match {
|
||||
case PartialVersion(major, minor) => Some(major.toInt, minor.toInt)
|
||||
case _ => None
|
||||
}
|
||||
private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean =
|
||||
major > minMajor || (major == minMajor && minor >= minMinor)
|
||||
|
||||
def binaryVersion(full: String, cutoff: String): String =
|
||||
{
|
||||
def sub(major: Int, minor: Int) = major + "." + minor
|
||||
(partialVersion(full), partialVersion(cutoff)) match {
|
||||
case (Some((major, minor)), None) => sub(major, minor)
|
||||
case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor)
|
||||
case _ => full
|
||||
}
|
||||
}
|
||||
|
||||
val CompletionsID = "completions"
|
||||
|
||||
def noAggregation: Seq[Scoped] = Seq(run, console, consoleQuick, consoleProject)
|
||||
|
|
@ -744,16 +736,16 @@ object Classpaths
|
|||
ivyLoggingLevel in GlobalScope :== UpdateLogging.DownloadOnly,
|
||||
ivyXML in GlobalScope :== NodeSeq.Empty,
|
||||
ivyValidate in GlobalScope :== false,
|
||||
ivyScala <<= ivyScala or (scalaHome, scalaVersion, scalaBinaryVersion in update) { (sh,v,vu) =>
|
||||
Some(new IvyScala(v, Nil, filterImplicit = true, checkExplicit = true, overrideScalaVersion = sh.isEmpty, substituteCross = x => IvySbt.substituteCross(x, vu)))
|
||||
ivyScala <<= ivyScala or (scalaHome, scalaVersion in update, scalaBinaryVersion in update) { (sh,fv,bv) =>
|
||||
Some(new IvyScala(fv, bv, Nil, filterImplicit = true, checkExplicit = true, overrideScalaVersion = sh.isEmpty))
|
||||
},
|
||||
moduleConfigurations in GlobalScope :== Nil,
|
||||
publishTo in GlobalScope :== None,
|
||||
artifactPath in makePom <<= artifactPathSetting(artifact in makePom),
|
||||
publishArtifact in makePom <<= publishMavenStyle,
|
||||
artifact in makePom <<= moduleName(Artifact.pom),
|
||||
projectID <<= (organization,moduleName,version,artifacts,crossPaths){ (org,module,version,as,crossEnabled) =>
|
||||
ModuleID(org, module, version).cross(crossEnabled).artifacts(as : _*)
|
||||
projectID <<= (organization,moduleName,version,artifacts,crossVersion in projectID){ (org,module,version,as,cross) =>
|
||||
ModuleID(org, module, version).cross(cross).artifacts(as : _*)
|
||||
},
|
||||
projectID <<= pluginProjectID,
|
||||
resolvers in GlobalScope :== Nil,
|
||||
|
|
@ -797,12 +789,19 @@ object Classpaths
|
|||
} tag(Tags.Update, Tags.Network),
|
||||
sbtDependency in GlobalScope <<= appConfiguration { app =>
|
||||
val id = app.provider.id
|
||||
val base = ModuleID(id.groupID, id.name, id.version, crossVersion = id.crossVersioned)
|
||||
IvySbt.substituteCross(base, app.provider.scalaProvider.version).copy(crossVersion = false)
|
||||
val scalaVersion = app.provider.scalaProvider.version
|
||||
val binVersion = binaryScalaVersion(scalaVersion)
|
||||
val cross = if(id.crossVersioned) if(isStable(scalaVersion)) CrossVersion.binary else CrossVersion.full else CrossVersion.Disabled
|
||||
val base = ModuleID(id.groupID, id.name, id.version, crossVersion = cross)
|
||||
CrossVersion(scalaVersion, binVersion)(base).copy(crossVersion = CrossVersion.Disabled)
|
||||
}
|
||||
)
|
||||
def pluginProjectID: Initialize[ModuleID] = (sbtBinaryVersion in update, scalaBinaryVersion in update, projectID, sbtPlugin) { (sbtV, scalaV, pid, isPlugin) =>
|
||||
if(isPlugin) sbtPluginExtra(pid, sbtV, scalaV) else pid
|
||||
def pluginProjectID: Initialize[ModuleID] = (sbtVersion in update, sbtBinaryVersion in update, scalaVersion in update, scalaBinaryVersion in update, projectID, sbtPlugin) {
|
||||
(sbtV, sbtBV, scalaV, scalaBV, pid, isPlugin) =>
|
||||
if(isPlugin)
|
||||
sbtPluginExtra(pid, selectVersion(sbtV, sbtBV), selectVersion(scalaV, scalaBV))
|
||||
else
|
||||
pid
|
||||
}
|
||||
def ivySbt0: Initialize[Task[IvySbt]] =
|
||||
(ivyConfiguration, credentials, streams) map { (conf, creds, s) =>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ object IvyConsole
|
|||
def parseManaged(arg: String, log: Logger): Seq[ModuleID] =
|
||||
arg match
|
||||
{
|
||||
case DepPattern(group, cross, name, version) => ModuleID(group.trim, name.trim, version.trim, crossVersion = !cross.trim.isEmpty) :: Nil
|
||||
case DepPattern(group, cross, name, version) =>
|
||||
val crossV = if(cross.trim.isEmpty) CrossVersion.Disabled else CrossVersion.binary
|
||||
ModuleID(group.trim, name.trim, version.trim, crossVersion = crossV) :: Nil
|
||||
case _ => log.warn("Ignoring invalid argument '" + arg + "'"); Nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ object Keys
|
|||
val scalaVersion = SettingKey[String]("scala-version", "The version of Scala used for building.")
|
||||
val scalaBinaryVersion = SettingKey[String]("scala-binary-version", "The Scala version substring describing binary compatibility.")
|
||||
val crossScalaVersions = SettingKey[Seq[String]]("cross-scala-versions", "The versions of Scala used when cross-building.")
|
||||
val crossVersion = SettingKey[CrossVersion]("cross-version", "Configures handling of the Scala version when cross-building.")
|
||||
val classpathOptions = SettingKey[ClasspathOptions]("classpath-options", "Configures handling of Scala classpaths.")
|
||||
val definedSbtPlugins = TaskKey[Set[String]]("defined-sbt-plugins", "The set of names of Plugin implementations defined by this project.")
|
||||
val sbtPlugin = SettingKey[Boolean]("sbt-plugin", "If true, enables adding sbt as a dependency and auto-generation of the plugin descriptor file.")
|
||||
|
|
@ -165,7 +166,7 @@ object Keys
|
|||
val artifactPath = SettingKey[File]("artifact-path", "The location of a generated artifact.")
|
||||
val artifact = SettingKey[Artifact]("artifact", "Describes an artifact.")
|
||||
val artifactClassifier = SettingKey[Option[String]]("artifact-classifier", "Sets the classifier used by the default artifact definition.")
|
||||
val artifactName = SettingKey[(String, ModuleID, Artifact) => String]("artifact-name", "Function that produces the artifact name from its definition.")
|
||||
val artifactName = SettingKey[(ScalaVersion, ModuleID, Artifact) => String]("artifact-name", "Function that produces the artifact name from its definition.")
|
||||
val mappings = TaskKey[Seq[(File,String)]]("mappings", "Defines the mappings from a file to a path, used by packaging, for example.")
|
||||
val fileMappings = TaskKey[Seq[(File,File)]]("file-mappings", "Defines the mappings from a file to a file, used for copying files, for example.")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ package sbt
|
|||
import FileInfo.{exists, hash}
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import Types.:+:
|
||||
import Types.{:+:, idFun}
|
||||
import scala.xml.NodeSeq
|
||||
import sbinary.{DefaultProtocol,Format}
|
||||
import DefaultProtocol.{immutableMapFormat, immutableSetFormat, optionsAreFormat}
|
||||
|
|
@ -80,8 +80,19 @@ object CacheIvy
|
|||
)
|
||||
implicit def exclusionRuleFormat(implicit sf: Format[String]): Format[ExclusionRule] =
|
||||
wrap[ExclusionRule, (String, String, String, Seq[String])]( e => (e.organization, e.name, e.artifact, e.configurations), { case (o,n,a,cs) => ExclusionRule(o,n,a,cs) })
|
||||
|
||||
implicit def crossVersionFormat: Format[CrossVersion] = wrap(crossToInt, crossFromInt)
|
||||
|
||||
private[this] final val DisabledValue = 0
|
||||
private[this] final val BinaryValue = 1
|
||||
private[this] final val FullValue = 2
|
||||
|
||||
import CrossVersion.{Binary, Disabled, Full}
|
||||
private[this] val crossFromInt = (i: Int) => i match { case BinaryValue => new Binary(idFun); case FullValue => new Full(idFun); case _ => Disabled }
|
||||
private[this] val crossToInt = (c: CrossVersion) => c match { case Disabled => 0; case b: Binary => BinaryValue; case f: Full => FullValue }
|
||||
|
||||
implicit def moduleIDFormat(implicit sf: Format[String], af: Format[Artifact], bf: Format[Boolean], ef: Format[ExclusionRule]): Format[ModuleID] =
|
||||
wrap[ModuleID, ((String,String,String,Option[String]),(Boolean,Boolean,Seq[Artifact],Seq[ExclusionRule],Map[String,String],Boolean))](
|
||||
wrap[ModuleID, ((String,String,String,Option[String]),(Boolean,Boolean,Seq[Artifact],Seq[ExclusionRule],Map[String,String],CrossVersion))](
|
||||
m => ((m.organization,m.name,m.revision,m.configurations), (m.isChanging, m.isTransitive, m.explicitArtifacts, m.exclusions, m.extraAttributes, m.crossVersion)),
|
||||
{ case ((o,n,r,cs),(ch,t,as,excl,x,cv)) => ModuleID(o,n,r,cs,ch,t,as,excl,x,cv) }
|
||||
)
|
||||
|
|
@ -144,6 +155,7 @@ object CacheIvy
|
|||
|
||||
implicit def artifactToHL = (a: Artifact) => a.name :+: a.`type` :+: a.extension :+: a.classifier :+: names(a.configurations) :+: a.url :+: a.extraAttributes :+: HNil
|
||||
implicit def exclusionToHL = (e: ExclusionRule) => e.organization :+: e.name :+: e.artifact :+: e.configurations :+: HNil
|
||||
implicit def crossToHL = (c: CrossVersion) => crossToInt(c) :+: HNil
|
||||
|
||||
/* implicit def deliverConfToHL = (p: DeliverConfiguration) => p.deliverIvyPattern :+: p.status :+: p.configurations :+: HNil
|
||||
implicit def publishConfToHL = (p: PublishConfiguration) => p.ivyFile :+: p.resolverName :+: p.artifacts :+: HNil*/
|
||||
|
|
@ -156,13 +168,14 @@ object CacheIvy
|
|||
implicit def connectionIC: InputCache[SshConnection] = wrapIn
|
||||
implicit def artifactIC: InputCache[Artifact] = wrapIn
|
||||
implicit def exclusionIC: InputCache[ExclusionRule] = wrapIn
|
||||
implicit def crossVersionIC: InputCache[CrossVersion] = wrapIn
|
||||
/* implicit def publishConfIC: InputCache[PublishConfiguration] = wrapIn
|
||||
implicit def deliverConfIC: InputCache[DeliverConfiguration] = wrapIn*/
|
||||
|
||||
object L1 {
|
||||
implicit def retrieveToHL = (r: RetrieveConfiguration) => exists(r.retrieveDirectory) :+: r.outputPattern :+: HNil
|
||||
implicit def ivyPathsToHL = (p: IvyPaths) => exists(p.baseDirectory) :+: p.ivyHome.map(exists.apply) :+: HNil
|
||||
implicit def ivyScalaHL = (i: IvyScala) => i.scalaVersion :+: names(i.configurations) :+: i.checkExplicit :+: i.filterImplicit :+: HNil
|
||||
implicit def ivyScalaHL = (i: IvyScala) => i.scalaFullVersion :+: i.scalaBinaryVersion :+: names(i.configurations) :+: i.checkExplicit :+: i.filterImplicit :+: HNil
|
||||
implicit def configurationToHL = (c: Configuration) => c.name :+: c.description :+: c.isPublic :+: names(c.extendsConfigs) :+: c.transitive :+: HNil
|
||||
|
||||
implicit def passwordToHL = (s: PasswordAuthentication) => Hash(s.user) :+: password(s.password) :+: HNil
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ object InfoTest extends Build
|
|||
lazy val root = Project("root", file(".")) settings(
|
||||
ivyPaths <<= (baseDirectory, target)( (dir, t) => new IvyPaths(dir, Some(t / "ivy-cache"))),
|
||||
ivyXML <<= (customInfo, organization, moduleName, version) apply inlineXML,
|
||||
scalaVersion := "2.9.0",
|
||||
projectID ~= (_ cross false),
|
||||
customInfo <<= baseDirectory{_ / "info" exists },
|
||||
TaskKey[Unit]("check-download") <<= checkDownload,
|
||||
|
|
@ -24,9 +25,9 @@ object InfoTest extends Build
|
|||
ScalaQuery is a type-safe database query API for Scala.
|
||||
</description>
|
||||
</info>
|
||||
<dependency org="org.scalacheck" name="scalacheck" rev="1.5"/>)
|
||||
<dependency org="org.scala-tools.testing" name="scalacheck_2.9.0" rev="1.9"/>)
|
||||
else
|
||||
<dependency org="org.scalacheck" name="scalacheck" rev="1.5"/>
|
||||
<dependency org="org.scala-tools.testing" name="scalacheck_2.9.0" rev="1.9"/>
|
||||
|
||||
def checkDownload = (dependencyClasspath in Compile) map { cp => if(cp.isEmpty) error("Dependency not downloaded"); () }
|
||||
def checkInfo = (customInfo, delivered) map { (addInfo, d) =>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
resolvers += ScalaToolsReleases
|
||||
|
||||
libraryDependencies += "org.scalacheck" % "scalacheck" % "1.5"
|
||||
|
||||
ivyPaths <<= baseDirectory( dir => new IvyPaths(dir, Some(dir / "ivy-home")))
|
||||
|
|
@ -7,4 +9,4 @@ TaskKey[Unit]("check") <<= update map { report =>
|
|||
assert(!files.isEmpty, "ScalaCheck module not found in update report")
|
||||
val missing = files.filter(! _.exists)
|
||||
assert(missing.isEmpty, "Reported ScalaCheck artifact files don't exist: " + missing.mkString(", "))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
#Project properties
|
||||
#Fri Jan 30 20:49:57 EST 2009
|
||||
project.name=Inline Dependency Test A
|
||||
project.version=1.0
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import sbt._
|
||||
|
||||
class UpdateTestProject(info: ProjectInfo) extends DefaultProject(info)
|
||||
{
|
||||
val sc = "org.scalacheck" % "scalacheck" % "1.5"
|
||||
override def ivyCacheDirectory = Some(outputPath / "ivy-cache")
|
||||
override def disableCrossPaths = true
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
object MakePomTest extends Build
|
||||
{
|
||||
lazy val root = Project("root", file(".")) settings(
|
||||
resolvers += ScalaToolsReleases,
|
||||
readPom <<= makePom map XML.loadFile,
|
||||
TaskKey[Unit]("check-pom") <<= checkPom,
|
||||
TaskKey[Unit]("check-extra") <<= checkExtra,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
moduleConfigurations += ModuleConfiguration("org.scala-lang", "*", "2.10.0-.*", scalaSnapshots)
|
||||
}
|
||||
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20111001.020530-165"
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20120122.024228-256"
|
||||
|
||||
resolvers := Nil
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
moduleConfigurations += ModuleConfiguration("org.not-scala-lang", "*", "2.10.0-.*", scalaSnapshots)
|
||||
}
|
||||
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20111001.020530-165"
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20120122.024228-256"
|
||||
|
||||
resolvers := Nil
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
moduleConfigurations += ModuleConfiguration("org.scala-lang", "*", "2.10.0-.*", scalaSnapshots)
|
||||
}
|
||||
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20111001.020530-165"
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20120122.024228-256"
|
||||
|
||||
resolvers := Nil
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
moduleConfigurations += ModuleConfiguration("org.scala-lang", "*", "2.10.0-.*", scalaSnapshots)
|
||||
}
|
||||
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20111001.020530-164"
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.0-20120122.024228-255"
|
||||
|
||||
resolvers := Nil
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
object ParentTest extends Build
|
||||
{
|
||||
lazy val parent: Project = Project("Flowmodel", file(".")) aggregate(core, reporters)
|
||||
lazy val core: Project = Project("Flowmodel core", file("core"), delegates = parent :: Nil)
|
||||
lazy val reporters: Project = Project("Extra reporters", file("reporters"), delegates = parent :: Nil) aggregate(jfreechart) dependsOn(jfreechart)
|
||||
lazy val jfreechart: Project = Project("JFreeChart reporters", file("jfreechart")/*, delegates = reporters :: Nil*/) dependsOn(core)
|
||||
lazy val core: Project = Project("Flowmodel-core", file("core"), delegates = parent :: Nil)
|
||||
lazy val reporters: Project = Project("Extra-reporters", file("reporters"), delegates = parent :: Nil) aggregate(jfreechart) dependsOn(jfreechart)
|
||||
lazy val jfreechart: Project = Project("JFreeChart-reporters", file("jfreechart")/*, delegates = reporters :: Nil*/) dependsOn(core)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
object PomRepoTest extends Build
|
||||
{
|
||||
lazy val root = Project("root", file(".")) settings(
|
||||
resolvers ++= Seq(local, ScalaToolsSnapshots),
|
||||
resolvers ++= Seq(local, ScalaToolsReleases, ScalaToolsSnapshots),
|
||||
InputKey[Unit]("check-pom") <<= InputTask(_ => spaceDelimited("<args>")) { result => (makePom, result, streams) map checkPomRepositories },
|
||||
makePomConfiguration <<= (makePomConfiguration, baseDirectory) { (conf, base) =>
|
||||
conf.copy(filterRepositories = pomIncludeRepository(base, conf.filterRepositories) )
|
||||
|
|
|
|||
|
|
@ -2,15 +2,23 @@ import sbt._
|
|||
import Keys._
|
||||
object P extends Build
|
||||
{
|
||||
override def settings = super.settings ++ Seq( scalaVersion in update := "2.9.0" )
|
||||
override def settings = super.settings ++ Seq(
|
||||
scalaBinaryVersion in update := "2.9.0",
|
||||
resolvers += ScalaToolsReleases
|
||||
)
|
||||
|
||||
def configIvyScala =
|
||||
ivyScala ~= { _.map(_.copy(checkExplicit = false)) }
|
||||
|
||||
val declared = SettingKey[Boolean]("declared")
|
||||
lazy val a = Project("A", file("a")) settings(
|
||||
libraryDependencies += "org.scala-tools.sbinary" %% "sbinary" % "0.4.0" % "provided"
|
||||
libraryDependencies += "org.scala-tools.sbinary" %% "sbinary" % "0.4.0" % "provided",
|
||||
configIvyScala
|
||||
)
|
||||
|
||||
lazy val b = Project("B", file("b")) dependsOn(a) settings(
|
||||
libraryDependencies <<= declared(d => if(d) Seq("org.scala-tools.sbinary" %% "sbinary" % "0.4.0" % "provided") else Nil),
|
||||
declared <<= baseDirectory(_ / "declare.lib" exists)
|
||||
declared <<= baseDirectory(_ / "declare.lib" exists),
|
||||
configIvyScala
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,10 @@ import Keys._
|
|||
|
||||
object Build extends Build
|
||||
{
|
||||
override def settings = super.settings ++ Seq(
|
||||
sbtBinaryVersion <<= sbtVersion
|
||||
)
|
||||
|
||||
lazy val root = Project("root", file(".")) aggregate(a,b,c)
|
||||
lazy val a = Project("a", file("a"))
|
||||
lazy val b = Project("b", file("b"))
|
||||
|
|
|
|||
Loading…
Reference in New Issue