diff --git a/build.sbt b/build.sbt index 3c5e465..5602a1a 100644 --- a/build.sbt +++ b/build.sbt @@ -82,36 +82,36 @@ // Create executable war file val executableConfig = config("executable").hide Keys.ivyConfigurations += executableConfig -libraryDependencies ++= Seq( - "org.eclipse.jetty" % "jetty-security" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-webapp" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-continuation" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-server" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-xml" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-http" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-servlet" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-io" % JettyVersion % "executable", - "org.eclipse.jetty" % "jetty-util" % JettyVersion % "executable" +libraryDependencies ++= Seq( + "org.eclipse.jetty" % "jetty-security" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-webapp" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-continuation" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-server" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-xml" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-http" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-servlet" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-io" % JettyVersion % "executable", + "org.eclipse.jetty" % "jetty-util" % JettyVersion % "executable" ) -val executableKey = TaskKey[File]("executable") -executableKey := { +val executableKey = TaskKey[File]("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" - val warName = Keys.name.value + ".war" + val workDir = Keys.target.value / "executable" + val warName = Keys.name.value + ".war" - val log = streams.value.log + val log = streams.value.log log info s"building executable webapp in ${workDir}" // initialize temp directory - val temp = workDir / "webapp" + val temp = workDir / "webapp" IO delete temp // include jetty classes - val jettyJars = Keys.update.value select configurationFilter(name = executableConfig.name) + val jettyJars = Keys.update.value select configurationFilter(name = executableConfig.name) jettyJars foreach { jar => IO unzip (jar, temp, (name:String) => (name startsWith "javax/") || @@ -120,31 +120,34 @@ } // include original war file - val warFile = (Keys.`package`).value + 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" */) + 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 + 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) - ) + Seq( + "md5" -> "MD5", + "sha1" -> "SHA-1", + "sha256" -> "SHA-256" + ) + .foreach { case (extension, algorithm) => + val checksumFile = workDir / (warName + "." + extension) + Checksums generate (outputFile, checksumFile, algorithm) } // done @@ -153,7 +156,7 @@ } /* Keys.artifact in (Compile, executableKey) ~= { - _ copy (`type` = "war", extension = "war")) + _ copy (`type` = "war", extension = "war")) } addArtifact(Keys.artifact in (Compile, executableKey), executableKey) */ diff --git a/project/Checksums.scala b/project/Checksums.scala new file mode 100644 index 0000000..dc9d849 --- /dev/null +++ b/project/Checksums.scala @@ -0,0 +1,34 @@ +import java.security.MessageDigest; +import scala.annotation._ +import sbt._ +import sbt.Using._ + +object Checksums { + private val bufferSize = 2048 + + def generate(source:File, target:File, algorithm:String):Unit = + IO write (target, compute(source, algorithm)) + + def compute(file:File, algorithm:String):String = + hex(raw(file, algorithm)) + + def raw(file:File, algorithm:String):Array[Byte] = + (Using fileInputStream file) { is => + val md = MessageDigest getInstance algorithm + val buf = new Array[Byte](bufferSize) + md.reset() + @tailrec + def loop() { + val len = is read buf + if (len != -1) { + md update (buf, 0, len) + loop() + } + } + loop() + md.digest() + } + + def hex(bytes:Array[Byte]):String = + bytes map { it => "%02x" format (it.toInt & 0xff) } mkString "" +}