Repository: incubator-wave Updated Branches: refs/heads/feature/WAVE-426-add-sbt 70f393281 -> 63c264142
Adds modified copy of GWT compile plugin. Project: http://git-wip-us.apache.org/repos/asf/incubator-wave/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-wave/commit/63c26414 Tree: http://git-wip-us.apache.org/repos/asf/incubator-wave/tree/63c26414 Diff: http://git-wip-us.apache.org/repos/asf/incubator-wave/diff/63c26414 Branch: refs/heads/feature/WAVE-426-add-sbt Commit: 63c26414227ad0aa8069c094d4fa0eb42eb73e46 Parents: 70f3932 Author: yuri.zelikov <[email protected]> Authored: Tue Jul 21 10:12:59 2015 +0300 Committer: yuri.zelikov <[email protected]> Committed: Tue Jul 21 10:12:59 2015 +0300 ---------------------------------------------------------------------- .gitignore | 2 +- build.sbt | 12 ++ project/GwtPlugin.scala | 157 +++++++++++++++++++ project/plugins.sbt | 4 + .../robots/dataapi/DataApiOAuthServletTest.java | 9 -- 5 files changed, 174 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/63c26414/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index bc2e910..b60f4de 100755 --- a/.gitignore +++ b/.gitignore @@ -34,5 +34,5 @@ war/WEB-INF *.iml *.eml .settings/ -project/ +project/target target/ http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/63c26414/build.sbt ---------------------------------------------------------------------- diff --git a/build.sbt b/build.sbt index 80f20f0..e7b3a5f 100644 --- a/build.sbt +++ b/build.sbt @@ -41,3 +41,15 @@ javaOptions in run += "-Dorg.eclipse.jetty.LEVEL=DEBUG" fork in run := true //parallelExecution in Test := false + +//import net.thunderklaus.GwtPlugin._ + +seq(gwtSettings :_*) + +//seq(ScriptedPlugin.scriptedSettings: _*) + +libraryDependencies += "org.mortbay.jetty" % "jetty" % "6.1.22" % "container" + +gwtVersion := "2.7.0" + +gwtModules := List("org.waveprotocol.box.webclient.WebClientProd") \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/63c26414/project/GwtPlugin.scala ---------------------------------------------------------------------- diff --git a/project/GwtPlugin.scala b/project/GwtPlugin.scala new file mode 100644 index 0000000..ed32bfa --- /dev/null +++ b/project/GwtPlugin.scala @@ -0,0 +1,157 @@ +package net.thunderklaus + +import sbt._ +import sbt.Keys._ +import java.io.File +import com.earldouglas.xsbtwebplugin.WebPlugin._ +import com.earldouglas.xsbtwebplugin.PluginKeys._ + +object GwtPlugin extends Plugin { + + lazy val Gwt = config("gwt") extend (Compile) + + val gwtModules = TaskKey[Seq[String]]("gwt-modules") + val gwtCompile = TaskKey[Unit]("gwt-compile", "Runs the GWT compiler") + val gwtForceCompile = TaskKey[Boolean]("gwt-force-compile", "Always recompile gwt modules") + val gwtDevMode = TaskKey[Unit]("gwt-devmode", "Runs the GWT devmode shell") + val gwtVersion = SettingKey[String]("gwt-version") + val gwtTemporaryPath = SettingKey[File]("gwt-temporary-path") + val gwtWebappPath = SettingKey[File]("gwt-webapp-path") + val gaeSdkPath = SettingKey[Option[String]]("gae-sdk-path") + + var gwtModule: Option[String] = None + val gwtSetModule = Command.single("gwt-set-module") { (state, arg) => + Project.evaluateTask(gwtModules, state) match { + case Some(Value(mods)) => { + gwtModule = mods.find(_.toLowerCase.contains(arg.toLowerCase)) + gwtModule match { + case Some(m) => println("gwt-devmode will run: " + m) + case None => println("No match for '" + arg + "' in " + mods.mkString(", ")) + } + } + case _ => None + } + state + } + + lazy val gwtSettings: Seq[Setting[_]] = webSettings ++ gwtOnlySettings + + lazy val gwtOnlySettings: Seq[Setting[_]] = inConfig(Gwt)(Defaults.configSettings) ++ Seq( + managedClasspath in Gwt <<= (managedClasspath in Compile, update) map { + (cp, up) => cp ++ Classpaths.managedJars(Provided, Set("src"), up) + }, + unmanagedClasspath in Gwt <<= (unmanagedClasspath in Compile), + gwtTemporaryPath <<= (target) { (target) => target / "gwt" }, + gwtWebappPath <<= (target) { (target) => target / "webapp" }, + gwtVersion := "2.3.0", + gwtForceCompile := false, + gaeSdkPath := None, + libraryDependencies <++= gwtVersion(gwtVersion => Seq( + "com.google.gwt" % "gwt-user" % gwtVersion % "provided", + "com.google.gwt" % "gwt-dev" % gwtVersion % "provided", + "javax.validation" % "validation-api" % "1.0.0.GA" % "provided" withSources (), + "com.google.gwt" % "gwt-servlet" % gwtVersion)), + gwtModules <<= (javaSource in Compile, resourceDirectory in Compile) map { + (javaSource, resources) => findGwtModules(javaSource) ++ findGwtModules(resources) + }, + gwtDevMode <<= (dependencyClasspath in Gwt, thisProject in Gwt, state in Gwt, javaSource in Compile, javaOptions in Gwt, + gwtModules, gaeSdkPath, gwtWebappPath, streams) map { + (dependencyClasspath, thisProject, pstate, javaSource, javaOpts, gwtModules, gaeSdkPath, warPath, s) => { + def gaeFile (path :String*) = gaeSdkPath.map(_ +: path mkString(File.separator)) + val module = gwtModule.getOrElse(gwtModules.headOption.getOrElse(error("Found no .gwt.xml files."))) + val cp = dependencyClasspath.map(_.data.absolutePath) ++ getDepSources(thisProject.dependencies, pstate) ++ + gaeFile("lib", "appengine-tools-api.jar").toList :+ javaSource.absolutePath + val javaArgs = javaOpts ++ (gaeFile("lib", "agent", "appengine-agent.jar") match { + case None => Nil + case Some(path) => List("-javaagent:" + path) + }) + val gwtArgs = gaeSdkPath match { + case None => Nil + case Some(path) => List( + "-server", "com.google.appengine.tools.development.gwt.AppEngineLauncher") + } + val command = mkGwtCommand( + cp, javaArgs, "com.google.gwt.dev.DevMode", warPath, gwtArgs, module) + s.log.info("Running GWT devmode on: " + module) + s.log.debug("Running GWT devmode command: " + command) + command ! + } + }, + + gwtCompile <<= (classDirectory in Compile, dependencyClasspath in Gwt, thisProject in Gwt, state in Gwt, javaSource in Compile, unmanagedSourceDirectories in Compile, javaOptions in Gwt, + gwtModules, gwtTemporaryPath, streams, gwtForceCompile) map { + (classDirectory, dependencyClasspath, thisProject, pstate, javaSource, unmanagedSource, javaOpts, gwtModules, warPath, s, force) => { + + val srcDirs = Seq(javaSource.absolutePath) ++ unmanagedSource.map(_.absolutePath) ++ getDepSources(thisProject.dependencies, pstate) + val cp = Seq(classDirectory.absolutePath) ++ + dependencyClasspath.map(_.data.absolutePath) ++ + srcDirs + + val needToCompile : Boolean = { + s.log.info("Checking GWT module updates: " + gwtModules.mkString(", ")) + val gwtFiles : Seq[File] = (warPath ** "*.nocache.js").get + if(gwtFiles.isEmpty) { + s.log.info("No GWT output is found in " + warPath) + true + } + else { + val lastCompiled = gwtFiles.map(_.lastModified).max + val moduleDirs = for(d <- srcDirs; m <- (new File(d) ** "*.gwt.xml").get) yield { m.getParentFile } + val gwtSrcs = for(m <- moduleDirs; f <- (m ** "*").get) yield f + gwtSrcs.find(lastCompiled < _.lastModified).isDefined + } + } + + if(force || needToCompile) { + val command = mkGwtCommand( + cp, javaOpts, "com.google.gwt.dev.Compiler", warPath, Nil, gwtModules.mkString(" ")) + s.log.info("Compiling GWT modules: " + gwtModules.mkString(",")) + s.log.debug("Running GWT compiler command: " + command) + command ! + } + else + s.log.info("GWT modules are up to date") + } + }, + webappResources in Compile <+= (gwtTemporaryPath) { (t: File) => t }, + + packageWar in Compile <<= (packageWar in Compile).dependsOn(gwtCompile), + + commands ++= Seq(gwtSetModule) + ) + + + + + def getDepSources(deps : Seq[ClasspathDep[ProjectRef]], state : State) : Set[String] = { + var sources = Set.empty[String] + val structure = Project.extract(state).structure + def get[A] = setting[A](structure)_ + deps.foreach{ + dep=> + sources += (get(dep.project, Keys.sourceDirectory, Compile).get.toString + "/java") + sources ++= getDepSources(Project.getProject(dep.project, structure).get.dependencies, state) + } + sources + } + + def setting[T](structure: Load.BuildStructure)(ref: ProjectRef, key: SettingKey[T], configuration: Configuration): Option[T] = key in (ref, configuration) get structure.data + + private def mkGwtCommand(cp: Seq[String], javaArgs: Seq[String], clazz: String, warPath: File, + gwtArgs: Seq[String], modules: String) = { + println("classpath: " + cp.mkString("\n")) + (List("java", "-cp", cp.mkString(File.pathSeparator)) ++ javaArgs ++ + List(clazz, "-war", warPath.absolutePath) ++ gwtArgs :+ modules).mkString(" ") + } + + + private def findGwtModules(srcRoot: File): Seq[String] = { + import Path.relativeTo + val files = (srcRoot ** "*.gwt.xml").get + val relativeStrings = files.flatMap(_ x relativeTo(srcRoot)).map(_._2) + relativeStrings.map(_.dropRight(".gwt.xml".length).replace(File.separator, ".")) + } + + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/63c26414/project/plugins.sbt ---------------------------------------------------------------------- diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..c5082fc --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,4 @@ +//addSbtPlugin("net.thunderklaus" % "sbt-gwt-plugin" % "1.1-105a30073000a6c09d19c1745c49dc58799e68f8") + +addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.4.0") + http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/63c26414/test/org/waveprotocol/box/server/robots/dataapi/DataApiOAuthServletTest.java ---------------------------------------------------------------------- diff --git a/test/org/waveprotocol/box/server/robots/dataapi/DataApiOAuthServletTest.java b/test/org/waveprotocol/box/server/robots/dataapi/DataApiOAuthServletTest.java index 4016ab9..67d120b 100644 --- a/test/org/waveprotocol/box/server/robots/dataapi/DataApiOAuthServletTest.java +++ b/test/org/waveprotocol/box/server/robots/dataapi/DataApiOAuthServletTest.java @@ -98,15 +98,6 @@ public class DataApiOAuthServletTest extends TestCase { stringWriter.close(); closed = true; } - - @Override - public boolean isReady() { - return true; - } - - @Override - public void setWriteListener(WriteListener wl) { - } } private static final String FAKE_TOKEN = "fake_token";
