* Moved topologicalSort in Dag trait to companion object

* Subprojects can be excluded from dependencies so that their actions aren't executed when a parent's actions are



git-svn-id: https://simple-build-tool.googlecode.com/svn/trunk@944 d89573ee-9141-11dd-94d4-bdf5e562f29c
This commit is contained in:
dmharrah 2009-08-09 02:03:24 +00:00
parent d798cb88b8
commit 749934f64a
4 changed files with 21 additions and 26 deletions

View File

@ -520,7 +520,7 @@ trait ReflectiveProject extends ReflectiveModules with ReflectiveTasks with Refl
/** This Project subclass is used to contain other projects as dependencies.*/
class ParentProject(val info: ProjectInfo) extends BasicDependencyProject
{
def dependencies = info.dependencies ++ subProjects.values.toList
def dependencies: Iterable[Project] = info.dependencies ++ subProjects.values.toList
/** The directories to which a project writes are listed here and is used
* to check a project and its dependencies for collisions.*/
override def outputDirectories = managedDependencyPath :: outputPath :: Nil

View File

@ -1,28 +1,31 @@
/* sbt -- Simple Build Tool
* Copyright 2008 David MacIver
* Copyright 2008, 2009 David MacIver, Mark Harrah
*/
package sbt;
import scala.collection.mutable;
trait Dag[Node <: Dag[Node]]{
self : Node =>
def dependencies : Iterable[Node]
def topologicalSort = Dag.topologicalSort(self)(_.dependencies)
}
object Dag
{
import scala.collection.mutable;
def topologicalSort = {
val discovered = new mutable.HashSet[Node];
val finished = new wrap.MutableSetWrapper(new java.util.LinkedHashSet[Node])
def topologicalSort[T](root: T)(dependencies: T => Iterable[T]) = {
val discovered = new mutable.HashSet[T];
val finished = new wrap.MutableSetWrapper(new java.util.LinkedHashSet[T])
def visit(dag : Node){
def visit(dag : T){
if (!discovered(dag)) {
discovered(dag) = true;
dag.dependencies.foreach(visit);
dependencies(dag).foreach(visit);
finished += dag;
}
}
visit(self);
visit(root);
finished.toList;
}

View File

@ -72,7 +72,7 @@ object Main
import success.project
val doNext: RunCompleteAction =
// in interactive mode, fill all undefined properties
if(args.length > 0 || fillUndefinedProjectProperties(project.topologicalSort.toList.reverse))
if(args.length > 0 || fillUndefinedProjectProperties(project.projectClosure.toList.reverse))
startProject(project, args, startTime)
else
new Exit(NormalExitCode)
@ -191,7 +191,7 @@ object Main
**/
private def interactive(baseProject: Project): RunCompleteAction =
{
val projectNames = baseProject.topologicalSort.map(_.name)
val projectNames = baseProject.projectClosure.map(_.name)
val prefixes = ContinuousExecutePrefix :: CrossBuildPrefix :: Nil
val completors = new Completors(ProjectAction, projectNames, interactiveCommands, List(GetAction, SetAction), prefixes)
val reader = new JLineReader(baseProject.historyPath, completors, baseProject.log)
@ -235,7 +235,7 @@ object Main
else if(trimmed.startsWith(ProjectAction + " "))
{
val projectName = trimmed.substring(ProjectAction.length + 1)
baseProject.topologicalSort.find(_.name == projectName) match
baseProject.projectClosure.find(_.name == projectName) match
{
case Some(newProject) =>
{
@ -255,7 +255,7 @@ object Main
if(trimmed == HelpAction)
displayInteractiveHelp()
else if(trimmed == ShowProjectsAction)
baseProject.topologicalSort.foreach(listProject)
baseProject.projectClosure.foreach(listProject)
else if(trimmed.startsWith(SetAction + " "))
setProperty(currentProject, trimmed.substring(SetAction.length + 1))
else if(trimmed.startsWith(GetAction + " "))
@ -414,7 +414,7 @@ object Main
private def toggleTrace(project: Project)
{
val newValue = !project.log.traceEnabled
project.topologicalSort.foreach(_.log.enableTrace(newValue))
project.projectClosure.foreach(_.log.enableTrace(newValue))
printTraceEnabled(project)
}
private def printTraceEnabled(project: Project)
@ -424,7 +424,7 @@ object Main
/** Sets the logging level on the given project.*/
private def setLevel(project: Project, level: Level.Value)
{
project.topologicalSort.foreach(_.log.setLevel(level))
project.projectClosure.foreach(_.log.setLevel(level))
Console.println("Set log level to " + project.log.getLevel)
}
/** Prints the elapsed time to the given project's log using the given

View File

@ -82,15 +82,7 @@ trait Project extends TaskManager with Dag[Project] with BasicEnvironment
* specified for the project and are different from those specified in the project constructor. The
* main use within sbt is in ParentProject.*/
def subProjects: Map[String, Project] = immutable.Map.empty
/** The name of this project and the names of all subprojects/dependencies, transitively.*/
def projectNames: Iterable[String] =
{
val names = new mutable.HashSet[String]
names ++= subProjects.keys
for(dependentProject <- topologicalSort)
names ++= dependentProject.tasks.keys
names.toList
}
def projectClosure: List[Project] = Dag.topologicalSort(this)(p => p.dependencies ++ p.subProjects.values.toList)
def call(name: String, parameters: Array[String]): Option[String] =
{
@ -424,7 +416,7 @@ object Project
* output directories. */
private def checkOutputDirectoriesImpl(project: Project): LoadResult =
{
val projects = project.topologicalSort
val projects = project.projectClosure
import scala.collection.mutable.{HashMap, HashSet, Set}
val outputDirectories = new HashMap[Path, Set[Project]]
for(p <- projects; path <- p.outputDirectories)