summaryrefslogtreecommitdiff
path: root/project
diff options
context:
space:
mode:
authorJosh Suereth <joshua.suereth@gmail.com>2012-05-10 09:48:03 -0400
committerJosh Suereth <joshua.suereth@gmail.com>2012-05-10 09:48:03 -0400
commitd9ca44bd31532c91df124cdd2f6f2a417bb4a0e1 (patch)
tree5a7c36f38ba2f5af1080427cc9f37a45d5bed2ff /project
parent3012bd9205636f0a4614d6dec65ffe5f86b719f6 (diff)
parent31546d1b3d841a0fddc9c84af48361c74243ce8e (diff)
downloadscala-d9ca44bd31532c91df124cdd2f6f2a417bb4a0e1.tar.gz
scala-d9ca44bd31532c91df124cdd2f6f2a417bb4a0e1.tar.bz2
scala-d9ca44bd31532c91df124cdd2f6f2a417bb4a0e1.zip
Merge remote-tracking branch 'jsuereth/sbt-build' into sbt-build-0.11.3
Diffstat (limited to 'project')
-rw-r--r--project/Build.scala6
-rw-r--r--project/CheatingComponentCompiler.scala148
-rw-r--r--project/Layers.scala6
-rw-r--r--project/Partest.scala2
-rw-r--r--project/Release.scala106
-rw-r--r--project/ShaResolve.scala2
-rw-r--r--project/Versions.scala142
7 files changed, 303 insertions, 109 deletions
diff --git a/project/Build.scala b/project/Build.scala
index 25fb31cf5b..c753b4901f 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -23,7 +23,7 @@ object ScalaBuild extends Build with Layers {
lazy val buildFixed = AttributeKey[Boolean]("build-uri-fixed")
// Build wide settings:
- override lazy val settings = super.settings ++ Seq(
+ override lazy val settings = super.settings ++ Versions.settings ++ Seq(
autoScalaLibrary := false,
resolvers += Resolver.url(
"Typesafe nightlies",
@@ -34,7 +34,7 @@ object ScalaBuild extends Build with Layers {
ScalaToolsSnapshots
),
organization := "org.scala-lang",
- version := "2.10.0-SNAPSHOT",
+ version <<= Versions.mavenVersion,
pomExtra := <xml:group>
<inceptionYear>2002</inceptionYear>
<licenses>
@@ -170,7 +170,7 @@ object ScalaBuild extends Build with Layers {
skip in Compile <<= lockFile.map(_ exists),
lock <<= lockFile map { f => IO.touch(f) },
unlock <<= lockFile map IO.delete
- )
+ ) ++ CheatingCompilerSettings.settings
// --------------------------------------------------------------
// Libraries used by Scalac that change infrequently
diff --git a/project/CheatingComponentCompiler.scala b/project/CheatingComponentCompiler.scala
new file mode 100644
index 0000000000..e23acfd946
--- /dev/null
+++ b/project/CheatingComponentCompiler.scala
@@ -0,0 +1,148 @@
+import sbt._
+
+import xsbti.{Logger => _,_}
+import compiler._
+import inc._
+import Locate.DefinesClass
+import java.io.File
+
+import java.util.concurrent._
+import Keys._
+import Compiler.Compilers
+
+
+object CheatingCompilerSettings {
+ val hackedmodules = TaskKey[Map[String,File]]("hacked-sbt-components")
+
+ def settings: Seq[Setting[_]] = Seq(
+ hackedmodules := Map.empty,
+
+ // Now look for org.scala-sbt compiler-interface-src!
+ hackedmodules <<= (hackedmodules, target, streams) map { (h, t, s) => Map(sbtCompilerInterface(t,s)) ++ h },
+
+ compilers <<= (hackedmodules, scalaInstance, appConfiguration, streams, classpathOptions, javaHome) map {
+ (hacks, si, app, s, co, jh) => CheatingCompilers.compilers(hacks, si, co, jh)(app, s.log)
+ }
+ )
+
+
+ def sbtCompilerInterface(cacheDir: File, s: TaskStreams): (String, File) =
+ "compiler-interface-src" -> pullFile("compiler-interface-src", "http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/0.12.0-M2/jars/compiler-interface-src.jar", cacheDir, s)
+
+ import dispatch.{url=>_,_}
+ def pullFile(name: String, url: String, cacheDir: File, s: TaskStreams): File = {
+ val cachedFile = cacheDir / (name + ".jar")
+ if (!cachedFile.exists) {
+ // Ensure the directory for the cache exists.
+ cachedFile.getParentFile.mkdirs()
+ val fous = new java.io.FileOutputStream(cachedFile)
+ try Http(dispatch.url(url) >>> fous) finally fous.close()
+ val sha = pullSha(url)
+ if(!isShaOk(cachedFile, sha)) sys.error("Downloaded sha does not match file: " + cachedFile.getAbsolutePath)
+ IO.write(file(cachedFile.getAbsolutePath + ".sha1"), sha)
+ }
+ cachedFile
+ }
+
+ def isShaOk(f: File, sha: String): Boolean =
+ ShaResolve.calculateSha(f) == sha
+
+ def isCached(f: File, url: String): Boolean =
+ if(f.exists) {
+ val savedsha = file(f.getAbsolutePath + ".sha1")
+ savedsha.exists && isShaOk(f, IO.read(savedsha))
+ } else false
+
+ def pullSha(url: String): String =
+ Http(dispatch.url(url + ".sha1") >- identity)
+}
+
+
+object CheatingCompilers {
+
+ def compilers(hacks: Map[String,File], instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File])(implicit app: AppConfiguration, log: Logger): Compilers = {
+ val javac = Compiler.directOrFork(instance, cpOptions, javaHome)
+ val scalac = scalaCompiler(hacks, instance, cpOptions)
+ new Compilers(scalac, javac)
+ }
+
+ def scalaCompiler(hacks: Map[String,File], instance: ScalaInstance, cpOptions: ClasspathOptions)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler = {
+ val launcher = app.provider.scalaProvider.launcher
+ val componentManager = new CheatingComponentManager(hacks, launcher.globalLock, app.provider.components, Option(launcher.ivyHome), log)
+ new AnalyzingCompiler(instance, componentManager, cpOptions, log)
+ }
+}
+
+
+class CheatingComponentManager(val hacks: Map[String,File], globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, ivyHome: Option[File], log: Logger)
+ extends ComponentManager(globalLock, provider, ivyHome, log) {
+
+ private[this] val ivyCache = new IvyCache(ivyHome)
+ /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */
+ override def files(id: String)(ifMissing: IfMissing): Iterable[File] = {
+ def fromGlobal1 =
+ lockGlobalCache {
+ try { update(id); getOrElse1(createAndCache1) }
+ catch { case e: NotInCache => createAndCache1 }
+ }
+ def getOrElse1(orElse: => Iterable[File]): Iterable[File] = {
+ val existing = provider.component(hacked(id))
+ if(existing.isEmpty) orElse else existing
+ }
+ def notFound1 = invalid("Could not find required component '" + id + "'")
+ def createAndCache1 =
+ ifMissing match {
+ case IfMissing.Fail => notFound1
+ case d: IfMissing.Define =>
+ d()
+ if(d.cache) cache(id)
+ getOrElse1(notFound1)
+ }
+ val result = lockLocalCache { getOrElse1(fromGlobal1) }
+ println("cheating-component-manager.files("+id+")")
+ result foreach println
+ result
+ }
+ private def isHacked(id: String) = hacks.keySet contains id
+ private def hacked(id: String) = if(isHacked(id)) "hacked-"+id else id
+ /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */
+ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)( action )
+ /** This is used to ensure atomic access to components in the global Ivy cache.*/
+ private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)( action )
+ private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action })
+ private def invalid(msg: String) = throw new InvalidComponent(msg)
+ private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e)
+
+ override def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(hacked(id), files.toSeq.toArray) }
+ /** Retrieve the file for component 'id' from the local repository. */
+ private def update(id: String): Unit =
+ if(isHacked(id)) {
+ // Grab jar magically
+ println("Grabbing hacked jar for ["+id+"] = " + hacks.get(id))
+ define(hacked(id), Seq(hacks(id)))
+ } else ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log) {jar =>
+ define(id, Seq(jar))
+ }
+
+
+ //---------------------!!!!!!!!!!!!!!!!----------------------------------------
+ // YUK - Ugly hack to use newer compiler interface - YUK
+ //---------------------!!!!!!!!!!!!!!!!----------------------------------------
+ private def sbtModuleID(id: String) = if(isHacked(id)) {
+ println("Making hackd module id!")
+ val version = "0.12.0-M2" // HACKED 20120314203952
+ val timestamp = "20120315T001212" // Hacked "20120314203952" //
+ val stampedVersion = version + "_" + timestamp
+ val result = ModuleID("org.scala-sbt", id, stampedVersion)
+ println("Looking for hacked module id: " + result)
+ result
+ } else ModuleID("org.scala-tools.sbt", id, ComponentManager.stampedVersion)
+ //---------------------!!!!!!!!!!!!!!!!----------------------------------------
+ // ENDYUK - Ugly hack to use newer compiler interface - ENDYUK
+ //---------------------!!!!!!!!!!!!!!!!----------------------------------------
+
+ /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */
+ override def cache(id: String): Unit = ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log)
+ override def clearCache(id: String): Unit = lockGlobalCache { ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) }
+}
+
diff --git a/project/Layers.scala b/project/Layers.scala
index d39e58014c..b15b327895 100644
--- a/project/Layers.scala
+++ b/project/Layers.scala
@@ -16,6 +16,8 @@ trait Layers extends Build {
def fjbg: Project
/** A setting that adds some external dependencies. */
def externalDeps: Setting[_]
+ /** The root project. */
+ def aaa_root: Project
/** Creates a reference Scala version that can be used to build other projects. This takes in the raw
* library, compiler and fjbg libraries as well as a string representing the layer name (used for compiling the compile-interface).
@@ -57,7 +59,7 @@ trait Layers extends Build {
// TODO - Allow other scalac option settings.
scalacOptions in Compile <++= (scalaSource in Compile) map (src => Seq("-sourcepath", src.getAbsolutePath)),
classpathOptions := ClasspathOptions.manual,
- resourceGenerators in Compile <+= (baseDirectory, version, resourceManaged, gitRunner, streams) map Release.generatePropertiesFile("library.properties"),
+ resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, streams) map Versions.generateVersionPropertiesFile("library.properties"),
referenceScala
)
@@ -70,7 +72,7 @@ trait Layers extends Build {
defaultExcludes := ("tests"),
javacOptions ++= Seq("-source", "1.4"),
defaultExcludes in unmanagedResources := "*.scala",
- resourceGenerators in Compile <+= (baseDirectory, version, resourceManaged, gitRunner, streams) map Release.generatePropertiesFile("compiler.properties"),
+ resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, streams) map Versions.generateVersionPropertiesFile("compiler.properties"),
// Note, we might be able to use the default task, but for some reason ant was filtering files out. Not sure what's up, but we'll
// stick with that for now.
unmanagedResources in Compile <<= (baseDirectory) map {
diff --git a/project/Partest.scala b/project/Partest.scala
index ad8047fa00..bbc160a41d 100644
--- a/project/Partest.scala
+++ b/project/Partest.scala
@@ -115,7 +115,7 @@ object partest {
}
}
- def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: ScopedTask[Seq[String]]): Project.Initialize[Task[PartestRunner]] =
+ def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: SettingKey[Seq[String]]): Project.Initialize[Task[PartestRunner]] =
(classpath, javacOptions) map ((cp, opts) => new PartestRunner(Build.data(cp), opts mkString " "))
}
diff --git a/project/Release.scala b/project/Release.scala
index 5ed77548fc..1a17956c13 100644
--- a/project/Release.scala
+++ b/project/Release.scala
@@ -1,115 +1,15 @@
import sbt._
import Keys._
-import _root_.com.jsuereth.git.GitRunner
object Release {
- // TODO - move more of the dist project over here...
+ // TODO - Just make the STARR artifacts and dump the sha1 files.
lazy val pushStarr = Command.command("push-starr") { (state: State) =>
- def f(s: Setting[_]): Setting[_] = s.key.key match {
- case version.key => // TODO - use full version
- s.asInstanceOf[Setting[String]].mapInit( (_,_) => timeFormat format (new java.util.Date))
- case organization.key =>
- s.asInstanceOf[Setting[String]].mapInit( (_,_) => "org.scala-lang.bootstrapp")
- // TODO - Switch publish repo to be typesafe starr repo.
- case publishTo.key =>
- s.asInstanceOf[Setting[Option[Resolver]]].mapInit((_,_) => Some("Starr Repo" at "http://typesafe.artifactoryonline.com/typesafe/starr-releases/"))
- case _ => s
- }
- val extracted = Project.extract(state)
- import extracted._
- // Swap version on projects
- val transformed = session.mergeSettings map ( s => f(s) )
- val newStructure = Load.reapply(transformed, structure)
- val newState = Project.setProject(session, newStructure, state)
- // TODO - Run tasks. Specifically, push scala-compiler + scala-library. *Then* bump the STARR version locally.
- // The final course of this command should be:
- // publish-local
- // Project.evaluateTask(publishLocal, newState)
- // bump STARR version setting
- // TODO - Define Task
- // Rebuild quick + test to ensure it works
- // Project.evaluateTask(test, newState)
- // push STARR remotely
- Project.evaluateTask(publish, newState)
+ // TODO do something
// Revert to previous project state.
- Project.setProject(session, structure, state)
+ state
}
- // TODO - Autocomplete
- /*lazy val setStarrHome = Command.single("set-starr-home") { (state: State, homeDir: String) =>
- def f(s: Setting[_]): Setting[_] =
- if(s.key.key == scalaInstance.key) {
- s.asInstanceOf[Setting[ScalaInstance]] mapInit { (key, value) =>
- if(value.version == "starr")
- scalaInstance <<= appConfiguration map { app =>
- val launcher = app.provider.scalaProvider.launcher
- ScalaInstance("starr", new File(homeDir), launcher)
- }
- else value
- }
- } else s
- val extracted = Project.extract(state)
- import extracted._
- val transformed = session.mergeSettings map f
- val newStructure = Load.reapply(transformed, structure)
- Project.setProject(session, newStructure, state)
- }*/
-
- lazy val timeFormat = {
- val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss")
- formatter.setTimeZone(java.util.TimeZone.getTimeZone("GMT"))
- formatter
- }
-
- /** This generates a properties file, if it does not already exist, with the maximum lastmodified timestamp
- * of any source file. */
- def generatePropertiesFile(name: String)(baseDirectory: File, version: String, dir: File, git: GitRunner, s: TaskStreams): Seq[File] = {
- // TODO - We can probably clean this up by moving caching bits elsewhere perhaps....
- val target = dir / name
- // TODO - Regenerate on triggers, like recompilation or something...
- val fullVersion = makeFullVersionString(baseDirectory, version, git, s)
- def hasSameVersion: Boolean = {
- val props = new java.util.Properties
- val in = new java.io.FileInputStream(target)
- try props.load(in) finally in.close()
- def withoutDate(s: String): String = s.reverse.dropWhile (_ != '.').reverse
- withoutDate(fullVersion) == withoutDate(props getProperty "version.number")
- }
- if (!target.exists || !hasSameVersion) {
- makePropertiesFile(target, fullVersion)
- }
- target :: Nil
- }
-
- // This creates the *.properties file used to determine the current version of scala at runtime. TODO - move these somewhere utility like.
- def makePropertiesFile(f: File, version: String): Unit =
- IO.write(f, "version.number = "+version+"\ncopyright.string = Copyright 2002-2011, LAMP/EPFL")
-
- def makeFullVersionString(baseDirectory: File, baseVersion: String, git: GitRunner, s: TaskStreams) = baseVersion+"."+getGitRevision(baseDirectory, git, currentDay, s)
-
- // TODO - do we want this in the build number?
- def currentDay = (new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss")) format (new java.util.Date)
-
-
-
- def getGitRevision(baseDirectory: File, git: GitRunner, date: String, s: TaskStreams) = {
-
- val mergeBase = {
- // TODO - Cache this value.
- // git("merge-base","v2.8.2","v2.9.1","master")(baseDirectory, s.log)
- "df13e31bbb"
- }
- // current commit sha
- val sha =
- git("rev-list", "-n", "1", "HEAD")(baseDirectory, s.log)
-
- val commits =
- git("--no-pager", "log", "--pretty=oneline", mergeBase +"..HEAD")(baseDirectory, s.log) split "[\r\n]+" size
-
- "rdev-%d-%s-g%s" format (commits, date, sha.substring(0,7))
- }
-
}
diff --git a/project/ShaResolve.scala b/project/ShaResolve.scala
index f54e96c0c6..e6824ee464 100644
--- a/project/ShaResolve.scala
+++ b/project/ShaResolve.scala
@@ -40,6 +40,8 @@ object ShaResolve {
throw t
}
+ // TODO - Finish this publishing aspect.
+
def getShaFromShafile(file: File): String = parseShaFile(file)._2
// This should calculate the SHA sum of a file the same as the linux process.
diff --git a/project/Versions.scala b/project/Versions.scala
new file mode 100644
index 0000000000..5f1fe0cacc
--- /dev/null
+++ b/project/Versions.scala
@@ -0,0 +1,142 @@
+import sbt._
+import Keys._
+import java.util.Properties
+import scala.util.control.Exception.catching
+import java.lang.{NumberFormatException => NFE}
+import java.io.FileInputStream
+import com.jsuereth.git.GitRunner
+import com.jsuereth.git.GitKeys.gitRunner
+
+case class VersionInfo(canonical: String,
+ maven: String,
+ osgi: String)
+
+/** this file is responsible for setting up Scala versioning schemes and updating all the necessary bits. */
+object Versions {
+ val buildNumberFile = SettingKey[File]("scala-build-number-file")
+ // TODO - Make this a setting?
+ val buildNumberProps = SettingKey[BaseBuildNumber]("scala-build-number-props")
+ val buildRelease = SettingKey[Boolean]("scala-build-release", "This is set to true if we're building a release.")
+ val mavenSuffix = SettingKey[String]("scala-maven-suffix", "This is set to whatever maven suffix is required.")
+
+ val gitSha = TaskKey[String]("scala-git-sha", "The sha of the current git commit.")
+ val gitDate = TaskKey[String]("scala-git-date", "The date of the current git commit.")
+
+ val mavenVersion = SettingKey[String]("scala-maven-version", "The maven version number.")
+ val osgiVersion = TaskKey[String]("scala-osgi-version", "The OSGi version number.")
+ val canonicalVersion = TaskKey[String]("scala-canonical-version", "The canonical version number.")
+
+ val scalaVersions = TaskKey[VersionInfo]("scala-version-info", "The scala versions used for this build.")
+
+
+
+ def settings: Seq[Setting[_]] = Seq(
+ buildNumberFile <<= baseDirectory apply (_ / "build.number"),
+ buildNumberProps <<= buildNumberFile apply loadBuildNumberProps,
+ buildRelease := Option(System.getProperty("build.release")) map (!_.isEmpty) getOrElse false,
+ mavenSuffix <<= buildRelease apply pickMavenSuffix,
+ mavenVersion <<= (buildNumberProps, mavenSuffix) apply makeMavenVersion,
+ gitSha <<= (gitRunner, baseDirectory, streams) map getGitSha,
+ gitDate <<= (gitRunner, baseDirectory, streams) map getGitDate,
+ osgiVersion <<= (buildNumberProps, gitDate, gitSha) map makeOsgiVersion,
+ canonicalVersion <<= (buildRelease, mavenVersion, buildNumberProps, gitDate, gitSha) map makeCanonicalVersion,
+ scalaVersions <<= (canonicalVersion, mavenVersion, osgiVersion) map VersionInfo.apply
+ )
+
+
+ /** This generates a properties file, if it does not already exist, with the maximum lastmodified timestamp
+ * of any source file. */
+ def generateVersionPropertiesFile(name: String)(dir: File, versions: VersionInfo, s: TaskStreams): Seq[File] = {
+ // TODO - We can probably clean this up by moving caching bits elsewhere perhaps....
+ val target = dir / name
+ // TODO - Regenerate on triggers, like recompilation or something...
+ def hasSameVersion: Boolean = {
+ val props = new java.util.Properties
+ val in = new java.io.FileInputStream(target)
+ try props.load(in) finally in.close()
+ versions.canonical == (props getProperty "version.number")
+ }
+ if (!target.exists || !hasSameVersion) {
+ makeVersionPropertiesFile(target, versions)
+ }
+ target :: Nil
+ }
+
+ // This creates the *.properties file used to determine the current version of scala at runtime. TODO - move these somewhere utility like.
+ def makeVersionPropertiesFile(f: File, versions: VersionInfo): Unit =
+ IO.write(f, "version.number = "+versions.canonical+"\n"+
+ "osgi.number = "+versions.osgi+"\n"+
+ "maven.number = "+versions.maven+"\n"+
+ "copyright.string = Copyright 2002-2011, LAMP/EPFL")
+
+ def makeCanonicalVersion(isRelease: Boolean, mvnVersion: String, base: BaseBuildNumber, gitDate: String, gitSha: String): String =
+ if(isRelease) mvnVersion
+ else {
+ val suffix = if(base.bnum > 0) "-%d".format(base.bnum) else ""
+ "%s.%s.%s%s-%s-%s" format (base.major, base.minor, base.patch, suffix, gitDate, gitSha)
+ }
+
+ def makeMavenVersion(base: BaseBuildNumber, suffix: String): String = {
+ val firstSuffix = if(base.bnum > 0) "-%d".format(base.bnum) else ""
+ "%d.%d.%d%s%s" format (base.major, base.minor, base.patch, firstSuffix, suffix)
+ }
+
+ def makeOsgiVersion(base: BaseBuildNumber, gitDate: String, gitSha: String): String = {
+ val suffix = if(base.bnum > 0) "-%d".format(base.bnum) else ""
+ "%s.%s.%s.v%s%s-%s" format (base.major, base.minor, base.patch, gitDate, suffix, gitSha)
+ }
+
+ /** Determines what the maven sufffix should be for this build. */
+ def pickMavenSuffix(isRelease: Boolean): String = {
+ def default = if(isRelease) "" else "-SNAPSHOT"
+ Option(System.getProperty("maven.version.suffix")) getOrElse default
+ }
+
+ /** Loads the build.number properties file into SBT. */
+ def loadBuildNumberProps(file: File): BaseBuildNumber = {
+ val fin = new FileInputStream(file)
+ try {
+ val props = new Properties()
+ props.load(fin)
+ def getProp(name: String): Int =
+ (for {
+ v <- Option(props.getProperty(name))
+ v2 <- catching(classOf[NFE]) opt v.toInt
+ } yield v2) getOrElse sys.error("Could not convert %s to integer!" format (name))
+
+ BaseBuildNumber(
+ major=getProp("version.major"),
+ minor=getProp("version.minor"),
+ patch=getProp("version.patch"),
+ bnum =getProp("version.bnum")
+ )
+ } finally fin.close()
+ }
+
+
+ def getGitDate(git: GitRunner, baseDirectory: File, s: TaskStreams): String = {
+ val lines = getGitLines("log","-1","--format=\"%ci\"")(git,baseDirectory, s)
+ val line = if(lines.isEmpty) sys.error("Could not retreive git commit sha!") else lines.head
+ // Lines *always* start with " for some reason...
+ line drop 1 split "\\s+" match {
+ case Array(date, time, _*) => "%s-%s" format (date.replaceAll("\\-", ""), time.replaceAll(":",""))
+ case _ => sys.error("Could not parse git date: " + line)
+ }
+ }
+
+ def getGitSha(git: GitRunner, baseDirectory: File, s: TaskStreams): String = {
+ val lines = getGitLines("log","-1","--format=\"%H\"", "HEAD")(git,baseDirectory, s)
+ val line = if(lines.isEmpty) sys.error("Could not retreive git commit sha!") else lines.head
+ val noquote = if(line startsWith "\"") line drop 1 else line
+ val nog = if(noquote startsWith "g") noquote drop 1 else noquote
+ nog take 10
+ }
+
+ def getGitLines(args: String*)(git: GitRunner, baseDirectory: File, s: TaskStreams): Seq[String] =
+ git(args: _*)(baseDirectory, s.log) split "[\r\n]+"
+}
+
+
+case class BaseBuildNumber(major: Int, minor: Int, patch: Int, bnum: Int) {
+ override def toString = "BaseBuildNumber(%d.%d.%d-%d)" format (major, minor, patch, bnum)
+}