From 8f25b07d719732c2d4f9a53dff9d7ec67872d308 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 4 Dec 2012 21:08:39 -0500 Subject: [PATCH] -cp/-classpath option to 'apply' command --- main/command/BasicCommands.scala | 16 ++++++++++++++-- sbt/src/sbt-test/actions/call/AddNew.scala | 13 +++++++++++++ sbt/src/sbt-test/actions/call/build.sbt | 9 +++++++++ sbt/src/sbt-test/actions/call/test | 11 +++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 sbt/src/sbt-test/actions/call/AddNew.scala create mode 100644 sbt/src/sbt-test/actions/call/build.sbt create mode 100644 sbt/src/sbt-test/actions/call/test diff --git a/main/command/BasicCommands.scala b/main/command/BasicCommands.scala index 18fe40d90..584958f5a 100644 --- a/main/command/BasicCommands.scala +++ b/main/command/BasicCommands.scala @@ -1,6 +1,7 @@ package sbt import complete.{DefaultParsers, HistoryCommands, Parser} + import classpath.ClasspathUtilities.toLoader import DefaultParsers._ import Types.{const,idFun} import Function.tupled @@ -79,11 +80,22 @@ object BasicCommands } def rebootParser(s: State) = token(Space ~> "full" ^^^ true) ?? false - def call = Command(ApplyCommand, Help.more(ApplyCommand, ApplyDetailed))(_ => spaceDelimited("")) { (state,args) => - val loader = getClass.getClassLoader + def call = Command(ApplyCommand, Help.more(ApplyCommand, ApplyDetailed))(_ => callParser) { case (state,(cp,args)) => + val parentLoader = getClass.getClassLoader + state.log.info("Applying State transformations " + args.mkString(", ") + (if(cp.isEmpty) "" else " from " + cp.mkString(File.separator))) + val loader = if(cp.isEmpty) parentLoader else toLoader(cp.map(f => new File(f)), parentLoader) val loaded = args.map(arg => ModuleUtilities.getObject(arg, loader)) (state /: loaded) { case (s, obj: (State => State)) => obj(s) } } + def callParser: Parser[(Seq[String], Seq[String])] = token(Space) ~> ((classpathOptionParser ?? Nil) ~ rep1sep(className, token(Space))) + private[this] def className: Parser[String] = + token(StringBasic.filter(s => !s.contains("-"), const("- not allowed in class name")), "") + private[this] def classpathOptionParser: Parser[Seq[String]] = + token( ("-cp" | "-classpath") ~> Space ) ~> rep1sep(classpathString, token(File.separatorChar)) <~ token(Space) + private[this] def classpathString: Parser[String] = + token(charClass(entryClass).+.string, "") + private[this] def entryClass(c: Char): Boolean = + c != File.separatorChar && !java.lang.Character.isWhitespace(c) def exit = Command.command(TerminateAction, exitBrief, exitBrief ) ( _ exit true ) diff --git a/sbt/src/sbt-test/actions/call/AddNew.scala b/sbt/src/sbt-test/actions/call/AddNew.scala new file mode 100644 index 000000000..fa94accef --- /dev/null +++ b/sbt/src/sbt-test/actions/call/AddNew.scala @@ -0,0 +1,13 @@ +package demo + +import sbt.{Command,State} + +object AddNewCommand extends (State => State) +{ + def apply(s: State): State = s ++ Seq(newCommand) + + def newCommand = Command.command("newCommand") { (s: State) => + println("This is a new command") + s + } +} \ No newline at end of file diff --git a/sbt/src/sbt-test/actions/call/build.sbt b/sbt/src/sbt-test/actions/call/build.sbt new file mode 100644 index 000000000..165393b53 --- /dev/null +++ b/sbt/src/sbt-test/actions/call/build.sbt @@ -0,0 +1,9 @@ +sbtPlugin := true + +val copyOutputDir = taskKey[Unit]("Copies the compiled classes to a root-level directory") + +copyOutputDir := { + val cd = (classDirectory in Compile).value + val to = baseDirectory.value / "out" + IO.copyDirectory(cd, to) +} \ No newline at end of file diff --git a/sbt/src/sbt-test/actions/call/test b/sbt/src/sbt-test/actions/call/test new file mode 100644 index 000000000..40f86f520 --- /dev/null +++ b/sbt/src/sbt-test/actions/call/test @@ -0,0 +1,11 @@ +# compiles a new State => State instance +> compile +# puts the classes in a stable location (out/) +> copyOutputDir + +# checks that `apply` can load from a specific classpath +> apply -cp out demo.AddNewCommand + +# check that AddNewCommand was actually run +# If it was, it should have registered `newCommand` +> newCommand \ No newline at end of file