mirror of https://github.com/sbt/sbt.git
91 lines
3.3 KiB
Scala
91 lines
3.3 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2010 Mark Harrah
|
|
*/
|
|
package sbt
|
|
|
|
import std._
|
|
import Path._
|
|
import TaskExtra._
|
|
import scala.collection.{immutable, mutable, JavaConversions}
|
|
|
|
import java.io.File
|
|
|
|
object Dummy
|
|
{
|
|
val InName = "command-line-input"
|
|
val StateName = "command-state"
|
|
val StreamsName = "task-streams"
|
|
val ContextName = "task-context"
|
|
|
|
def dummy[T](name: String): Task[T] = task( error("Dummy task '" + name + "' did not get converted to a full task.") ) named name
|
|
val In = dummy[Input](InName)
|
|
val State = dummy[State](StateName)
|
|
val Streams = dummy[TaskStreams](StreamsName)
|
|
val Context = dummy[Transform.Context[Project]](ContextName)
|
|
}
|
|
/** A group of tasks, often related in some way.
|
|
* This trait should be used like:
|
|
* def testTasks(prefix: Option[String]) = new TestTasks(prefix)
|
|
* final class TestTasks(val prefix: Option[String]) extends TaskGroup {
|
|
* lazy val test = ...
|
|
* lazy val discover = ...
|
|
* }
|
|
*
|
|
* This allows a method to return multiple tasks that can still be referenced uniformly and directly:
|
|
* val test = testTasks(None)
|
|
* val it = testTasks(Some("integration"))
|
|
*
|
|
* > test
|
|
* ... run test.test ...
|
|
* > integration-test
|
|
* ... run it.test ...
|
|
*/
|
|
trait TaskGroup
|
|
{
|
|
def prefix: Option[String]
|
|
def tasks: immutable.SortedMap[String, Task[_]] = ReflectiveContext.deepTasks(this)
|
|
}
|
|
object ReflectiveContext
|
|
{
|
|
def deepTasks(context: AnyRef): immutable.SortedMap[String, Task[_]] =
|
|
{
|
|
val direct = ReflectUtilities.allVals[Task[_]](context)
|
|
val groups = ReflectUtilities.allVals[TaskGroup](context)
|
|
val nested = groups.flatMap { case (name, group) => prefixAll(group.prefix, group.tasks) }
|
|
nested ++ direct // this order necessary so that direct shadows nested
|
|
}
|
|
def prefixAll(pre: Option[String], tasks: immutable.SortedMap[String, Task[_]]): immutable.SortedMap[String, Task[_]] =
|
|
pre match
|
|
{
|
|
case Some(p) if !p.isEmpty => prefix(p, tasks)
|
|
case _ => tasks
|
|
}
|
|
def prefix(p: String, tasks: Iterable[(String, Task[_])]): immutable.SortedMap[String, Task[_]] =
|
|
immutable.TreeMap[String, Task[_]]() ++ (tasks map { case (name, task) => (p + name.capitalize, task) })
|
|
|
|
import Transform.Context
|
|
def apply[Owner <: AnyRef : Manifest](context: Owner, name: String, root: Owner): Context[Owner] = new Context[Owner]
|
|
{
|
|
private[sbt] lazy val tasks: immutable.SortedMap[String, Task[_]] = deepTasks(context)
|
|
private[sbt] lazy val reverseName: collection.Map[Task[_], String] = reverseMap(tasks)
|
|
private[sbt] lazy val sub: Map[String, Owner] = ReflectUtilities.allVals[Owner](context)
|
|
private[sbt] lazy val reverseSub: collection.Map[Owner, String] = reverseMap(sub)
|
|
|
|
def rootOwner = root
|
|
val staticName: Task[_] => Option[String] = reverseName.get _
|
|
val ownerName = (o: Owner) => if(o eq context) Some(name) else None
|
|
val owner = (t: Task[_]) => if(reverseName contains t) Some(context) else None
|
|
def allTasks(o: Owner): Seq[Task[_]] = if(o eq context) tasks.values.toSeq else Nil
|
|
def ownerForName(oname: String): Option[Owner] = if(name == oname) Some(context) else None
|
|
val aggregate = (_: Owner) => Nil
|
|
val static = (o: Owner, s: String) => if(o eq context) tasks.get(s) else None
|
|
|
|
private def reverseMap[A,B](in: Iterable[(A,B)]): collection.Map[B,A] =
|
|
{
|
|
import JavaConversions._
|
|
val map: mutable.Map[B, A] = new java.util.IdentityHashMap[B, A]
|
|
for( (name, task) <- in ) map(task) = name
|
|
map
|
|
}
|
|
}
|
|
} |