mirror of https://github.com/sbt/sbt.git
add 'project /' and 'project ..' commands
This commit is contained in:
parent
730b613007
commit
f462cda1fb
|
|
@ -79,9 +79,18 @@ trait Named
|
|||
{
|
||||
def name: String
|
||||
}
|
||||
|
||||
trait Navigation[Project]
|
||||
{
|
||||
def parentProject: Option[Project]
|
||||
def self: Project
|
||||
def initialProject(s: State): Project
|
||||
def projectClosure(s: State): Seq[Project]
|
||||
def rootProject: Project
|
||||
}
|
||||
trait Member[Node <: Member[Node]]
|
||||
{ self: Node =>
|
||||
def projectClosure(state: State): Seq[Node]
|
||||
{
|
||||
def navigation: Navigation[Node]
|
||||
}
|
||||
trait Tasked
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@ ProjectCommand +
|
|||
""" + ProjectCommand + """ name
|
||||
Changes to the project with the provided name.
|
||||
This command fails if there is no project with the given name.
|
||||
""" + ProjectCommand + """ /
|
||||
Changes to the initial project.
|
||||
""" + ProjectCommand + """ ..
|
||||
Changes to the parent project of the current project.
|
||||
If there is no parent project, the current project is unchanged.
|
||||
|
||||
Use n+1 dots to change to the nth parent.
|
||||
For example, 'project ....' is equivalent to three consecutive 'project ..' commands.
|
||||
"""
|
||||
|
||||
def projectsBrief = (ProjectsCommand, projectsDetailed)
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ object Commands
|
|||
def projects = Command { case s @ State(d: Member[_]) =>
|
||||
Apply.simple(ProjectsCommand, projectsBrief, projectsDetailed ) { (in,s) =>
|
||||
val log = logger(s)
|
||||
d.projectClosure(s).foreach { case n: Named => listProject(n, d eq n, log); case _ => () }
|
||||
d.navigation.projectClosure(s).foreach { case n: Named => listProject(n, d eq n, log); case _ => () }
|
||||
s
|
||||
}(s)
|
||||
}
|
||||
|
|
@ -212,17 +212,34 @@ object Commands
|
|||
logger(s).info(d.name)
|
||||
s
|
||||
}
|
||||
else if(to == "/")
|
||||
setProject(d.navigation.initialProject(s), s)
|
||||
else if(to.forall(_ == '.'))
|
||||
if(to.length > 1) gotoParent(to.length - 1, d, s) else s
|
||||
else
|
||||
{
|
||||
d.projectClosure(s).find { case n: Named => n.name == to; case _ => false } match
|
||||
d.navigation.projectClosure(s).find { case n: Named => n.name == to; case _ => false } match
|
||||
{
|
||||
case Some(np) => logger(s).info("Set current project to " + to); s.copy(np)()
|
||||
case Some(np) => setProject(np, s)
|
||||
case None => logger(s).error("Invalid project name '" + to + "' (type 'projects' to list available projects)."); s.fail
|
||||
}
|
||||
}
|
||||
}(s)
|
||||
}
|
||||
|
||||
@tailrec def gotoParent[Node <: Member[Node]](n: Int, base: Member[Node], s: State): State =
|
||||
base.navigation.parentProject match
|
||||
{
|
||||
case Some(pp) => if(n <= 1) setProject(pp, s) else gotoParent(n-1, pp, s)
|
||||
case None => if(s.project == base) s else setProject(base, s)
|
||||
}
|
||||
|
||||
def setProject(np: AnyRef, s: State): State =
|
||||
{
|
||||
np match { case n: Named =>
|
||||
logger(s).info("Set current project to " + n.name)
|
||||
}
|
||||
s.copy(np)()
|
||||
}
|
||||
def exit = Command { case s => Apply( Help(exitBrief) ) {
|
||||
case in if TerminateActions contains in.line =>
|
||||
runExitHooks(s).exit(true)
|
||||
|
|
|
|||
|
|
@ -152,7 +152,12 @@ object MultiContext
|
|||
val static = (o: Owner, s: String) => context(o).static(o, s)
|
||||
}
|
||||
}
|
||||
|
||||
final class MultiNavigation(val self: Project, val parentProject: Option[Project]) extends Navigation[Project]
|
||||
{
|
||||
def initialProject(s: State): Project = MultiProject.initialProject(s, rootProject)
|
||||
def projectClosure(s: State): Seq[Project] = MultiProject.topologicalSort(initialProject(s))
|
||||
@tailrec final lazy val rootProject: Project = parentProject match { case Some(p) => p.navigation.rootProject; case None => self }
|
||||
}
|
||||
trait Project extends Tasked with HistoryEnabled with Member[Project] with Named with ConsoleTask with Watched
|
||||
{
|
||||
val info: ProjectInfo
|
||||
|
|
@ -165,8 +170,7 @@ trait Project extends Tasked with HistoryEnabled with Member[Project] with Named
|
|||
def historyPath = Some(outputRootPath / ".history")
|
||||
def streamBase = outputRootPath / "streams"
|
||||
|
||||
def projectClosure(s: State): Seq[Project] = MultiProject.topologicalSort(MultiProject.initialProject(s, rootProject))
|
||||
@tailrec final def rootProject: Project = info.parent match { case Some(p) => p.rootProject; case None => this }
|
||||
def navigation: Navigation[Project] = new MultiNavigation(this, info.parent)
|
||||
|
||||
implicit def streams = Dummy.Streams
|
||||
def input = Dummy.In
|
||||
|
|
|
|||
Loading…
Reference in New Issue