mirror of https://github.com/sbt/sbt.git
first shot at general command/definition model
This commit is contained in:
parent
d0fa1eb461
commit
d7b66458f2
|
|
@ -0,0 +1,11 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
package inc
|
||||
|
||||
final case class Discovered(baseClasses: Set[String], annotations: Set[String], hasMain: Boolean, isModule: Boolean)
|
||||
object Discovered
|
||||
{
|
||||
def empty = new Discovered(Set.empty, Set.empty, false, false)
|
||||
}
|
||||
|
|
@ -86,9 +86,4 @@ object Discovery
|
|||
}
|
||||
|
||||
def isUnit(t: Type): Boolean = named(t, "scala.Unit")
|
||||
}
|
||||
final case class Discovered(baseClasses: Set[String], annotations: Set[String], hasMain: Boolean, isModule: Boolean)
|
||||
object Discovered
|
||||
{
|
||||
def empty = new Discovered(Set.empty, Set.empty, false, false)
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import java.io.File
|
|||
|
||||
object Incremental
|
||||
{
|
||||
def println(s: String) = ()
|
||||
def compile(sources: Set[File], previous: Analysis, current: ReadStamps, externalAPI: String => Source, doCompile: Set[File] => Analysis)(implicit equivS: Equiv[Stamp]): Analysis =
|
||||
{
|
||||
val initialChanges = changedInitial(sources, previous.stamps, previous.apis, current, externalAPI)
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ final class API(val global: Global, val callback: xsbti.AnalysisCallback) extend
|
|||
|
||||
private def processType(t: Type): xsbti.api.Type =
|
||||
{
|
||||
class TypeCompat { def dealias = t } // 2.7.7 compatibility: don't bother dealiasing
|
||||
implicit def compat(t: Type): TypeCompat = new TypeCompat
|
||||
t.dealias match
|
||||
{
|
||||
case NoPrefix => Constants.emptyType
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[scala]
|
||||
version: 2.7.7
|
||||
version: 2.8.0
|
||||
#classifiers: sources, javadoc
|
||||
|
||||
[app]
|
||||
|
|
@ -33,8 +33,8 @@
|
|||
project.name: quick=set(test), new=prompt(Name), fill=prompt(Name)
|
||||
project.organization: new=prompt(Organization)
|
||||
project.version: quick=set(1.0), new=prompt(Version)[1.0], fill=prompt(Version)[1.0]
|
||||
build.scala.versions: quick=set(2.7.7), new=prompt(Scala version)[2.7.7], fill=prompt(Scala version)[2.7.7]
|
||||
sbt.version: quick=set(0.7.4), new=prompt(sbt version)[0.7.4], fill=prompt(sbt version)[0.7.4]
|
||||
build.scala.versions: quick=set(2.8.0), new=prompt(Scala version)[2.8.0], fill=prompt(Scala version)[2.8.0]
|
||||
sbt.version: quick=set(0.9.0-SNAPSHOT), new=prompt(sbt version)[0.9.0-SNAPSHOT], fill=prompt(sbt version)[0.9.0-SNAPSHOT]
|
||||
project.scratch: quick=set(true)
|
||||
project.initialize: quick=set(true), new=set(true)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
package sbt
|
||||
|
||||
import sbt.compile.{AnalyzingCompiler, JavaCompiler}
|
||||
import sbt.build.AggressiveCompile
|
||||
import java.io.File
|
||||
import System.{currentTimeMillis => now}
|
||||
import Path._
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2009, 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
|
||||
sealed trait Command
|
||||
{
|
||||
def applies: PartialFunction[State, Apply]
|
||||
}
|
||||
trait Apply
|
||||
{
|
||||
def help: Seq[(String,String)]
|
||||
def run: PartialFunction[Input, State]
|
||||
}
|
||||
object Command
|
||||
{
|
||||
def apply(f: PartialFunction[State, Apply]): Command =
|
||||
new Command { def applies = f }
|
||||
|
||||
def simple(name: String, help: (String, String)*)(f: State => State): Command =
|
||||
apply { case s => Apply(help) { case in if in.line == name => f(s) }}
|
||||
}
|
||||
object Apply
|
||||
{
|
||||
def apply(h: Seq[(String,String)])(r: PartialFunction[Input, State]): Apply =
|
||||
new Apply { def help = h; def run = r }
|
||||
}
|
||||
|
||||
trait Logged
|
||||
{
|
||||
def log: Logger
|
||||
}
|
||||
trait HistoryEnabled
|
||||
{
|
||||
def historyPath: Option[Path]
|
||||
}
|
||||
|
||||
final case class Input(line: String)
|
||||
{
|
||||
def name: String = error("TODO")
|
||||
def arguments: String = error("TODO")
|
||||
}
|
||||
|
||||
object Next extends Enumeration {
|
||||
val Reload, Fail, Done, Continue = Value
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009, 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
|
||||
import complete.HistoryCommands
|
||||
import HistoryCommands.{Start => HistoryPrefix}
|
||||
import sbt.build.{AggressiveCompile, Build, BuildException, Parse, ParseException}
|
||||
import scala.annotation.tailrec
|
||||
|
||||
/** This class is the entry point for sbt.*/
|
||||
class xMain extends xsbti.AppMain
|
||||
{
|
||||
final def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
|
||||
{
|
||||
import Commands._
|
||||
val initialCommands = Seq(help, history, exit, load)
|
||||
val state = State( () )( configuration, initialCommands, Set.empty, None, configuration.arguments.map(_.trim).toList, Next.Continue )
|
||||
run(state)
|
||||
}
|
||||
|
||||
@tailrec final def run(state: State): xsbti.MainResult =
|
||||
{
|
||||
import Next._
|
||||
state.next match
|
||||
{
|
||||
case Continue => run(next(state))
|
||||
case Fail => Exit(1)
|
||||
case Done => Exit(0)
|
||||
case Reload =>
|
||||
val app = state.configuration.provider
|
||||
new Reboot(app.scalaProvider.version, state.commands, app.id, state.configuration.baseDirectory)
|
||||
}
|
||||
}
|
||||
def next(state: State): State = state.process(process)
|
||||
def process(command: String, state: State): State =
|
||||
{
|
||||
val in = Input(command)
|
||||
Commands.applicable(state).flatMap( _.run.lift(in) ).headOption.getOrElse {
|
||||
System.err.println("Unknown command '" + command + "'")
|
||||
state.fail
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
object Commands
|
||||
{
|
||||
def applicable(state: State): Stream[Apply] =
|
||||
state.processors.toStream.flatMap(_.applies.lift(state) )
|
||||
|
||||
def help = Command.simple("help", ("help", "Displays this help message.")) { s =>
|
||||
val message = applicable(s).flatMap(_.help).map { case (a,b) => a + " : " + b }.mkString("\n")
|
||||
System.out.println(message)
|
||||
s
|
||||
}
|
||||
|
||||
def history = Command { case s @ State(p: HistoryEnabled with Logged) =>
|
||||
Apply(HistoryCommands.descriptions) {
|
||||
case in if in.line startsWith("!") =>
|
||||
HistoryCommands(in.line.substring(HistoryPrefix.length).trim, p.historyPath, 500/*JLine.MaxHistorySize*/, p.log.error _) match
|
||||
{
|
||||
case Some(commands) =>
|
||||
commands.foreach(println) //better to print it than to log it
|
||||
(commands ::: s).continue
|
||||
case None => s.fail
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def helpExit = (TerminateActions.mkString(", "), "Terminates the build.")
|
||||
|
||||
def exit = Command { case s => Apply(helpExit :: Nil) {
|
||||
case Input(line) if TerminateActions contains line =>
|
||||
s.exit(true)
|
||||
}
|
||||
}
|
||||
|
||||
def load = Command { case s => Apply(Nil) {
|
||||
case Input(line) if line.startsWith("load") =>
|
||||
loadCommand(line, s.configuration) match
|
||||
{
|
||||
case Right(newValue) =>
|
||||
ExitHooks.runExitHooks(s.exitHooks.toSeq)
|
||||
s.copy(project = newValue)(exitHooks = Set.empty)
|
||||
case Left(e) => e.printStackTrace; System.err.println(e.toString); s.fail // TODO: log instead of print
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def loadCommand(line: String, configuration: xsbti.AppConfiguration): Either[Throwable, Any] =
|
||||
try { Right( Build( Parse(line)(configuration.baseDirectory), configuration ) ) }
|
||||
catch { case e @ (_: ParseException | _: BuildException | _: xsbti.CompileFailed) => Left(e) }
|
||||
|
||||
val Exit = "exit"
|
||||
val Quit = "quit"
|
||||
/** The list of lowercase command names that may be used to terminate the program.*/
|
||||
val TerminateActions: Seq[String] = Seq(Exit, Quit)
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ private case class Exit(code: Int) extends xsbti.Exit
|
|||
{
|
||||
require(code >= 0)
|
||||
}
|
||||
private class Reboot(val scalaVersion: String, argsList: List[String], val app: xsbti.ApplicationID, val baseDirectory: File) extends xsbti.Reboot
|
||||
private class Reboot(val scalaVersion: String, argsList: Seq[String], val app: xsbti.ApplicationID, val baseDirectory: File) extends xsbti.Reboot
|
||||
{
|
||||
def arguments = argsList.toArray
|
||||
}
|
||||
|
|
@ -24,8 +24,4 @@ private class ApplicationID(delegate: xsbti.ApplicationID, newVersion: String) e
|
|||
def crossVersioned = delegate.crossVersioned
|
||||
|
||||
def classpathExtra = delegate.classpathExtra
|
||||
}
|
||||
private final class ReloadException(val remainingArguments: List[String], val buildScalaVersion: Option[String]) extends RuntimeException
|
||||
{
|
||||
override def fillInStackTrace = this
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009, 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
|
||||
case class State(project: Any)(
|
||||
val configuration: xsbti.AppConfiguration,
|
||||
val processors: Seq[Command],
|
||||
val exitHooks: Set[ExitHook],
|
||||
val onFailure: Option[String],
|
||||
val commands: Seq[String],
|
||||
val next: Next.Value
|
||||
)
|
||||
|
||||
trait StateOps {
|
||||
def process(f: (String, State) => State): State
|
||||
def ::: (commands: Seq[String]): State
|
||||
def :: (command: String): State
|
||||
def continue: State
|
||||
def reload: State
|
||||
def exit(ok: Boolean): State
|
||||
def fail: State
|
||||
}
|
||||
object State
|
||||
{
|
||||
implicit def stateOps(s: State): StateOps = new StateOps {
|
||||
def process(f: (String, State) => State): State =
|
||||
s.commands match {
|
||||
case x :: xs => f(x, s.copy()(commands = xs))
|
||||
case Nil => exit(true)
|
||||
}
|
||||
s.copy()(commands = s.commands.drop(1))
|
||||
def ::: (newCommands: Seq[String]): State = s.copy()(commands = newCommands ++ s.commands)
|
||||
def :: (command: String): State = s.copy()(commands = command +: s.commands)
|
||||
def setNext(n: Next.Value) = s.copy()(next = n)
|
||||
def continue = setNext(Next.Continue)
|
||||
def reload = setNext(Next.Reload)
|
||||
def exit(ok: Boolean) = setNext(if(ok) Next.Fail else Next.Done)
|
||||
def fail =
|
||||
s.onFailure match
|
||||
{
|
||||
case Some(c) => s.copy()(commands = c :: Nil, onFailure = None)
|
||||
case None => exit(ok = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
package build
|
||||
|
||||
import inc._
|
||||
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
package build
|
||||
|
||||
import java.io.File
|
||||
import classpath.ClasspathUtilities.toLoader
|
||||
import ModuleUtilities.getObject
|
||||
import compile.{AnalyzingCompiler, JavaCompiler}
|
||||
import Path._
|
||||
|
||||
final class BuildException(msg: String) extends RuntimeException(msg)
|
||||
|
||||
object Build
|
||||
{
|
||||
def loader(configuration: xsbti.AppConfiguration): ClassLoader =
|
||||
configuration.provider.mainClass.getClassLoader
|
||||
|
||||
def apply(command: LoadCommand, configuration: xsbti.AppConfiguration): Any =
|
||||
command match
|
||||
{
|
||||
case BinaryLoad(classpath, module, name) =>
|
||||
binary(classpath, module, name, loader(configuration))
|
||||
case SourceLoad(classpath, sourcepath, output, module, auto, name) =>
|
||||
source(classpath, sourcepath, output, module, auto, name, configuration)
|
||||
case _ => error("Not implemented yet")
|
||||
}
|
||||
|
||||
def binary(classpath: Seq[File], module: Boolean, name: String, parent: ClassLoader): Any =
|
||||
{
|
||||
if(name.isEmpty)
|
||||
error("Class name required to load binary project.")
|
||||
else
|
||||
{
|
||||
val loader = toLoader(classpath, parent)
|
||||
if(module)
|
||||
getObject(name, loader)
|
||||
else
|
||||
{
|
||||
val clazz = Class.forName(name, true, loader)
|
||||
clazz.newInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def source(classpath: Seq[File], sources: Seq[File], output: Option[File], module: Boolean, auto: Auto.Value, name: String, configuration: xsbti.AppConfiguration): Any =
|
||||
{
|
||||
// TODO: accept Logger as an argument
|
||||
val log = new ConsoleLogger with Logger with sbt.IvyLogger
|
||||
|
||||
val scalaProvider = configuration.provider.scalaProvider
|
||||
val launcher = scalaProvider.launcher
|
||||
val instance = ScalaInstance(scalaProvider.version, launcher)
|
||||
|
||||
val out = output.getOrElse(configuration.baseDirectory / "target" asFile)
|
||||
val target = out / ("scala_" + instance.actualVersion)
|
||||
val outputDirectory = target / "classes"
|
||||
val cacheDirectory = target / "cache"
|
||||
val projectClasspath = outputDirectory.asFile +: classpath
|
||||
val compileClasspath = projectClasspath ++ configuration.provider.mainClasspath.toSeq
|
||||
|
||||
val componentManager = new ComponentManager(launcher.globalLock, configuration.provider.components, log)
|
||||
val compiler = new AnalyzingCompiler(instance, componentManager, log)
|
||||
val javac = JavaCompiler.directOrFork(compiler.cp, compiler.scalaInstance)( (args: Seq[String], log: Logger) => Process("javac", args) ! log )
|
||||
|
||||
val agg = new AggressiveCompile(cacheDirectory)
|
||||
val analysis = agg(compiler, javac, sources, compileClasspath, outputDirectory, Nil, Nil)(log)
|
||||
|
||||
val discovered = discover(analysis, module, auto, name)
|
||||
load(discovered)(x => binary(projectClasspath, module, x, loader(configuration)) )
|
||||
}
|
||||
def discover(analysis: inc.Analysis, module: Boolean, auto: Auto.Value, name: String): Seq[String] =
|
||||
{
|
||||
import Auto.{Annotation, Explicit, Subclass}
|
||||
auto match {
|
||||
case Explicit => if(name.isEmpty) error("No name specified to load explicitly.") else Seq(name)
|
||||
case Subclass => discover(analysis, module, new inc.Discovery(Set(name), Set.empty))
|
||||
case Annotation => discover(analysis, module, new inc.Discovery(Set.empty, Set(name)))
|
||||
}
|
||||
}
|
||||
def discover(analysis: inc.Analysis, module: Boolean, discovery: inc.Discovery): Seq[String] =
|
||||
{
|
||||
for(src <- analysis.apis.internal.values.toSeq;
|
||||
(df, found) <- discovery(src.definitions) if found.isModule == module)
|
||||
yield
|
||||
df.name
|
||||
}
|
||||
def load(discovered: Seq[String])(doLoad: String => Any): Any =
|
||||
discovered match
|
||||
{
|
||||
case Seq() => error("No project found")
|
||||
case Seq(x) => doLoad(x)
|
||||
case xs => error("Multiple projects found: " + discovered.mkString(", "))
|
||||
}
|
||||
|
||||
def error(msg: String) = throw new BuildException(msg)
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
package build
|
||||
|
||||
import java.io.File
|
||||
|
||||
sealed trait LoadCommand
|
||||
final case class BinaryLoad(classpath: Seq[File], module: Boolean, name: String) extends LoadCommand
|
||||
final case class SourceLoad(classpath: Seq[File], sourcepath: Seq[File], output: Option[File], module: Boolean, auto: Auto.Value, name: String) extends LoadCommand
|
||||
final case class ProjectLoad(base: File, name: String) extends LoadCommand
|
||||
|
||||
object Auto extends Enumeration
|
||||
{
|
||||
val Subclass, Annotation, Explicit = Value
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2010 Mark Harrah
|
||||
*/
|
||||
package sbt
|
||||
package build
|
||||
|
||||
import java.io.File
|
||||
|
||||
final class ParseException(msg: String) extends RuntimeException(msg)
|
||||
|
||||
/** Parses a load command.
|
||||
*
|
||||
* load ::= 'load' (binary | source | project)
|
||||
*
|
||||
* binary ::= classpath module name
|
||||
* source ::= classpath '-src' paths ('-d' dir)? ('-auto' ('sub' | 'annot'))? module name
|
||||
* project ::= ('-project' path)? name?
|
||||
*
|
||||
* name ::= '-name' nameString
|
||||
* module ::= ('-module' ('true'|'false') )?
|
||||
* classpath ::= '-cp' paths
|
||||
* path ::= pathChar+
|
||||
* paths ::= path (pathSep path)*
|
||||
*/
|
||||
|
||||
object Parse
|
||||
{
|
||||
import File.{pathSeparatorChar => sep}
|
||||
|
||||
def error(msg: String) = throw new ParseException(msg)
|
||||
def apply(commandString: String)(implicit base: File): LoadCommand =
|
||||
{
|
||||
val tokens = commandString.split("""\s+""").toSeq
|
||||
if(tokens.isEmpty) error("Empty command")
|
||||
else if(tokens.head != "load") error("Not a load command")
|
||||
else
|
||||
{
|
||||
val args = tokens.drop(1)
|
||||
val srcs = sourcepath(args)
|
||||
val nme = name(args)
|
||||
|
||||
lazy val cp = classpath(args)
|
||||
lazy val mod = module(args)
|
||||
lazy val proj = project(args).getOrElse(base)
|
||||
|
||||
if(!srcs.isEmpty)
|
||||
SourceLoad(cp, srcs, output(args), mod, auto(args), nme)
|
||||
else if(!cp.isEmpty)
|
||||
BinaryLoad(cp, mod, nme)
|
||||
else
|
||||
ProjectLoad(proj, nme)
|
||||
}
|
||||
}
|
||||
|
||||
def auto(args: Seq[String]): Auto.Value =
|
||||
getArg(args, "auto") match {
|
||||
case None => Auto.Explicit
|
||||
case Some("sub") => Auto.Subclass
|
||||
case Some("annot") => Auto.Annotation
|
||||
case Some(x) => error("Illegal auto argument '" + x + "'")
|
||||
}
|
||||
|
||||
def module(args: Seq[String]): Boolean =
|
||||
getArg(args, "module") match {
|
||||
case None | Some("false") => false
|
||||
case Some("true") => true
|
||||
case Some(x) => error("Expected boolean, got '" + x + "'")
|
||||
}
|
||||
|
||||
def name(args: Seq[String]): String =
|
||||
getArg(args, "name") getOrElse("")
|
||||
|
||||
def output(args: Seq[String])(implicit base: File): Option[File] =
|
||||
getArg(args, "d") map file(base)
|
||||
|
||||
def project(args: Seq[String])(implicit base: File): Option[File] =
|
||||
getArg(args, "project") map file(base)
|
||||
|
||||
def pathArg(args: Seq[String], name: String)(implicit base: File): Seq[File] =
|
||||
getArg(args, name).toSeq flatMap paths
|
||||
|
||||
def classpath(args: Seq[String])(implicit base: File): Seq[File] = pathArg(args, "cp")
|
||||
def sourcepath(args: Seq[String])(implicit base: File): Seq[File] = pathArg(args, "src")
|
||||
|
||||
def getArg(args: Seq[String], name: String): Option[String] =
|
||||
{
|
||||
val opt = "-" + name
|
||||
val found = args.dropWhile(_ != opt)
|
||||
|
||||
if(found.isEmpty)
|
||||
None
|
||||
else
|
||||
found.drop(1).headOption match
|
||||
{
|
||||
case x @ Some(arg) if !arg.startsWith("-") => x
|
||||
case _ => error("No argument provided for -" + name)
|
||||
}
|
||||
}
|
||||
|
||||
def paths(implicit base: File): String => Seq[File] =
|
||||
_ split sep map file(base)
|
||||
|
||||
def file(base: File) = (path: String) => Path.fromString(base, path).asFile
|
||||
}
|
||||
|
|
@ -2,4 +2,4 @@ project.organization=org.scala-tools.sbt
|
|||
project.name=xsbt
|
||||
sbt.version=0.7.4
|
||||
project.version=0.9.0-SNAPSHOT
|
||||
build.scala.versions=2.8.0.RC6
|
||||
build.scala.versions=2.8.0
|
||||
|
|
|
|||
|
|
@ -40,11 +40,14 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
val compilerSub = project(compilePath, "Compile", new CompileProject(_),
|
||||
launchInterfaceSub, interfaceSub, ivySub, ioSub, classpathSub, compileInterfaceSub, logSub)
|
||||
|
||||
val altCompilerSub = baseProject("main", "Alternate Compiler Test",
|
||||
classfileSub, compileIncrementalSub, compilerSub, ioSub, logSub, discoverySub, compilePersistSub, processSub)
|
||||
val buildSub = baseProject("main" / "build", "Project Builder",
|
||||
classfileSub, classpathSub, compilePersistSub, compilerSub, compileIncrementalSub, interfaceSub, ivySub, launchInterfaceSub, logSub, discoverySub, processSub)
|
||||
|
||||
val altCompilerSub = project("main", "Alternate Compiler Test", (i: ProjectInfo) => new Base(i) { override def normalizedName = "sbt" }, // temporary
|
||||
buildSub, compileIncrementalSub, compilerSub, completeSub, discoverySub, ioSub, logSub, processSub)
|
||||
|
||||
/** following modules are not updated for 2.8 or 0.9 */
|
||||
val testSub = project("scripted", "Test", new TestProject(_), ioSub)
|
||||
/*val testSub = project("scripted", "Test", new TestProject(_), ioSub)
|
||||
|
||||
val trackingSub = baseProject(cachePath / "tracking", "Tracking", cacheSub)
|
||||
|
||||
|
|
@ -53,7 +56,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
|
||||
val installerSub = project(sbtPath / "install", "Installer", new InstallerProject(_) {}, sbtSub)
|
||||
|
||||
lazy val dist = task { None } dependsOn(launchSub.proguard, sbtSub.publishLocal, installerSub.publishLocal)
|
||||
lazy val dist = task { None } dependsOn(launchSub.proguard, sbtSub.publishLocal, installerSub.publishLocal)*/
|
||||
|
||||
def baseProject(path: Path, name: String, deps: Project*) = project(path, name, new Base(_), deps : _*)
|
||||
def testedBase(path: Path, name: String, deps: Project*) = project(path, name, new TestedBase(_), deps : _*)
|
||||
|
|
@ -131,8 +134,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
trait TestDependencies extends Project
|
||||
{
|
||||
val sc = "org.scala-tools.testing" %% "scalacheck" % "1.7" % "test"
|
||||
val sp = "org.scala-tools.testing" %% "specs" % "1.6.5-SNAPSHOT" % "test"
|
||||
val snaps = ScalaToolsSnapshots
|
||||
val sp = "org.scala-tools.testing" %% "specs" % "1.6.5" % "test"
|
||||
}
|
||||
class LogProject(info: ProjectInfo) extends Base(info) with TestDependencies
|
||||
{
|
||||
|
|
@ -144,7 +146,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
{
|
||||
// these compilation options are useful for debugging caches and task composition
|
||||
//override def compileOptions = super.compileOptions ++ List(Unchecked,ExplainTypes, CompileOption("-Xlog-implicits"))
|
||||
val sbinary = "org.scala-tools.sbinary" %% "sbinary" % "0.3.1-SNAPSHOT"
|
||||
val sbinary = "org.scala-tools.sbinary" %% "sbinary" % "0.3.1"
|
||||
}
|
||||
class Base(info: ProjectInfo) extends DefaultProject(info) with ManagedBase with Component with Licensed
|
||||
{
|
||||
|
|
@ -246,7 +248,8 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
|
||||
// sub projects for each version of Scala to precompile against other than the one sbt is built against
|
||||
// each sub project here will add ~100k to the download
|
||||
lazy val precompiled28 = precompiledSub("2.8.0.RC6")
|
||||
//lazy val precompiled28 = precompiledSub("2.8.0")
|
||||
lazy val precompiled27 = precompiledSub("2.7.7")
|
||||
|
||||
def precompiledSub(v: String) =
|
||||
project(info.projectPath, "Precompiled " + v, new Precompiled(v)(_), cip.info.dependencies.toSeq : _* /*doesn't include subprojects of cip*/ )
|
||||
|
|
@ -261,6 +264,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) with NoCrossPaths
|
|||
* subproject does not depend on any Scala subprojects, so mixing versions is not a problem. */
|
||||
override def compileClasspath = cip.compileClasspath --- cip.mainUnmanagedClasspath +++ mainUnmanagedClasspath
|
||||
|
||||
override def compileOptions = Nil
|
||||
// these ensure that the classes compiled against other versions of Scala are not exported (for compilation/testing/...)
|
||||
override def projectClasspath(config: Configuration) = Path.emptyPathFinder
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
/*package sbt
|
||||
|
||||
import java.io.File
|
||||
import compile.AnalyzingCompiler
|
||||
|
||||
final class Console(compiler: AnalyzingCompiler) extends NotNull
|
||||
{
|
||||
/** Starts an interactive scala interpreter session with the given classpath.*/
|
||||
def apply(classpath: Iterable[File], log: Logger): Option[String] =
|
||||
apply(classpath, Nil, "", log)
|
||||
|
||||
def apply(classpath: Iterable[File], options: Seq[String], initialCommands: String, log: Logger): Option[String] =
|
||||
{
|
||||
def console0 = compiler.console(Path.getFiles(classpath), options, initialCommands, log)
|
||||
JLine.withJLine( Run.executeTrapExit(console0, log) )
|
||||
}
|
||||
}*/
|
||||
|
|
@ -12,21 +12,11 @@ trait ExitHook extends NotNull
|
|||
def runBeforeExiting(): Unit
|
||||
}
|
||||
|
||||
trait ExitHookRegistry
|
||||
object ExitHooks
|
||||
{
|
||||
def register(hook: ExitHook): Unit
|
||||
def unregister(hook: ExitHook): Unit
|
||||
}
|
||||
|
||||
|
||||
class ExitHooks extends ExitHookRegistry
|
||||
{
|
||||
private val exitHooks = new scala.collection.mutable.HashSet[ExitHook]
|
||||
def register(hook: ExitHook) { exitHooks += hook }
|
||||
def unregister(hook: ExitHook) { exitHooks -= hook }
|
||||
/** Calls each registered exit hook, trapping any exceptions so that each hook is given a chance to run. */
|
||||
def runExitHooks(debug: String => Unit): List[Throwable] =
|
||||
exitHooks.toList.flatMap( hook =>
|
||||
def runExitHooks(exitHooks: Seq[ExitHook]): Seq[Throwable] =
|
||||
exitHooks.flatMap( hook =>
|
||||
ErrorHandling.wideConvert( hook.runBeforeExiting() ).left.toOption
|
||||
)
|
||||
}
|
||||
|
|
@ -13,11 +13,8 @@ object JettyRunner
|
|||
val DefaultPort = 8080
|
||||
val DefaultScanInterval = 3
|
||||
}
|
||||
//TODO: don't pass registry, just handle it in client
|
||||
class JettyRunner(configuration: JettyConfiguration, registry: ExitHookRegistry) extends ExitHook
|
||||
class JettyRunner(configuration: JettyConfiguration) extends ExitHook
|
||||
{
|
||||
registry.register(this)
|
||||
|
||||
def name = "jetty-shutdown"
|
||||
def runBeforeExiting() { stop() }
|
||||
private var running: Option[Stoppable] = None
|
||||
|
|
|
|||
Loading…
Reference in New Issue