mirror of https://github.com/sbt/sbt.git
75 lines
3.3 KiB
Scala
75 lines
3.3 KiB
Scala
|
|
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)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|