cross building

+, ++ require a space
+ <command>
++ <scala-version> [command]
set scala versions in crossScalaVersions
This commit is contained in:
Mark Harrah 2011-04-09 20:42:57 -04:00
parent 8d06ba2d92
commit 2f2e24c87d
5 changed files with 59 additions and 4 deletions

View File

@ -39,7 +39,7 @@ object Command
def apply[T](name: String, briefHelp: (String, String), detail: String)(parser: State => Parser[T])(effect: (State,T) => State): Command =
apply(name, Help(name, briefHelp, detail) )(parser)(effect)
def apply[T](name: String, help: Help*)(parser: State => Parser[T])(effect: (State,T) => State): Command =
make(name, help : _* )(s => applyEffect(parser(s))(t => effect(s,t)) )
make(name, help : _* )(applyEffect(parser)(effect) )
def args(name: String, briefHelp: (String, String), detail: String, display: String)(f: (State, Seq[String]) => State): Command =
args(name, display, Help(name, briefHelp, detail) )(f)
@ -53,9 +53,12 @@ object Command
make(name, help : _*)( state => token(trimmed(any.+.string) map apply1(f, state)) )
def custom(parser: State => Parser[() => State], help: Seq[Help] = Nil): Command = new ArbitraryCommand(parser, help, AttributeMap.empty)
def arb[T](parser: State => Parser[T], help: Help*)(effect: (State, T) => State): Command = custom(applyEffect(parser)(effect), help)
def validID(name: String) = DefaultParsers.matches(OpOrID, name)
def applyEffect[T](parser: State => Parser[T])(effect: (State, T) => State): State => Parser[() => State] =
s => applyEffect(parser(s))(t => effect(s,t))
def applyEffect[T](p: Parser[T])(f: T => State): Parser[() => State] =
p map { t => () => f(t) }

50
main/Cross.scala Normal file
View File

@ -0,0 +1,50 @@
/* sbt -- Simple Build Tool
* Copyright 2011 Mark Harrah
*/
package sbt
import Keys._
import complete.{DefaultParsers, Parser}
import DefaultParsers._
object Cross
{
final val Switch = "++"
final val Cross = "+"
def switchParser(state: State): Parser[(String, String)] =
{
val knownVersions = crossVersions(state)
token(Switch ~ Space) flatMap { _ => token(NotSpace.examples(knownVersions : _*)) ~ (token(Space ~> matched(state.combinedParser)) ?? "") }
}
lazy val switchVersion = Command.arb(requireSession(switchParser)) { case (state, (version, command)) =>
val x = Project.extract(state)
import x._
val add = (scalaVersion := version) :: Nil
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, add)
val newStructure = Load.reapply(session.original ++ append, structure)
Project.setProject(session, newStructure, command :: state)
}
def crossParser(state: State): Parser[String] =
token(Cross ~ Space) flatMap { _ => token(matched(state.combinedParser)) }
lazy val crossBuild = Command.arb(requireSession(crossParser)) { (state, command) =>
val x = Project.extract(state)
import x._
val versions = crossVersions(state)
val current = scalaVersion in currentRef get structure.data map(Switch + " " + _) toList;
if(versions.isEmpty) command :: state else versions.map(Switch + " " + _ + " " + command) ::: current ::: state
}
def crossVersions(state: State): Seq[String] =
{
val x = Project.extract(state)
import x._
crossScalaVersions in currentRef get structure.data getOrElse Nil
}
def requireSession[T](p: State => Parser[T]): State => Parser[T] = s =>
if(s get sessionSettings isEmpty) failure("No project loaded") else p(s)
}

View File

@ -125,6 +125,7 @@ object Defaults
scalacOptions in GlobalScope :== Nil,
scalaInstance <<= scalaInstanceSetting,
scalaVersion in GlobalScope <<= appConfiguration( _.provider.scalaProvider.version),
crossScalaVersions <<= Seq(scalaVersion).join,
target <<= (target, scalaInstance, crossPaths)( (t,si,cross) => if(cross) t / ("scala-" + si.actualVersion) else t )
)

View File

@ -76,6 +76,7 @@ object Keys
val scalaHome = SettingKey[Option[File]]("scala-home")
val scalaInstance = SettingKey[ScalaInstance]("scala-instance")
val scalaVersion = SettingKey[String]("scala-version")
val crossScalaVersions = SettingKey[Seq[String]]("cross-scala-versions")
val classpathOptions = SettingKey[ClasspathOptions]("classpath-options")
val definedSbtPlugins = TaskKey[Set[String]]("defined-sbt-plugins")
val sbtPlugin = SettingKey[Boolean]("sbt-plugin")

View File

@ -4,10 +4,10 @@
package sbt
import Execute.NodeView
import complete.HistoryCommands
import complete.{DefaultParsers, HistoryCommands, Parser}
import HistoryCommands.{Start => HistoryPrefix}
import compiler.EvalImports
import sbt.complete.{DefaultParsers, Parser}
import Command.applyEffect
import Keys.{analysis,historyPath,logged,shellPrompt}
@ -59,7 +59,7 @@ class xMain extends xsbti.AppMain
import CommandSupport._
object BuiltinCommands
{
def DefaultCommands: Seq[Command] = Seq(ignore, help, reboot, read, history, continuous, exit, loadProject, loadProjectImpl, loadFailed, Script.command,
def DefaultCommands: Seq[Command] = Seq(ignore, help, reboot, read, history, continuous, exit, loadProject, loadProjectImpl, loadFailed, Script.command, Cross.crossBuild, Cross.switchVersion,
projects, project, setOnFailure, clearOnFailure, ifLast, multi, shell, set, inspect, eval, alias, append, last, lastGrep, nop, sessionCommand, act)
def DefaultBootCommands: Seq[String] = LoadProject :: (IfLast + " " + Shell) :: Nil