Backwards compatibility check for getScala method.

Added groupId dependant baseDirectoryName.
General code cleanup.
This commit is contained in:
Vojin Jovanovic 2012-04-11 04:04:21 +02:00
parent f17cb88d00
commit cbb8caef0c
4 changed files with 41 additions and 43 deletions

View File

@ -53,22 +53,12 @@ private object BootConfiguration
val DefaultIvyConfiguration = "default"
private val ScalaDirectoryName = "lib"
/** The name of the directory within the boot directory to retrieve scala to.
* scalaOrg is appended if non-standard scala is used.
*
* The reason for this inconsistency is backward compatiblity and
* relatively infrequent use of non-standard scalaOrg */
def scalaDirectoryName(scalaOrg: String) = scalaOrg match {
case ScalaOrg => ScalaDirectoryName
case _ => ScalaDirectoryName + "-" + scalaOrg
}
val ScalaDirectoryName = "lib"
/** The Ivy pattern to use for retrieving the scala compiler and library. It is relative to the directory
* containing all jars for the requested version of scala.
*/
def scalaRetrievePattern(scalaOrg: String) = scalaDirectoryName(scalaOrg) + "/[artifact](-[classifier]).[ext]"
val scalaRetrievePattern = ScalaDirectoryName + "/[artifact](-[classifier]).[ext]"
def artifactType(classifier: String) =
classifier match
@ -82,20 +72,23 @@ private object BootConfiguration
* containing all jars for the requested version of scala. */
def appRetrievePattern(appID: xsbti.ApplicationID) = appDirectoryName(appID, "/") + "(/[component])/[artifact]-[revision](-[classifier]).[ext]"
val ScalaDirPrefix = "scala-"
val ScalaVersionPrefix = ".scala-"
/** The name of the directory to retrieve the application and its dependencies to.*/
def appDirectoryName(appID: xsbti.ApplicationID, sep: String) = appID.groupID + sep + appID.name + sep + appID.version
/** The name of the directory in the boot directory to put all jars for the given version of scala in.*/
def baseDirectoryName(scalaVersion: Option[String]) = scalaVersion match {
def baseDirectoryName(scalaOrg: String, scalaVersion: Option[String]) = scalaVersion match {
case None => "other"
case Some(sv) => ScalaDirPrefix + sv
case Some(sv) => scalaOrg + ScalaVersionPrefix + sv
}
def extractScalaVersion(dir: File): Option[String] =
{
val name = dir.getName
if(name.startsWith(ScalaDirPrefix)) Some(name.substring(ScalaDirPrefix.length)) else None
if(name.contains(ScalaVersionPrefix))
Some(name.substring(name.lastIndexOf(ScalaVersionPrefix) + ScalaVersionPrefix.length))
else
None
}
}
private object ProxyProperties

View File

