mirror of https://github.com/sbt/sbt.git
Merge 'vjovanov/0.12' into 0.12
This commit is contained in:
commit
2aad26a5ba
|
|
@ -53,10 +53,11 @@ private object BootConfiguration
|
|||
|
||||
val DefaultIvyConfiguration = "default"
|
||||
|
||||
/** The name of the directory within the boot directory to retrieve scala to. */
|
||||
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. */
|
||||
* containing all jars for the requested version of scala.
|
||||
*/
|
||||
val scalaRetrievePattern = ScalaDirectoryName + "/[artifact](-[classifier]).[ext]"
|
||||
|
||||
def artifactType(classifier: String) =
|
||||
|
|
@ -71,19 +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) => (if (scalaOrg == ScalaOrg) "" else 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
|
||||
|
|
|
|||
|
|
@ -77,17 +77,18 @@ 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, 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(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 =
|
||||
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,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)
|
||||
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)))
|
||||
|
|
@ -129,8 +130,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: 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) })
|
||||
|
|
@ -142,14 +143,14 @@ 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 + ")")
|
||||
|
||||
|
|
@ -161,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)))
|
||||
|
|
@ -170,19 +171,19 @@ 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)
|
||||
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 {
|
||||
|
|
@ -191,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 =>
|
||||
|
|
@ -219,9 +220,9 @@ 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 scalaHome = new File(bootDirectory, baseDirectoryName(scalaOrg, Some(scalaVersion)))
|
||||
val libDirectory = new File(scalaHome, ScalaDirectoryName)
|
||||
(scalaHome, libDirectory)
|
||||
}
|
||||
|
|
@ -257,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(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(version: String): ModuleDefinition = new ModuleDefinition(
|
||||
configuration = makeConfiguration(Some(version)),
|
||||
def scalaModule(org: String, version: String): ModuleDefinition = new ModuleDefinition(
|
||||
configuration = makeConfiguration(org, Some(version)),
|
||||
target = new UpdateScala(Value.get(classifiers.forScala)),
|
||||
failLabel = "Scala " + version,
|
||||
extraClasspath = array()
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -33,8 +33,11 @@ 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]) {
|
||||
def getScalaVersion = scalaVersion match { case Some(sv) => sv; case None => "" }
|
||||
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 => "" }
|
||||
|
||||
}
|
||||
|
||||
final class UpdateResult(val success: Boolean, val scalaVersion: Option[String])
|
||||
|
|
@ -42,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}
|
||||
import config.{bootDirectory, checksums, getScalaVersion, ivyHome, repositories, scalaVersion, scalaOrg}
|
||||
bootDirectory.mkdirs
|
||||
|
||||
private def logFile = new File(bootDirectory, UpdateLogName)
|
||||
|
|
@ -127,11 +130,12 @@ final class Update(config: UpdateConfiguration)
|
|||
target match
|
||||
{
|
||||
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 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 + "...")
|
||||
val scalaOrgString = if (scalaOrg != ScalaOrg) " " + scalaOrg else ""
|
||||
System.out.println("Getting" + scalaOrgString + " Scala " + scalaVersion + " " + reason + "...")
|
||||
case u: UpdateApp =>
|
||||
val app = u.id
|
||||
val resolvedName = (app.crossVersioned, scalaVersion) match {
|
||||
|
|
@ -239,7 +243,7 @@ final class Update(config: UpdateConfiguration)
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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 version, String reason, String scalaOrg);
|
||||
public AppProvider app(ApplicationID id, String version);
|
||||
public ClassLoader topLoader();
|
||||
public GlobalLock globalLock();
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ object Defaults extends BuildCommon
|
|||
))
|
||||
def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(defaultTestTasks(test) ++ defaultTestTasks(testOnly) ++ defaultTestTasks(testQuick) ++ Seq(
|
||||
crossVersion :== CrossVersion.Disabled,
|
||||
scalaOrganization :== ScalaArtifacts.Organization,
|
||||
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, scalaOrganization, scalaVersion, scalaHome) map { (app, org, version, home) =>
|
||||
val launcher = app.provider.scalaProvider.launcher
|
||||
home match {
|
||||
case None => ScalaInstance(version, launcher)
|
||||
case None => ScalaInstance(org, version, launcher)
|
||||
case Some(h) => ScalaInstance(h, launcher)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 scalaOrganization = SettingKey[String]("scala-organization", "Organization/group ID of the Scala used in the project. Default value is 'org.scala-lang'. This is an advanced setting used for clones of the Scala Language. It should be disregarded in standard use cases.", 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)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,19 @@ final class ScalaInstance(val version: String, val loader: ClassLoader, val libr
|
|||
}
|
||||
object ScalaInstance
|
||||
{
|
||||
val ScalaOrg = "org.scala-lang"
|
||||
val VersionPrefix = "version "
|
||||
|
||||
def apply(org: String, version: String, launcher: xsbti.Launcher): ScalaInstance =
|
||||
// Due to incompatibility with previous launchers if scalaOrg has default value revert to an existing method
|
||||
if (org == ScalaOrg)
|
||||
apply(version, launcher)
|
||||
else try {
|
||||
apply(version, launcher.getScala(version, "", org))
|
||||
} catch {
|
||||
case x: NoSuchMethodError => 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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue