2011-06-10 13:48:53 +02:00
|
|
|
import sbt._
|
|
|
|
|
import Keys._
|
|
|
|
|
import StringUtilities.normalize
|
|
|
|
|
|
|
|
|
|
object Util
|
|
|
|
|
{
|
2012-07-01 21:16:42 +02:00
|
|
|
val ExclusiveTest = Tags.Tag("exclusive-test")
|
2011-06-10 13:48:53 +02:00
|
|
|
lazy val componentID = SettingKey[Option[String]]("component-id")
|
2012-07-13 19:41:00 +02:00
|
|
|
lazy val scalaKeywords = TaskKey[Set[String]]("scala-keywords")
|
|
|
|
|
lazy val generateKeywords = TaskKey[File]("generateKeywords")
|
2013-07-19 04:45:04 +02:00
|
|
|
lazy val nightly211 = SettingKey[Boolean]("nightly-211")
|
2013-01-19 00:49:20 +01:00
|
|
|
lazy val includeTestDependencies = SettingKey[Boolean]("includeTestDependencies", "Doesn't declare test dependencies.")
|
2011-06-10 13:48:53 +02:00
|
|
|
|
2013-09-10 14:30:00 +02:00
|
|
|
def inAll(projects: => Seq[ProjectReference], key: SettingKey[Task[Unit]]): Project.Initialize[Task[Unit]] =
|
2011-09-26 14:20:07 +02:00
|
|
|
inAllProjects(projects, key) { deps => nop dependsOn( deps : _*) }
|
|
|
|
|
|
2013-09-10 14:30:00 +02:00
|
|
|
def inAllProjects[T](projects: => Seq[ProjectReference], key: SettingKey[T]): Project.Initialize[Seq[T]] =
|
|
|
|
|
Def.settingDyn {
|
|
|
|
|
val lb = loadedBuild.value
|
|
|
|
|
val pr = thisProjectRef.value
|
2011-09-26 14:20:07 +02:00
|
|
|
def resolve(ref: ProjectReference): ProjectRef = Scope.resolveProjectRef(pr.build, Load.getRootProject(lb.units), ref)
|
|
|
|
|
val refs = projects flatMap { base => Defaults.transitiveDependencies(resolve(base.project), lb, includeRoot=true, classpath=true, aggregate=true) }
|
|
|
|
|
refs map ( ref => (key in ref).? ) joinWith(_ flatMap { x => x})
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-10 13:48:53 +02:00
|
|
|
def noPublish(p: Project) = p.copy(settings = noRemotePublish(p.settings))
|
2013-09-10 14:30:00 +02:00
|
|
|
def noRemotePublish(in: Seq[Setting[_]]) = in filterNot { _.key.key == publish.key }
|
2011-06-10 13:48:53 +02:00
|
|
|
|
2013-07-19 04:45:04 +02:00
|
|
|
def nightlySettings = Seq(
|
|
|
|
|
nightly211 <<= scalaVersion(_.startsWith("2.11.")),
|
|
|
|
|
includeTestDependencies <<= nightly211(x => !x)
|
|
|
|
|
)
|
|
|
|
|
def commonSettings(nameString: String) = Seq(
|
|
|
|
|
crossVersion in update <<= (crossVersion,nightly211) { (cv, n) => if(n) CrossVersion.full else cv },
|
|
|
|
|
name := nameString
|
|
|
|
|
)
|
2013-09-10 14:30:00 +02:00
|
|
|
def minProject(path: File, nameString: String) = Project(normalize(nameString), path) settings( commonSettings(nameString) ++ publishPomSettings : _* )
|
|
|
|
|
def baseProject(path: File, nameString: String) = minProject(path, nameString) settings( base : _*)
|
2013-07-19 04:45:04 +02:00
|
|
|
def testedBaseProject(path: File, nameString: String) = baseProject(path, nameString) settings(testDependencies)
|
2011-06-10 13:48:53 +02:00
|
|
|
|
|
|
|
|
lazy val javaOnly = Seq[Setting[_]](/*crossPaths := false, */compileOrder := CompileOrder.JavaThenScala, unmanagedSourceDirectories in Compile <<= Seq(javaSource in Compile).join)
|
2013-09-24 17:25:02 +02:00
|
|
|
lazy val base: Seq[Setting[_]] = Seq(projectComponent) ++ baseScalacOptions ++ Licensed.settings
|
2013-01-23 18:48:54 +01:00
|
|
|
lazy val baseScalacOptions = Seq(
|
|
|
|
|
scalacOptions ++= Seq("-Xelide-below", "0"),
|
|
|
|
|
scalacOptions <++= scalaVersion map CrossVersion.partialVersion map {
|
|
|
|
|
case Some((2, 9)) => Nil // support 2.9 for some subprojects for the Scala Eclipse IDE
|
2013-02-13 14:13:50 +01:00
|
|
|
case _ => Seq("-feature", "-language:implicitConversions", "-language:postfixOps", "-language:higherKinds", "-language:existentials")
|
2013-01-23 18:48:54 +01:00
|
|
|
}
|
|
|
|
|
)
|
2011-06-10 13:48:53 +02:00
|
|
|
|
2013-01-19 00:49:20 +01:00
|
|
|
def testDependencies = libraryDependencies <++= includeTestDependencies { incl =>
|
|
|
|
|
if(incl) Seq(
|
|
|
|
|
"org.scalacheck" %% "scalacheck" % "1.10.0" % "test",
|
|
|
|
|
"org.specs2" %% "specs2" % "1.12.3" % "test"
|
|
|
|
|
)
|
|
|
|
|
else Seq()
|
|
|
|
|
}
|
2011-06-10 13:48:53 +02:00
|
|
|
|
2013-09-10 14:30:00 +02:00
|
|
|
lazy val minimalSettings: Seq[Setting[_]] = Defaults.paths ++ Seq[Setting[_]](crossTarget := target.value, name <<= thisProject(_.id))
|
2011-06-10 13:48:53 +02:00
|
|
|
|
|
|
|
|
def projectComponent = projectID <<= (projectID, componentID) { (pid, cid) =>
|
|
|
|
|
cid match { case Some(id) => pid extra("e:component" -> id); case None => pid }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lazy val apiDefinitions = TaskKey[Seq[File]]("api-definitions")
|
|
|
|
|
|
|
|
|
|
def generateAPICached(cache: File, defs: Seq[File], cp: Classpath, out: File, main: Option[String], run: ScalaRun, s: TaskStreams): Seq[File] =
|
|
|
|
|
{
|
|
|
|
|
def gen() = generateAPI(defs, cp, out, main, run, s)
|
|
|
|
|
val f = FileFunction.cached(cache / "gen-api", FilesInfo.hash) { _ => gen().toSet} // TODO: check if output directory changed
|
|
|
|
|
f(defs.toSet).toSeq
|
|
|
|
|
}
|
|
|
|
|
def generateAPI(defs: Seq[File], cp: Classpath, out: File, main: Option[String], run: ScalaRun, s: TaskStreams): Seq[File] =
|
|
|
|
|
{
|
|
|
|
|
IO.delete(out)
|
|
|
|
|
IO.createDirectory(out)
|
2013-10-08 19:38:33 +02:00
|
|
|
val args = "xsbti.api" :: out.getAbsolutePath :: defs.map(_.getAbsolutePath).toList
|
2011-06-10 13:48:53 +02:00
|
|
|
val mainClass = main getOrElse "No main class defined for datatype generator"
|
|
|
|
|
toError(run.run(mainClass, cp.files, args, s.log))
|
|
|
|
|
(out ** "*.java").get
|
|
|
|
|
}
|
2012-05-14 03:31:40 +02:00
|
|
|
def lastCompilationTime(analysis: sbt.inc.Analysis): Long =
|
|
|
|
|
{
|
|
|
|
|
val times = analysis.apis.internal.values.map(_.compilation.startTime)
|
|
|
|
|
if(times.isEmpty) 0L else times.max
|
|
|
|
|
}
|
|
|
|
|
def generateVersionFile(version: String, dir: File, s: TaskStreams, analysis: sbt.inc.Analysis): Seq[File] =
|
2011-06-10 13:48:53 +02:00
|
|
|
{
|
|
|
|
|
import java.util.{Date, TimeZone}
|
|
|
|
|
val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss")
|
|
|
|
|
formatter.setTimeZone(TimeZone.getTimeZone("GMT"))
|
|
|
|
|
val timestamp = formatter.format(new Date)
|
2012-07-01 21:16:41 +02:00
|
|
|
val content = versionLine(version) + "\ntimestamp=" + timestamp
|
2011-06-10 13:48:53 +02:00
|
|
|
val f = dir / "xsbt.version.properties"
|
2012-07-01 21:16:41 +02:00
|
|
|
if(!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) {
|
2011-06-26 18:27:07 +02:00
|
|
|
s.log.info("Writing version information to " + f + " :\n" + content)
|
|
|
|
|
IO.write(f, content)
|
|
|
|
|
}
|
2011-06-10 13:48:53 +02:00
|
|
|
f :: Nil
|
|
|
|
|
}
|
2012-07-01 21:16:41 +02:00
|
|
|
def versionLine(version: String): String = "version=" + version
|
|
|
|
|
def containsVersion(propFile: File, version: String): Boolean = IO.read(propFile).contains(versionLine(version))
|
|
|
|
|
|
2011-06-10 13:48:53 +02:00
|
|
|
def binID = "compiler-interface-bin"
|
|
|
|
|
def srcID = "compiler-interface-src"
|
2012-04-05 05:05:13 +02:00
|
|
|
|
|
|
|
|
def publishPomSettings: Seq[Setting[_]] = Seq(
|
2012-04-15 01:51:09 +02:00
|
|
|
publishArtifact in makePom := false,
|
2012-04-05 05:05:13 +02:00
|
|
|
pomPostProcess := cleanPom _
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def cleanPom(pomNode: scala.xml.Node) =
|
|
|
|
|
{
|
|
|
|
|
import scala.xml._
|
|
|
|
|
def cleanNodes(nodes: Seq[Node]): Seq[Node] = nodes flatMap ( _ match {
|
|
|
|
|
case elem @ Elem(prefix, "dependency", attributes, scope, children @ _*) if excludePomDependency(elem) =>
|
|
|
|
|
NodeSeq.Empty
|
|
|
|
|
case Elem(prefix, "classifier", attributes, scope, children @ _*) =>
|
|
|
|
|
NodeSeq.Empty
|
|
|
|
|
case Elem(prefix, label, attributes, scope, children @ _*) =>
|
|
|
|
|
Elem(prefix, label, attributes, scope, cleanNodes(children): _*).theSeq
|
|
|
|
|
case other => other
|
|
|
|
|
})
|
|
|
|
|
cleanNodes(pomNode.theSeq)(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def excludePomDependency(node: scala.xml.Node) = node \ "artifactId" exists { n => excludePomArtifact(n.text) }
|
|
|
|
|
|
|
|
|
|
def excludePomArtifact(artifactId: String) = (artifactId == "compiler-interface") || (artifactId startsWith "precompiled")
|
2012-07-01 21:16:42 +02:00
|
|
|
|
|
|
|
|
val testExclusive = tags in test += ( (ExclusiveTest, 1) )
|
|
|
|
|
|
|
|
|
|
// TODO: replace with Tags.exclusive after 0.12.0
|
|
|
|
|
val testExclusiveRestriction = Tags.customLimit { (tags: Map[Tags.Tag,Int]) =>
|
|
|
|
|
val exclusive = tags.getOrElse(ExclusiveTest, 0)
|
|
|
|
|
val all = tags.getOrElse(Tags.All, 0)
|
|
|
|
|
exclusive == 0 || all == 1
|
|
|
|
|
}
|
2012-07-13 19:41:00 +02:00
|
|
|
|
|
|
|
|
def getScalaKeywords: Set[String] =
|
|
|
|
|
{
|
|
|
|
|
val g = new scala.tools.nsc.Global(new scala.tools.nsc.Settings)
|
|
|
|
|
g.nme.keywords.map(_.toString)
|
|
|
|
|
}
|
|
|
|
|
def writeScalaKeywords(base: File, keywords: Set[String]): File =
|
|
|
|
|
{
|
|
|
|
|
val init = keywords.map(tn => '"' + tn + '"').mkString("Set(", ", ", ")")
|
|
|
|
|
val ObjectName = "ScalaKeywords"
|
2012-11-07 00:27:36 +01:00
|
|
|
val PackageName = "sbt"
|
2012-07-13 19:41:00 +02:00
|
|
|
val keywordsSrc =
|
2012-11-07 00:27:36 +01:00
|
|
|
"""package %s
|
2012-07-13 19:41:00 +02:00
|
|
|
object %s {
|
|
|
|
|
val values = %s
|
2012-11-07 00:27:36 +01:00
|
|
|
}""".format(PackageName, ObjectName, init)
|
|
|
|
|
val out = base / PackageName.replace('.', '/') / (ObjectName + ".scala")
|
2012-07-13 19:41:00 +02:00
|
|
|
IO.write(out, keywordsSrc)
|
|
|
|
|
out
|
|
|
|
|
}
|
|
|
|
|
def keywordsSettings: Seq[Setting[_]] = inConfig(Compile)(Seq(
|
|
|
|
|
scalaKeywords := getScalaKeywords,
|
|
|
|
|
generateKeywords <<= (sourceManaged, scalaKeywords) map writeScalaKeywords,
|
|
|
|
|
sourceGenerators <+= generateKeywords map (x => Seq(x))
|
|
|
|
|
))
|
2011-06-10 13:48:53 +02:00
|
|
|
}
|
|
|
|
|
object Common
|
|
|
|
|
{
|
|
|
|
|
def lib(m: ModuleID) = libraryDependencies += m
|
2013-06-01 16:56:30 +02:00
|
|
|
lazy val jlineDep = "jline" % "jline" % "2.11"
|
2013-06-26 16:07:32 +02:00
|
|
|
lazy val jline = lib(jlineDep)
|
2012-05-03 01:56:35 +02:00
|
|
|
lazy val ivy = lib("org.apache.ivy" % "ivy" % "2.3.0-rc1")
|
2011-06-12 02:09:15 +02:00
|
|
|
lazy val httpclient = lib("commons-httpclient" % "commons-httpclient" % "3.1")
|
2012-03-18 00:31:56 +01:00
|
|
|
lazy val jsch = lib("com.jcraft" % "jsch" % "0.1.46" intransitive() )
|
2013-07-19 04:45:04 +02:00
|
|
|
lazy val sbinary = libraryDependencies <+= Util.nightly211(n => "org.scala-tools.sbinary" % "sbinary" % "0.4.2" cross(if(n) CrossVersion.full else CrossVersion.binary))
|
2011-06-10 13:48:53 +02:00
|
|
|
lazy val scalaCompiler = libraryDependencies <+= scalaVersion("org.scala-lang" % "scala-compiler" % _ )
|
2013-06-29 01:03:30 +02:00
|
|
|
lazy val testInterface = lib("org.scala-sbt" % "test-interface" % "1.0")
|
2013-07-09 20:55:30 +02:00
|
|
|
def libModular(name: String) = libraryDependencies <++= (scalaVersion, scalaOrganization)( (sv,o) =>
|
|
|
|
|
if(sv.startsWith("2.11.")) (o % name % sv) :: Nil else Nil
|
|
|
|
|
)
|
|
|
|
|
lazy val scalaXml = libModular("scala-xml")
|
|
|
|
|
lazy val scalaParsers = libModular("scala-parser-combinators")
|
2011-06-10 13:48:53 +02:00
|
|
|
}
|
|
|
|
|
object Licensed
|
|
|
|
|
{
|
|
|
|
|
lazy val notice = SettingKey[File]("notice")
|
|
|
|
|
lazy val extractLicenses = TaskKey[Seq[File]]("extract-licenses")
|
|
|
|
|
|
|
|
|
|
lazy val seeRegex = """\(see (.*?)\)""".r
|
|
|
|
|
def licensePath(base: File, str: String): File = { val path = base / str; if(path.exists) path else error("Referenced license '" + str + "' not found at " + path) }
|
|
|
|
|
def seePaths(base: File, noticeString: String): Seq[File] = seeRegex.findAllIn(noticeString).matchData.map(d => licensePath(base, d.group(1))).toList
|
|
|
|
|
|
|
|
|
|
def settings: Seq[Setting[_]] = Seq(
|
|
|
|
|
notice <<= baseDirectory(_ / "NOTICE"),
|
|
|
|
|
unmanagedResources in Compile <++= (notice, extractLicenses) map { _ +: _ },
|
|
|
|
|
extractLicenses <<= (baseDirectory in ThisBuild, notice, streams) map extractLicenses0
|
|
|
|
|
)
|
|
|
|
|
def extractLicenses0(base: File, note: File, s: TaskStreams): Seq[File] =
|
|
|
|
|
if(!note.exists) Nil else
|
|
|
|
|
try { seePaths(base, IO.read(note)) }
|
|
|
|
|
catch { case e: Exception => s.log.warn("Could not read NOTICE"); Nil }
|
2012-04-05 05:05:13 +02:00
|
|
|
}
|