From f18241395ba6f030a8bc8a4d837378ca8e1b0e1e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 11 Mar 2011 22:33:30 -0500 Subject: [PATCH] 'reload plugins' to change to plugins project 'reload return' to change back to original project. Declaring a plugin: > reload plugins > set libraryDependencies += ... > reload return --- main/Build.scala | 19 ++++++++----------- main/CommandSupport.scala | 2 +- main/Main.scala | 10 ++++++---- main/Project.scala | 32 +++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/main/Build.scala b/main/Build.scala index a06f04d20..6e5708e68 100644 --- a/main/Build.scala +++ b/main/Build.scala @@ -213,10 +213,10 @@ object Load import BuildStreams._ // note that there is State is passed in but not pulled out - def defaultLoad(state: State, log: Logger): (() => Eval, BuildStructure) = + def defaultLoad(state: State, baseDirectory: File, log: Logger): (() => Eval, BuildStructure) = { val stagingDirectory = defaultStaging.getCanonicalFile // TODO: properly configurable - val base = state.configuration.baseDirectory.getCanonicalFile + val base = baseDirectory.getCanonicalFile val loader = getClass.getClassLoader val provider = state.configuration.provider val classpath = provider.mainClasspath ++ provider.scalaProvider.jars @@ -486,8 +486,8 @@ object Load new BuildUnit(uri, normBase, loadedDefs, plugs) } - def plugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins = if(dir.exists) buildPlugins(dir, s, config) else noPlugins(config) - def noPlugins(config: LoadBuildConfiguration): LoadedPlugins = new LoadedPlugins(config.classpath, config.loader, Nil, Nil) + def plugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins = if(dir.exists) buildPlugins(dir, s, config) else noPlugins(dir, config) + def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = new LoadedPlugins(dir, config.classpath, config.loader, Nil, Nil) def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins = { val (eval,pluginDef) = apply(dir, s, config) @@ -496,7 +496,7 @@ object Load val pluginClasspath = config.evalPluginDef(pluginDef, pluginState) val definitionClasspath = (data(pluginClasspath) ++ config.classpath).distinct val pluginLoader = ClasspathUtilities.toLoader(definitionClasspath, config.loader) - loadPlugins(definitionClasspath, pluginLoader, analyzed(pluginClasspath)) + loadPlugins(dir, definitionClasspath, pluginLoader, analyzed(pluginClasspath)) } def definitions(base: File, targetBase: File, srcs: Seq[File], plugins: LoadedPlugins, compilers: Compilers, log: Logger, buildBase: File): LoadedDefinitions = @@ -521,13 +521,13 @@ object Load (inputs, analysis) } - def loadPlugins(classpath: Seq[File], loader: ClassLoader, analysis: Seq[inc.Analysis]): LoadedPlugins = + def loadPlugins(dir: File, classpath: Seq[File], loader: ClassLoader, analysis: Seq[inc.Analysis]): LoadedPlugins = { val (pluginNames, plugins) = if(classpath.isEmpty) (Nil, Nil) else { val names = analysis flatMap findPlugins (names, loadPlugins(loader, names) ) } - new LoadedPlugins(classpath, loader, plugins, pluginNames) + new LoadedPlugins(dir, classpath, loader, plugins, pluginNames) } def loadPlugins(loader: ClassLoader, pluginNames: Seq[String]): Seq[Setting[_]] = @@ -564,10 +564,7 @@ object Load final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]]) final class LoadedDefinitions(val base: File, val target: File, val loader: ClassLoader, val builds: Seq[Build], val buildNames: Seq[String]) - final class LoadedPlugins(val classpath: Seq[File], val loader: ClassLoader, val plugins: Seq[Setting[_]], val pluginNames: Seq[String]) - object LoadedPlugins { - def empty(loader: ClassLoader) = new LoadedPlugins(Nil, loader, Nil, Nil) - } + final class LoadedPlugins(val base: File, val classpath: Seq[File], val loader: ClassLoader, val plugins: Seq[Setting[_]], val pluginNames: Seq[String]) final class BuildUnit(val uri: URI, val localBase: File, val definitions: LoadedDefinitions, val plugins: LoadedPlugins) { override def toString = if(uri.getScheme == "file") localBase.toString else (uri + " (locally: " + localBase +")") diff --git a/main/CommandSupport.scala b/main/CommandSupport.scala index 5915fbfa9..675692877 100644 --- a/main/CommandSupport.scala +++ b/main/CommandSupport.scala @@ -247,7 +247,7 @@ CompileSyntax + """ def LoadProjectImpl = "loadp" def LoadProject = "reload" - def LoadProjectBrief = LoadProjectDetailed + def LoadProjectBrief = (LoadProject, LoadProjectDetailed) def LoadProjectDetailed = "Loads the project in the current directory" def Shell = "shell" diff --git a/main/Main.scala b/main/Main.scala index 9d28c5029..e48422542 100644 --- a/main/Main.scala +++ b/main/Main.scala @@ -331,11 +331,13 @@ object BuiltinCommands } } - def loadProjectCommands = (OnFailure + " " + LoadFailed) :: LoadProjectImpl :: ClearOnFailure :: FailureWall :: Nil - def loadProject = Command.command(LoadProject, LoadProjectBrief, LoadProjectDetailed) { loadProjectCommands ::: _ } + def loadProjectCommands(arg: String) = (OnFailure + " " + LoadFailed) :: (LoadProjectImpl + " " + arg).trim :: ClearOnFailure :: FailureWall :: Nil + def loadProject = Command(LoadProject, LoadProjectBrief, LoadProjectDetailed)(_ => matched(Project.loadActionParser)) { (s,arg) => loadProjectCommands(arg) ::: s } - def loadProjectImpl = Command.command(LoadProjectImpl) { s => - val (eval, structure) = Load.defaultLoad(s, logger(s)) + def loadProjectImpl = Command(LoadProjectImpl)(_ => Project.loadActionParser) { (s0, action) => + val (s, base) = Project.loadAction(s0, action) + IO.createDirectory(base) + val (eval, structure) = Load.defaultLoad(s, base, logger(s)) val session = Load.initialSession(structure, eval) Project.setProject(session, structure, s) } diff --git a/main/Project.scala b/main/Project.scala index 9198783eb..9872e80aa 100644 --- a/main/Project.scala +++ b/main/Project.scala @@ -98,11 +98,13 @@ object Project extends Init[Scope] val project = Load.getProject(structure.units, ref.build, ref.project) logger(s).info("Set current project to " + ref.project + " (in build " + ref.build +")") def get[T](k: SettingKey[T]): Option[T] = k in ref get structure.data + def commandsIn(axis: ResolvedReference) = commands in axis get structure.data toList ; + val allCommands = commandsIn(ref) ++ commandsIn(BuildRef(ref.build)) ++ (commands get structure.data toList ) val history = get(historyPath) flatMap identity val prompt = get(shellPrompt) val watched = get(watch) - val commandDefs = get(commands).toList.flatten[Command].map(_ tag (projectCommand, true)) + val commandDefs = allCommands.distinct.flatten[Command].map(_ tag (projectCommand, true)) val newProcessors = commandDefs ++ BuiltinCommands.removeTagged(s.processors, projectCommand) val newAttrs = setCond(Watched.Configuration, watched, s.attributes).put(historyPath.key, history) s.copy(attributes = setCond(shellPrompt.key, prompt, newAttrs), processors = newProcessors) @@ -192,6 +194,34 @@ object Project extends Init[Scope] inScope(ThisScope.copy(task = Select(t.key)) )( ss ) def inScope(scope: Scope)(ss: Seq[Setting[_]]): Seq[Setting[_]] = Project.transform(Scope.replaceThis(scope), ss) + + object LoadAction extends Enumeration { + val Return, Current, Plugins = Value + } + import LoadAction._ + import complete.DefaultParsers._ + + val loadActionParser = token(Space ~> ("plugins" ^^^ Plugins | "return" ^^^ Return)) ?? Current + + val ProjectReturn = AttributeKey[List[File]]("project-return") + def projectReturn(s: State): List[File] = s.attributes get ProjectReturn getOrElse Nil + def setProjectReturn(s: State, pr: List[File]): State = s.copy(attributes = s.attributes.put( ProjectReturn, pr) ) + def loadAction(s: State, action: LoadAction.Value) = action match { + case Return => + projectReturn(s) match + { + case current :: returnTo :: rest => (setProjectReturn(s, returnTo :: rest), returnTo) + case _ => error("Not currently in a plugin definition") + } + case Current => + val base = s.configuration.baseDirectory + projectReturn(s) match { case Nil => (setProjectReturn(s, base :: Nil), base); case x :: xs => (s, x) } + case Plugins => + val extracted = Project.extract(s) + val newBase = extracted.currentUnit.unit.plugins.base + val newS = setProjectReturn(s, newBase :: projectReturn(s)) + (newS, newBase) + } } import SessionSettings._