Temporarily use a Scala home with '++ /path/to/scala/home'

This commit is contained in:
Mark Harrah 2013-01-28 17:14:53 -05:00
parent 13ea342b7a
commit 76a02c463f
4 changed files with 40 additions and 14 deletions

View File

@ -8,6 +8,7 @@ package sbt
import DefaultParsers._
import Def.{ScopedKey, Setting}
import Scope.GlobalScope
import java.io.File
object Cross
{
@ -16,25 +17,49 @@ object Cross
def switchParser(state: State): Parser[(String, String)] =
{
val knownVersions = crossVersions(state)
lazy val switchArgs = token(NotSpace.examples(knownVersions : _*)) ~ (token(Space ~> matched(state.combinedParser)) ?? "")
lazy val nextSpaced = spacedFirst(Switch)
token(Switch ~ OptSpace) flatMap { _ => switchArgs & nextSpaced }
def versionAndCommand(spacePresent: Boolean) = {
val knownVersions = crossVersions(state)
val version = token(StringBasic.examples(knownVersions : _*))
val spacedVersion = if(spacePresent) version else version & spacedFirst(Switch)
val optionalCommand = token(Space ~> matched(state.combinedParser)) ?? ""
spacedVersion ~ optionalCommand
}
token(Switch ~> OptSpace) flatMap { sp => versionAndCommand(!sp.isEmpty) }
}
def spacedFirst(name: String) = opOrIDSpaced(name) ~ any.+
lazy val switchVersion = Command.arb(requireSession(switchParser)) { case (state, (version, command)) =>
val x = Project.extract(state)
import x._
println("Setting version to " + version)
val add = (scalaVersion in GlobalScope :== version) :: (scalaHome in GlobalScope :== None) :: Nil
val cleared = session.mergeSettings.filterNot( crossExclude )
val home = IO.resolve(x.currentProject.base, new File(version))
val (add, exclude) =
if(home.exists) {
val instance = ScalaInstance(home)(state.classLoaderCache.apply _)
state.log.info("Setting Scala home to " + home + " with actual version " + instance.actualVersion)
val settings = Seq(
scalaVersion in GlobalScope :== instance.actualVersion,
scalaHome in GlobalScope :== Some(home),
scalaInstance in GlobalScope :== instance
)
(settings, excludeKeys(Set(scalaVersion.key, scalaHome.key, scalaInstance.key)))
} else {
state.log.info("Setting version to " + version)
val settings = Seq(
scalaVersion in GlobalScope :== version,
scalaHome in GlobalScope :== None
)
(settings, excludeKeys(Set(scalaVersion.key, scalaHome.key)))
}
val cleared = session.mergeSettings.filterNot( exclude )
val newStructure = Load.reapply(add ++ cleared, structure)
Project.setProject(session, newStructure, command :: state)
}
def crossExclude(s: Setting[_]): Boolean =
s.key match {
case ScopedKey( Scope(_, Global, Global, _), scalaHome.key | scalaVersion.key) => true
@deprecated("No longer used.", "0.13.0")
def crossExclude(s: Setting[_]): Boolean = excludeKeys(Set(scalaVersion.key, scalaHome.key))(s)
private[this] def excludeKeys(keys: Set[AttributeKey[_]]): Setting[_] => Boolean =
_.key match {
case ScopedKey( Scope(_, Global, Global, _), key) if keys.contains(key) => true
case _ => false
}

View File

@ -23,6 +23,7 @@ Features
- Support defining Projects in .sbt files: vals of type Project are added to the Build. Details below.
- New syntax for settings, tasks, and input tasks. Details below.
- Automatically link to external API scaladocs of dependencies by setting ``autoAPIMappings := true``. This requires at least Scala 2.10.1 and for dependencies to define ``apiURL`` for their scaladoc location. Mappings may be manually added to the ``apiMappings`` task as well.
- Support setting Scala home directory temporary using the switch command: ``++ /path/to/scala/home``.
Fixes
-----

View File

@ -132,13 +132,13 @@ General commands
- ``+ <command>`` Executes the project specified action or method for
all versions of Scala defined in the ``crossScalaVersions``
setting.
- ``++ <version> <command>`` Temporarily changes the version of Scala
- ``++ <version|home-directory> <command>`` Temporarily changes the version of Scala
building the project and executes the provided command. ``<command>``
is optional. The specified version of Scala is used until the project
is reloaded, settings are modified (such as by the ``set`` or
``session`` commands), or ``++`` is run again. ``<version>`` does not
need to be listed in the build definition, but it must be available
in a repository.
in a repository. Alternatively, specify the path to a Scala installation.
- ``; A ; B`` Execute A and if it succeeds, run B. Note that the
leading semicolon is required.
- ``eval <Scala-expression>`` Evaluates the given Scala expression and

View File

@ -142,5 +142,5 @@ isn't available for all Scala versions or it uses a different convention
than the default.
As a final note, you can use ``++ <version>`` to temporarily switch the
Scala version currently being used to build (see
:doc:`Running </Getting-Started/Running>` for details).
Scala version currently being used to build. ``<version>`` should be either a version for Scala published to a repository, as in ``++ 2.10.0`` or the path to a Scala home directory, as in ``++ /path/to/scala/home``. See
:doc:`/Detailed-Topics/Command-Line-Reference>` for details.