@ -77,14 +77,14 @@ object Launch
}
final class RunConfiguration(val scalaVersion: Option[String], val app: xsbti.ApplicationID, val workingDirectory: File, val arguments: List[String])
import BootConfiguration.{appDirectoryName, baseDirectoryName, extractScalaVersion, scalaDirectoryName, TestLoadScalaClasses}
import BootConfiguration.{appDirectoryName, baseDirectoryName, extractScalaVersion, ScalaDirectoryName, TestLoadScalaClasses, ScalaOrg}
class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val ivyOptions: IvyOptions) extends xsbti.Launcher
{
import ivyOptions.{checksums => checksumsList, classifiers, repositories}
bootDirectory.mkdirs
private val scalaProviders = new Cache[(String, String), String, xsbti.ScalaProvider]((x, y) => getScalaProvider(x._1, x._2, y))
def getScala(version: String): xsbti.ScalaProvider = getScala(version, "")
def getScala(version: String, reason: String): xsbti.ScalaProvider = getScala(version, reason, BootConfiguration.ScalaOrg)
def getScala(version: String, reason: String): xsbti.ScalaProvider = getScala(version, reason, ScalaOrg)
def getScala(version: String, reason: String, scalaOrg: String) = scalaProviders((scalaOrg, version), reason)
def app(id: xsbti.ApplicationID, version: String): xsbti.AppProvider = app(id, Option(version))
def app(id: xsbti.ApplicationID, scalaVersion: Option[String]): xsbti.AppProvider =
@ -103,8 +103,8 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
def jnaLoader(parent: ClassLoader): ClassLoader =
{
val id = AppID("net.java.dev.jna", "jna", "3.2.3", "", toArray(Nil), false, array())
val configuration = makeConfiguration(None, None)
val jnaHome = appDirectory(new File(bootDirectory, baseDirectoryName(None)), id)
val configuration = makeConfiguration(ScalaOrg, None)
val jnaHome = appDirectory(new File(bootDirectory, baseDirectoryName(ScalaOrg, None)), id)
val module = appModule(id, None, false, "jna")
def makeLoader(): ClassLoader = {
val urls = toURLs(wrapNull(jnaHome.listFiles(JarFilter)))
@ -130,7 +130,7 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
module.retrieveCorrupt(missing)
}
private[this] def makeConfiguration(scalaOrg: Option[String], version: Option[String]): UpdateConfiguration =
private[this] def makeConfiguration(scalaOrg: String, version: Option[String]): UpdateConfiguration =
new UpdateConfiguration(bootDirectory, ivyOptions.ivyHome, scalaOrg, version, repositories, checksumsList)
final def getAppProvider(id: xsbti.ApplicationID, explicitScalaVersion: Option[String], forceAppUpdate: Boolean): xsbti.AppProvider =
@ -143,13 +143,13 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
def retrieve() = {
val sv = update(app, "")
val scalaVersion = strictOr(explicitScalaVersion, sv)
new RetrievedModule(true, app, sv, baseDirs(scalaHome(scalaVersion)))
new RetrievedModule(true, app, sv, baseDirs(scalaHome(ScalaOrg, scalaVersion)))
}
val retrievedApp =
if(forceAppUpdate)
retrieve()
else
existing(app, explicitScalaVersion, baseDirs) getOrElse retrieve()
existing(app, ScalaOrg, explicitScalaVersion, baseDirs) getOrElse retrieve()
val scalaVersion = getOrError(strictOr(explicitScalaVersion, retrievedApp.detectedScalaVersion), "No Scala version specified or detected")
val scalaProvider = getScala(scalaVersion, "(for " + id.name + ")")
@ -162,8 +162,8 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
else
getAppProvider0(id, explicitScalaVersion, true)
}
def scalaHome(scalaVersion: Option[String]): File = new File(bootDirectory, baseDirectoryName(scalaVersion))
def appHome(id: xsbti.ApplicationID, scalaVersion: Option[String]): File = appDirectory(scalaHome(scalaVersion), id)
def scalaHome(scalaOrg: String, scalaVersion: Option[String]): File = new File(bootDirectory, baseDirectoryName(scalaOrg, scalaVersion))
def appHome(id: xsbti.ApplicationID, scalaVersion: Option[String]): File = appDirectory(scalaHome(ScalaOrg, scalaVersion), id)
def checkedAppProvider(id: xsbti.ApplicationID, module: RetrievedModule, scalaProvider: xsbti.ScalaProvider): (Iterable[String], xsbti.AppProvider) =
{
val p = appProvider(id, module, scalaProvider, appHome(id, Some(scalaProvider.version)))
@ -183,7 +183,7 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
val p = scalaProvider(scalaVersion, retrieved, topLoader, lib)
checkLoader(p.loader, retrieved.definition, TestLoadScalaClasses, p)
}
existing(scalaM, Some(scalaVersion), _ => baseDirs) flatMap { mod =>
existing(scalaM, scalaOrg, Some(scalaVersion), _ => baseDirs) flatMap { mod =>
try Some(provider(mod))
catch { case e: Exception => None }
} getOrElse {
@ -192,10 +192,10 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
}
}
def existing(module: ModuleDefinition, explicitScalaVersion: Option[String], baseDirs: File => List[File]): Option[RetrievedModule] =
def existing(module: ModuleDefinition, scalaOrg: String, explicitScalaVersion: Option[String], baseDirs: File => List[File]): Option[RetrievedModule] =
{
val filter = new java.io.FileFilter {
val explicitName = explicitScalaVersion.map(sv => baseDirectoryName(Some(sv)))
val explicitName = explicitScalaVersion.map(sv => baseDirectoryName(scalaOrg, Some(sv)))
def accept(file: File) = file.isDirectory && explicitName.forall(_ == file.getName)
}
val retrieved = wrapNull(bootDirectory.listFiles(filter)) flatMap { scalaDir =>
@ -222,8 +222,8 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
def scalaDirs(module: ModuleDefinition, scalaOrg: String, scalaVersion: String): (File, File) =
{
val scalaHome = new File(bootDirectory, baseDirectoryName(Some(scalaVersion)))
val libDirectory = new File(scalaHome, scalaDirectoryName(scalaOrg))
val scalaHome = new File(bootDirectory, baseDirectoryName(scalaOrg, Some(scalaVersion)))
val libDirectory = new File(scalaHome, ScalaDirectoryName)
(scalaHome, libDirectory)
}
@ -258,13 +258,13 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
}
def appModule(id: xsbti.ApplicationID, scalaVersion: Option[String], getClassifiers: Boolean, tpe: String): ModuleDefinition = new ModuleDefinition(
configuration = makeConfiguration(None, scalaVersion),
configuration = makeConfiguration(ScalaOrg, scalaVersion),
target = new UpdateApp(Application(id), if(getClassifiers) Value.get(classifiers.app) else Nil, tpe),
failLabel = id.name + " " + id.version,
extraClasspath = id.classpathExtra
)
def scalaModule(org: String, version: String): ModuleDefinition = new ModuleDefinition(
configuration = makeConfiguration(Some(org), Some(version)),
configuration = makeConfiguration(org, Some(version)),
target = new UpdateScala(Value.get(classifiers.forScala)),
failLabel = "Scala " + version,
extraClasspath = array()

View File

@ -33,12 +33,10 @@ sealed trait UpdateTarget { def tpe: String; def classifiers: List[String] }
final class UpdateScala(val classifiers: List[String]) extends UpdateTarget { def tpe = "scala" }
final class UpdateApp(val id: Application, val classifiers: List[String], val tpe: String) extends UpdateTarget
final class UpdateConfiguration(val bootDirectory: File, val ivyHome: Option[File], val scalaOrg: Option[String],
final class UpdateConfiguration(val bootDirectory: File, val ivyHome: Option[File], val scalaOrg: String,
val scalaVersion: Option[String], val repositories: List[xsbti.Repository], val checksums: List[String]) {
def getScalaVersion = scalaVersion match { case Some(sv) => sv; case None => "" }
def getScalaOrg = scalaOrg match { case Some(so) => so; case None => ScalaOrg }
def getScalaVersion = scalaVersion match { case Some(sv) => sv; case None => "" }
}
@ -47,7 +45,7 @@ final class UpdateResult(val success: Boolean, val scalaVersion: Option[String])
/** Ensures that the Scala and application jars exist for the given versions or else downloads them.*/
final class Update(config: UpdateConfiguration)
{
import config.{bootDirectory, checksums, getScalaVersion, ivyHome, repositories, scalaVersion, getScalaOrg}
import config.{bootDirectory, checksums, getScalaVersion, ivyHome, repositories, scalaVersion, scalaOrg}
bootDirectory.mkdirs
private def logFile = new File(bootDirectory, UpdateLogName)
@ -132,12 +130,11 @@ final class Update(config: UpdateConfiguration)
target match
{
case u: UpdateScala =>
val scalaVersion = getScalaVersion
val scalaOrg = getScalaOrg
val scalaVersion = getScalaVersion
addDependency(moduleID, scalaOrg, CompilerModuleName, scalaVersion, "default;optional(default)", u.classifiers)
addDependency(moduleID, scalaOrg, LibraryModuleName, scalaVersion, "default", u.classifiers)
excludeJUnit(moduleID)
System.out.println("Getting Scala " + scalaVersion + " " + reason + "...")
System.out.println("Getting " + scalaOrg + " Scala " + scalaVersion + " " + reason + "...")
case u: UpdateApp =>
val app = u.id
val resolvedName = (app.crossVersioned, scalaVersion) match {
@ -239,13 +236,13 @@ final class Update(config: UpdateConfiguration)
val (pattern, extraFilter) =
target match
{
case _: UpdateScala => (scalaRetrievePattern(getScalaOrg), const(true))
case _: UpdateScala => (scalaRetrievePattern, const(true))
case u: UpdateApp => (appRetrievePattern(u.id.toID), notCoreScala _)
}
val filter = (a: IArtifact) => retrieveType(a.getType) && a.getExtraAttribute("classifier") == null && extraFilter(a)
retrieveOptions.setArtifactFilter(new ArtifactFilter(filter))
val scalaV = strictOr(scalaVersion, autoScalaVersion)
retrieveEngine.retrieve(module.getModuleRevisionId, baseDirectoryName(scalaV) + "/" + pattern, retrieveOptions)
retrieveEngine.retrieve(module.getModuleRevisionId, baseDirectoryName(scalaOrg, scalaV) + "/" + pattern, retrieveOptions)
}
private[this] def notCoreScala(a: IArtifact) = a.getName match {
case LibraryModuleName | CompilerModuleName => false

View File

@ -23,8 +23,16 @@ object ScalaInstance
{
val VersionPrefix = "version "
def apply(org: String, version: String, launcher: xsbti.Launcher): ScalaInstance =
def apply(org: String, version: String, launcher: xsbti.Launcher): ScalaInstance = {
// launcher compatibility check
val strClass = "".getClass
if (launcher.getClass.getMethods.exists(m =>
m.getName == "getScala" &&
m.getParameterTypes.toSeq == Seq(strClass, strClass, strClass)))
apply(version, launcher.getScala(version, "", org))
else
error("Incompatible version of the xsbti.Launcher interface. Use sbt-0.12.x launcher instead.")
}
/** Creates a ScalaInstance using the given provider to obtain the jars and loader.*/
def apply(version: String, launcher: xsbti.Launcher): ScalaInstance =
apply(version, launcher.getScala(version))