diff --git a/executable.sbt b/executable.sbt new file mode 100755 index 0000000..c1837fd --- /dev/null +++ b/executable.sbt @@ -0,0 +1,77 @@ +val executableConfig = config("executable").hide +val executableKey = TaskKey[File]("executable") + +Keys.ivyConfigurations += executableConfig +libraryDependencies ++= Seq( + "org.eclipse.jetty" % "jetty-security" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-webapp" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-continuation" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-server" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-xml" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-http" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-servlet" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-io" % "8.1.16.v20140903" % "executable", + "org.eclipse.jetty" % "jetty-util" % "8.1.16.v20140903" % "executable" +) +executableKey := { + import org.apache.ivy.util.ChecksumHelper + import java.util.jar.{ Manifest => JarManifest } + import java.util.jar.Attributes.{ Name => AttrName } + + val workDir = Keys.target.value / "executable" + var warName = Keys.name.value + "-" + Keys.version.value + "-executable.war" + + val log = streams.value.log + log info s"building executable webapp in ${workDir}" + + // initialize temp directory + val temp = workDir / "webapp" + IO delete temp + + // include jetty classes + val jettyJars = Keys.update.value select configurationFilter(name = executableConfig.name) + jettyJars foreach { jar => + IO unzip (jar, temp, (name:String) => + (name startsWith "javax/") || + (name startsWith "org/") + ) + } + + // include original war file + val warFile = (Keys.`package`).value + IO unzip (warFile, temp) + + // include launcher classes + val classDir = (Keys.classDirectory in Compile).value + val launchClasses = Seq("JettyLauncher.class" /*, "HttpsSupportConnector.class" */) + launchClasses foreach { name => + IO copyFile (classDir / name, temp / name) + } + + // zip it up + IO delete (temp / "META-INF" / "MANIFEST.MF") + val contentMappings = (temp.*** --- PathFinder(temp)).get pair relativeTo(temp) + val manifest = new JarManifest + manifest.getMainAttributes put (AttrName.MANIFEST_VERSION, "1.0") + manifest.getMainAttributes put (AttrName.MAIN_CLASS, "JettyLauncher") + val outputFile = workDir / warName + IO jar (contentMappings, outputFile, manifest) + + // generate checksums + Seq("md5", "sha1") foreach { algorithm => + IO.write( + workDir / (warName + "." + algorithm), + ChecksumHelper computeAsString (outputFile, algorithm) + ) + } + + // done + log info s"built executable webapp ${outputFile}" + outputFile +} +/* +Keys.artifact in (Compile, executableKey) ~= { + _ copy (`type` = "war", extension = "war")) +} +addArtifact(Keys.artifact in (Compile, executableKey), executableKey) +*/