sbt/launch/ResolveVersions.scala

75 lines
3.3 KiB
Scala
Raw Normal View History

2009-09-26 08:18:04 +02:00
package xsbt.boot
import java.io.{File, FileInputStream, FileOutputStream}
import java.util.Properties
object ResolvedVersion extends Enumeration
{
val Explicit, Read, Prompted = Value
}
final case class ResolvedVersion(v: String, method: ResolvedVersion.Value) extends NotNull
object ResolveVersions
{
def apply(conf: LaunchConfiguration): (LaunchConfiguration, () => Unit) = (new ResolveVersions(conf))()
private def doNothing = () => ()
private def trim(s: String) = if(s eq null) None else notEmpty(s.trim)
private def notEmpty(s: String) = if(s.isEmpty) None else Some(s)
private def readProperties(propertiesFile: File) =
{
val properties = new Properties
if(propertiesFile.exists)
Using( new FileInputStream(propertiesFile) )( properties.load )
properties
}
private def userDeclined(label: String) = throw new BootException("No " + label +" version specified.")
private def promptVersion(label: String, default: Option[String]) =
{
val message = label + default.map(" [" + _ + "]").getOrElse("") + " : "
SimpleReader.readLine(message).flatMap(x => notEmpty(x) orElse(default)) getOrElse(userDeclined(label))
}
}
import ResolveVersions.{doNothing, notEmpty, promptVersion, readProperties, trim, userDeclined}
final class ResolveVersions(conf: LaunchConfiguration) extends NotNull
{
private def propertiesFile = conf.boot.properties
private lazy val properties = readProperties(propertiesFile)
def apply(): (LaunchConfiguration, () => Unit) =
{
import conf._
val appVersionProperty = app.name.toLowerCase.replaceAll("\\s+",".") + ".version"
val scalaVersion = (new Resolve("scala.version", "Scala"))(conf.scalaVersion)
val appVersion = (new Resolve(appVersionProperty, app.name))(app.version)
val prompted = Seq((scalaVersion, conf.scalaVersion), (appVersion, app.version)).exists {
case (resolved, original) => resolved.method == ResolvedVersion.Prompted &&
( original match { case Version.Implicit(Version.Implicit.ReadOrPrompt, _) => true; case _ => false } )
}
val finish = if(!prompted) doNothing else () => Using( new FileOutputStream(propertiesFile) ) { out => properties.store(out, "") }
( withVersions(scalaVersion.v, appVersion.v), finish )
}
private final class Resolve(versionProperty: String, label: String) extends NotNull
{
def noVersionInFile = throw new BootException("No " + versionProperty + " specified in " + propertiesFile)
def apply(v: Version): ResolvedVersion =
{
import Version.{Explicit, Implicit}
import Implicit.{Prompt, Read, ReadOrPrompt}
v match
{
case e: Explicit => ResolvedVersion(e.value, ResolvedVersion.Explicit)
case Implicit(Read , default) => ResolvedVersion(readVersion() orElse default getOrElse noVersionInFile, ResolvedVersion.Read )
case Implicit(Prompt, default) => ResolvedVersion(promptVersion(label, default), ResolvedVersion.Prompted)
case Implicit(ReadOrPrompt, default) => readOrPromptVersion(default)
}
}
def readVersion() = trim(properties.getProperty(versionProperty))
def readOrPromptVersion(default: Option[String]) =
readVersion().map(v => ResolvedVersion(v, ResolvedVersion.Read)) getOrElse
{
val prompted = promptVersion(label, default)
properties.setProperty(versionProperty, prompted)
ResolvedVersion( prompted, ResolvedVersion.Prompted)
}
}
}