summaryrefslogtreecommitdiff
path: root/project
diff options
context:
space:
mode:
authorJosh Suereth <joshua.suereth@gmail.com>2011-12-14 17:44:51 -0500
committerJosh Suereth <joshua.suereth@gmail.com>2011-12-14 17:44:51 -0500
commite5961909c0775682d840aa18baabea9755c82822 (patch)
treee449e28298858198150508f74233d9d99e5b197a /project
parent2f150c026785854b47132335fe44347dd16d0427 (diff)
downloadscala-e5961909c0775682d840aa18baabea9755c82822.tar.gz
scala-e5961909c0775682d840aa18baabea9755c82822.tar.bz2
scala-e5961909c0775682d840aa18baabea9755c82822.zip
Native SHA1 calculations.
* SHA1 sum calculations are now done in pure Scala. * Cache jar SHAs are checked for validity.
Diffstat (limited to 'project')
-rw-r--r--project/ShaResolve.scala60
1 files changed, 52 insertions, 8 deletions
diff --git a/project/ShaResolve.scala b/project/ShaResolve.scala
index 5cc99fd9cf..f54e96c0c6 100644
--- a/project/ShaResolve.scala
+++ b/project/ShaResolve.scala
@@ -5,7 +5,7 @@ import Keys._
import Project.Initialize
import scala.collection.{ mutable, immutable }
import scala.collection.parallel.CompositeThrowable
-
+import java.security.MessageDigest
/** Helpers to resolve SHA artifacts from typesafe repo. */
@@ -30,29 +30,73 @@ object ShaResolve {
jar = dir / uri
if !jar.exists || !isValidSha(file)
sha = getShaFromShafile(file)
- } pullFile(jar, sha + "/" + uri, cacheDir, s)
+ } pullFile(jar, sha + "/" + uri, cacheDir, sha, s)
}
@inline final def loggingParallelExceptions[U](s: TaskStreams)(f: => U): U = try f catch {
case t: CompositeThrowable =>
- s.log.error("Error during parallel execution, GET READ FOR STACK TRACES!!")
+ s.log.error("Error during parallel execution, GET READY FOR STACK TRACES!!")
t.throwables foreach (t2 => s.log.trace(t2))
throw t
}
- def getShaFromShafile(file: File): String = (IO read file split "\\s" headOption) getOrElse error("No SHA found for " + file)
+ def getShaFromShafile(file: File): String = parseShaFile(file)._2
+
+ // This should calculate the SHA sum of a file the same as the linux process.
+ def calculateSha(file: File): String = {
+ val digest = MessageDigest.getInstance("SHA1")
+ val in = new java.io.FileInputStream(file);
+ val buffer = new Array[Byte](8192)
+ try {
+ def read(): Unit = in.read(buffer) match {
+ case x if x <= 0 => ()
+ case size => digest.update(buffer, 0, size); read()
+ }
+ read()
+ } finally in.close()
+ val sha = convertToHex(digest.digest())
+ sha
+ }
+
+ // TODO - Prettier way of doing this...
+ private def convertToHex(data: Array[Byte]): String = {
+ val buf = new StringBuffer
+ for (i <- 0 until data.length) {
+ var halfbyte = (data(i) >>> 4) & 0x0F;
+ var two_halfs = 0;
+ while(two_halfs < 2) {
+ if ((0 <= halfbyte) && (halfbyte <= 9))
+ buf.append(('0' + halfbyte).toChar)
+ else
+ buf.append(('a' + (halfbyte - 10)).toChar);
+ halfbyte = data(i) & 0x0F;
+ two_halfs += 1
+ }
+ }
+ return buf.toString
+ }
+ // Parses a sha file into a file and a sha.
+ def parseShaFile(file: File): (File, String) =
+ IO.read(file).split("\\s") match {
+ case Array(sha, filename) if filename.startsWith("?") => (new File(file.getParentFile, filename.drop(1)), sha)
+ case Array(sha, filename) => (new File(file.getParentFile, filename), sha)
+ case _ => error(file.getAbsolutePath + " is an invalid sha file")
+ }
+
def isValidSha(file: File): Boolean =
- try (Process(Seq("shasum", "-p", "--check", file.getAbsolutePath), Some(file.getParentFile)).!! contains "OK")
- catch {
+ try {
+ val (jar, sha) = parseShaFile(file)
+ jar.exists && calculateSha(jar) == sha
+ } catch {
case t: Exception => false
}
- def pullFile(file: File, uri: String, cacheDir: File, s: TaskStreams): Unit = {
+ def pullFile(file: File, uri: String, cacheDir: File, sha: String, s: TaskStreams): Unit = {
val cachedFile = cacheDir / uri
- if (!cachedFile.exists) {
+ if (!cachedFile.exists || calculateSha(cachedFile) != sha) {
// Ensure the directory for the cache exists.
cachedFile.getParentFile.mkdirs()
val url = remote_urlbase + "/" + uri