Adding `scalaOrg` setting key for scala clones.

Adding scalaOrg key that specifies organization (artifactId) of scala used in the project. The change does not affect version checks for dependecies and LauncherConfiguration.

Modified scalaProvider cache in Launcher to use (scalaOrg, version) as a key.

Downloaded jars are stored in the folder scala-.../lig-<scalaOrg> if scalaOrg is not default.

scala-org is an advanced setting so it can not be used in build.sbt.
This commit is contained in:
Vojin Jovanovic 2012-04-04 19:06:55 +02:00
parent 602e5e2f27
commit 182b7c655f
8 changed files with 56 additions and 31 deletions

View File

@ -53,11 +53,22 @@ private object BootConfiguration
val DefaultIvyConfiguration = "default"
/** The name of the directory within the boot directory to retrieve scala to. */
val ScalaDirectoryName = "lib"
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
}
/** 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. */
val scalaRetrievePattern = ScalaDirectoryName + "/[artifact](-[classifier]).[ext]"
* containing all jars for the requested version of scala.
*/
def scalaRetrievePattern(scalaOrg: String) = scalaDirectoryName(scalaOrg) + "/[artifact](-[classifier]).[ext]"
def artifactType(classifier: String) =
classifier match
@ -80,6 +91,7 @@ private object BootConfiguration
case None => "other"
case Some(sv) => ScalaDirPrefix + sv
}
def extractScalaVersion(dir: File): Option[String] =
{
val name = dir.getName

View File

@ -77,18 +77,17 @@ 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}
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, xsbti.ScalaProvider](getScalaProvider(_,_))
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 = scalaProviders(version, reason)
def getScala(version: String, reason: String): xsbti.ScalaProvider = getScala(BootConfiguration.ScalaOrg, version, reason)
def getScala(scalaOrg: String, version: String, reason: 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 =
getAppProvider(id, scalaVersion, false)
def app(id: xsbti.ApplicationID, scalaVersion: Option[String]): xsbti.AppProvider = getAppProvider(id, scalaVersion, false)
val bootLoader = new BootFilteredLoader(getClass.getClassLoader)
val topLoader = jnaLoader(bootLoader)
@ -102,7 +101,7 @@ 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)
val configuration = makeConfiguration(None, None)
val jnaHome = appDirectory(new File(bootDirectory, baseDirectoryName(None)), id)
val module = appModule(id, None, false, "jna")
def makeLoader(): ClassLoader = {
@ -129,8 +128,8 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
module.retrieveCorrupt(missing)
}
private[this] def makeConfiguration(version: Option[String]): UpdateConfiguration =
new UpdateConfiguration(bootDirectory, ivyOptions.ivyHome, version, repositories, checksumsList)
private[this] def makeConfiguration(scalaOrg: Option[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 =
locked(new Callable[xsbti.AppProvider] { def call = getAppProvider0(id, explicitScalaVersion, forceAppUpdate) })
@ -149,7 +148,7 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
retrieve()
else
existing(app, explicitScalaVersion, baseDirs) getOrElse retrieve()
val scalaVersion = getOrError(strictOr(explicitScalaVersion, retrievedApp.detectedScalaVersion), "No Scala version specified or detected")
val scalaProvider = getScala(scalaVersion, "(for " + id.name + ")")
@ -170,13 +169,13 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
(missing, p)
}
private[this] def locked[T](c: Callable[T]): T = Locks(orNull(updateLockFile), c)
def getScalaProvider(scalaVersion: String, reason: String): xsbti.ScalaProvider =
locked(new Callable[xsbti.ScalaProvider] { def call = getScalaProvider0(scalaVersion, reason) })
def getScalaProvider(scalaOrg: String, scalaVersion: String, reason: String): xsbti.ScalaProvider =
locked(new Callable[xsbti.ScalaProvider] { def call = getScalaProvider0(scalaOrg, scalaVersion, reason) })
private[this] final def getScalaProvider0(scalaVersion: String, reason: String) =
private[this] final def getScalaProvider0(scalaOrg: String, scalaVersion: String, reason: String) =
{
val scalaM = scalaModule(scalaVersion)
val (scalaHome, lib) = scalaDirs(scalaM, scalaVersion)
val scalaM = scalaModule(scalaOrg, scalaVersion)
val (scalaHome, lib) = scalaDirs(scalaM, scalaOrg, scalaVersion)
val baseDirs = lib :: Nil
def provider(retrieved: RetrievedModule): xsbti.ScalaProvider = {
val p = scalaProvider(scalaVersion, retrieved, topLoader, lib)
@ -219,10 +218,10 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i
def appDirectory(base: File, id: xsbti.ApplicationID): File =
new File(base, appDirectoryName(id, File.separator))
def scalaDirs(module: ModuleDefinition, scalaVersion: String): (File, File) =
def scalaDirs(module: ModuleDefinition, scalaOrg: String, scalaVersion: String): (File, File) =
{
val scalaHome = new File(bootDirectory, baseDirectoryName(Some(scalaVersion)))
val libDirectory = new File(scalaHome, ScalaDirectoryName)
val libDirectory = new File(scalaHome, scalaDirectoryName(scalaOrg))
(scalaHome, libDirectory)
}
@ -257,13 +256,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(scalaVersion),
configuration = makeConfiguration(None, 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(version: String): ModuleDefinition = new ModuleDefinition(
configuration = makeConfiguration(Some(version)),
def scalaModule(org: String, version: String): ModuleDefinition = new ModuleDefinition(
configuration = makeConfiguration(Some(org), Some(version)),
target = new UpdateScala(Value.get(classifiers.forScala)),
failLabel = "Scala " + version,
extraClasspath = array()

View File

@ -15,12 +15,14 @@ final case class LaunchConfiguration(scalaVersion: Value[String], ivyConfigurati
val sv = Value.get(scalaVersion)
if(sv == "auto") None else Some(sv)
}
def withScalaVersion(newScalaVersion: String) = LaunchConfiguration(new Explicit(newScalaVersion), ivyConfiguration, app, boot, logging, appProperties)
def withApp(app: Application) = LaunchConfiguration(scalaVersion, ivyConfiguration, app, boot, logging, appProperties)
def withAppVersion(newAppVersion: String) = LaunchConfiguration(scalaVersion, ivyConfiguration, app.withVersion(new Explicit(newAppVersion)), boot, logging, appProperties)
// TODO: withExplicit
def withVersions(newScalaVersion: String, newAppVersion: String, classifiers0: Classifiers) =
LaunchConfiguration(new Explicit(newScalaVersion), ivyConfiguration.copy(classifiers = classifiers0), app.withVersion(new Explicit(newAppVersion)), boot, logging, appProperties)
def map(f: File => File) = LaunchConfiguration(scalaVersion, ivyConfiguration, app.map(f), boot.map(f), logging, appProperties)
}
final case class IvyOptions(ivyHome: Option[File], classifiers: Classifiers, repositories: List[xsbti.Repository], checksums: List[String])

View File

@ -33,8 +33,13 @@ 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 scalaVersion: Option[String], val repositories: List[xsbti.Repository], val checksums: List[String]) {
final class UpdateConfiguration(val bootDirectory: File, val ivyHome: Option[File], val scalaOrg: Option[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 }
}
final class UpdateResult(val success: Boolean, val scalaVersion: Option[String])
@ -42,7 +47,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}
import config.{bootDirectory, checksums, getScalaVersion, ivyHome, repositories, scalaVersion, getScalaOrg}
bootDirectory.mkdirs
private def logFile = new File(bootDirectory, UpdateLogName)
@ -128,8 +133,9 @@ final class Update(config: UpdateConfiguration)
{
case u: UpdateScala =>
val scalaVersion = getScalaVersion
addDependency(moduleID, ScalaOrg, CompilerModuleName, scalaVersion, "default;optional(default)", u.classifiers)
addDependency(moduleID, ScalaOrg, LibraryModuleName, scalaVersion, "default", u.classifiers)
val scalaOrg = getScalaOrg
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 + "...")
case u: UpdateApp =>
@ -233,7 +239,7 @@ final class Update(config: UpdateConfiguration)
val (pattern, extraFilter) =
target match
{
case _: UpdateScala => (scalaRetrievePattern, const(true))
case _: UpdateScala => (scalaRetrievePattern(getScalaOrg), const(true))
case u: UpdateApp => (appRetrievePattern(u.id.toID), notCoreScala _)
}
val filter = (a: IArtifact) => retrieveType(a.getType) && a.getExtraAttribute("classifier") == null && extraFilter(a)

View File

@ -7,6 +7,7 @@ public interface Launcher
public static final int InterfaceVersion = 1;
public ScalaProvider getScala(String version);
public ScalaProvider getScala(String version, String reason);
public ScalaProvider getScala(String scalaOrg, String version, String reason);
public AppProvider app(ApplicationID id, String version);
public ClassLoader topLoader();
public GlobalLock globalLock();

View File

@ -52,6 +52,7 @@ object Defaults extends BuildCommon
))
def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(defaultTestTasks(test) ++ defaultTestTasks(testOnly) ++ defaultTestTasks(testQuick) ++ Seq(
crossVersion :== CrossVersion.Disabled,
scalaOrg :== "org.scala-lang",
buildDependencies <<= buildDependencies or Classpaths.constructBuildDependencies,
taskTemporaryDirectory := IO.createTemporaryDirectory,
onComplete <<= taskTemporaryDirectory { dir => () => IO.delete(dir); IO.createDirectory(dir) },
@ -264,10 +265,10 @@ object Defaults extends BuildCommon
}
}
}
def scalaInstanceSetting = (appConfiguration, scalaVersion, scalaHome) map { (app, version, home) =>
def scalaInstanceSetting = (appConfiguration, scalaOrg, scalaVersion, scalaHome) map { (app, scalaOrg, version, home) =>
val launcher = app.provider.scalaProvider.launcher
home match {
case None => ScalaInstance(version, launcher)
case None => ScalaInstance(scalaOrg, version, launcher)
case Some(h) => ScalaInstance(h, launcher)
}
}

View File

@ -135,6 +135,7 @@ object Keys
val compileInputs = TaskKey[Compiler.Inputs]("compile-inputs", "Collects all inputs needed for compilation.", DTask)
val scalaHome = SettingKey[Option[File]]("scala-home", "If Some, defines the local Scala installation to use for compilation, running, and testing.", ASetting)
val scalaInstance = TaskKey[ScalaInstance]("scala-instance", "Defines the Scala instance to use for compilation, running, and testing.", DTask)
val scalaOrg = SettingKey[String]("scala-org", "Artifact id of Scala scala used in the project.", CSetting)
val scalaVersion = SettingKey[String]("scala-version", "The version of Scala used for building.", APlusSetting)
val scalaBinaryVersion = SettingKey[String]("scala-binary-version", "The Scala version substring describing binary compatibility.", BPlusSetting)
val crossScalaVersions = SettingKey[Seq[String]]("cross-scala-versions", "The versions of Scala used when cross-building.", BPlusSetting)

View File

@ -22,6 +22,9 @@ final class ScalaInstance(val version: String, val loader: ClassLoader, val libr
object ScalaInstance
{
val VersionPrefix = "version "
def apply(org: String, version: String, launcher: xsbti.Launcher): ScalaInstance =
apply(version, launcher.getScala(org, version, ""))
/** 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))