2011-01-19 00:24:11 +01:00
|
|
|
/* sbt -- Simple Build Tool
|
|
|
|
|
* Copyright 2011 Mark Harrah
|
|
|
|
|
*/
|
|
|
|
|
package sbt
|
|
|
|
|
|
|
|
|
|
import java.io.File
|
|
|
|
|
import java.net.URI
|
|
|
|
|
import Project._
|
2011-01-22 20:01:59 +01:00
|
|
|
import Command.{HistoryPath,Watch}
|
|
|
|
|
import CommandSupport.logger
|
2011-01-19 00:24:11 +01:00
|
|
|
|
|
|
|
|
final case class Project(id: String, base: File, aggregate: Seq[ProjectRef] = Nil, dependencies: Seq[Project.ClasspathDependency] = Nil, inherits: Seq[ProjectRef] = Nil,
|
|
|
|
|
settings: Seq[Project.Setting[_]] = Project.defaultSettings, configurations: Seq[Configuration] = Configurations.default)
|
|
|
|
|
{
|
|
|
|
|
def uses = aggregate ++ dependencies.map(_.project)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object Project extends Init[Scope]
|
|
|
|
|
{
|
|
|
|
|
def defaultSettings: Seq[Setting[_]] = Nil
|
|
|
|
|
|
|
|
|
|
final case class ClasspathDependency(project: ProjectRef, configuration: Option[String])
|
|
|
|
|
final class Constructor(p: ProjectRef) {
|
|
|
|
|
def %(conf: String): ClasspathDependency = new ClasspathDependency(p, Some(conf))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def getOrError[T](state: State, key: AttributeKey[T], msg: String): T = state get key getOrElse error(msg)
|
|
|
|
|
def structure(state: State): Load.BuildStructure = getOrError(state, StructureKey, "No build loaded.")
|
|
|
|
|
def session(state: State): SessionSettings = getOrError(state, SessionKey, "Session not initialized.")
|
|
|
|
|
|
|
|
|
|
def current(state: State): (URI, String) =
|
|
|
|
|
{
|
|
|
|
|
val s = session(state)
|
|
|
|
|
val uri = s.currentBuild
|
|
|
|
|
(uri, s.currentProject(uri))
|
|
|
|
|
}
|
|
|
|
|
def currentRef(state: State): ProjectRef =
|
|
|
|
|
{
|
|
|
|
|
val (unit, it) = current(state)
|
|
|
|
|
ProjectRef(Some(unit), Some(it))
|
|
|
|
|
}
|
2011-01-22 20:01:59 +01:00
|
|
|
def updateCurrent(s: State): State =
|
|
|
|
|
{
|
|
|
|
|
val structure = Project.structure(s)
|
|
|
|
|
val (uri, id) = Project.current(s)
|
|
|
|
|
val ref = ProjectRef(uri, id)
|
|
|
|
|
val project = Load.getProject(structure.units, uri, id)
|
|
|
|
|
logger(s).info("Set current project to " + id + " (in build " + uri +")")
|
|
|
|
|
|
|
|
|
|
val data = structure.data
|
|
|
|
|
val historyPath = HistoryPath(ref).get(data).flatMap(identity)
|
|
|
|
|
val newAttrs = s.attributes.put(Watch.key, makeWatched(data, ref, project)).put(HistoryPath.key, historyPath)
|
|
|
|
|
s.copy(attributes = newAttrs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def makeWatched(data: Settings[Scope], ref: ProjectRef, project: Project): Watched =
|
|
|
|
|
{
|
|
|
|
|
def getWatch(ref: ProjectRef) = Watch(ref).get(data)
|
|
|
|
|
getWatch(ref) match
|
|
|
|
|
{
|
|
|
|
|
case Some(currentWatch) =>
|
|
|
|
|
val subWatches = project.uses flatMap { p => getWatch(p) }
|
|
|
|
|
Watched.multi(currentWatch, subWatches)
|
|
|
|
|
case None => Watched.empty
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-01-19 00:24:11 +01:00
|
|
|
def display(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)
|
|
|
|
|
|
|
|
|
|
def mapScope(f: Scope => Scope) = new (ScopedKey ~> ScopedKey) { def apply[T](key: ScopedKey[T]) =
|
|
|
|
|
ScopedKey( f(key.scope), key.key)
|
|
|
|
|
}
|
|
|
|
|
def transform(g: Scope => Scope, ss: Seq[Setting[_]]): Seq[Setting[_]] = {
|
|
|
|
|
val f = mapScope(g)
|
2011-01-24 04:34:17 +01:00
|
|
|
ss.map(_ mapKey f mapReferenced f)
|
2011-01-19 00:24:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val SessionKey = AttributeKey[SessionSettings]("session-settings")
|
|
|
|
|
val StructureKey = AttributeKey[Load.BuildStructure]("build-structure")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
import SessionSettings._
|
|
|
|
|
|
|
|
|
|
final class SessionSettings(val currentBuild: URI, val currentProject: Map[URI, String], val original: Seq[Setting[_]], val prepend: SessionMap, val append: SessionMap) {
|
|
|
|
|
assert(currentProject contains currentBuild, "Current build (" + currentBuild + ") not associated with a current project.")
|
|
|
|
|
def setCurrent(build: URI, project: String): SessionSettings = new SessionSettings(build, currentProject.updated(build, project), original, prepend, append)
|
|
|
|
|
def current: (URI, String) = (currentBuild, currentProject(currentBuild))
|
|
|
|
|
}
|
|
|
|
|
object SessionSettings {
|
|
|
|
|
type SessionSetting = (Setting[_], String)
|
|
|
|
|
type SessionMap = Map[(URI, String), Seq[SessionSetting]]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait ProjectConstructors
|
|
|
|
|
{
|
|
|
|
|
implicit def configDependencyConstructor[T <% ProjectRef](p: T): Project.Constructor = new Project.Constructor(p)
|
|
|
|
|
implicit def classpathDependency[T <% ProjectRef](p: T): Project.ClasspathDependency = new Project.ClasspathDependency(p, None)
|
|
|
|
|
}
|
2011-01-24 04:34:17 +01:00
|
|
|
// the URI must be resolved and normalized before it is definitive
|
2011-01-19 00:24:11 +01:00
|
|
|
final case class ProjectRef(uri: Option[URI], id: Option[String])
|
|
|
|
|
object ProjectRef
|
|
|
|
|
{
|
|
|
|
|
def apply(base: URI, id: String): ProjectRef = ProjectRef(Some(base), Some(id))
|
|
|
|
|
/** Reference to the project with 'id' in the current build unit.*/
|
|
|
|
|
def apply(id: String): ProjectRef = ProjectRef(None, Some(id))
|
2011-01-24 04:34:17 +01:00
|
|
|
def apply(base: File, id: String): ProjectRef = ProjectRef(Some(IO.toURI(base)), Some(id))
|
2011-01-19 00:24:11 +01:00
|
|
|
/** Reference to the root project at 'base'.*/
|
|
|
|
|
def apply(base: URI): ProjectRef = ProjectRef(Some(base), None)
|
|
|
|
|
/** Reference to the root project at 'base'.*/
|
2011-01-24 04:34:17 +01:00
|
|
|
def apply(base: File): ProjectRef = ProjectRef(Some(IO.toURI(base)), None)
|
2011-01-19 00:24:11 +01:00
|
|
|
/** Reference to the root project in the current build unit.*/
|
|
|
|
|
def root = ProjectRef(None, None)
|
|
|
|
|
|
|
|
|
|
implicit def stringToRef(s: String): ProjectRef = ProjectRef(s)
|
|
|
|
|
implicit def projectToRef(p: Project): ProjectRef = ProjectRef(p.id)
|
|
|
|
|
implicit def uriToRef(u: URI): ProjectRef = ProjectRef(u)
|
|
|
|
|
implicit def fileToRef(f: File): ProjectRef = ProjectRef(f)
|
|
|
|
|
}
|