changeset 14133:d2e4b81fd8f0

mx: support sha1 digest for dependencies
author Bernhard Urban <bernhard.urban@jku.at>
date Tue, 11 Mar 2014 18:36:20 +0100
parents 5bf75c95ed56
children e71d421370f3
files mx/projects mxtool/mx.py
diffstat 2 files changed, 51 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mx/projects	Tue Mar 11 18:03:09 2014 +0100
+++ b/mx/projects	Tue Mar 11 18:36:20 2014 +0100
@@ -7,6 +7,7 @@
 
 library@JUNIT@path=lib/junit-4.8.jar
 library@JUNIT@urls=http://repo1.maven.org/maven2/junit/junit/4.8/junit-4.8.jar
+library@JUNIT@sha1=4150c00c5706306ef0f8f1410e70c8ff12757922
 library@JUNIT@eclipse.container=org.eclipse.jdt.junit.JUNIT_CONTAINER/4
 
 library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar
@@ -17,12 +18,15 @@
 
 library@JACOCOAGENT@path=lib/jacocoagent.jar
 library@JACOCOAGENT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoagent.jar
+library@JACOCOAGENT@sha1=9e2c835289356d86afbf31840f05a0f9007c4e44
 
 library@JACOCOREPORT@path=lib/jacocoreport.jar
 library@JACOCOREPORT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport.jar
+library@JACOCOREPORT@sha1=32fb5ba2f12d86c4feb74bcefc17a4e6fad8a323
 
 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar
 library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar
+library@DACAPO_SCALA@sha1=59b64c974662b5cf9dbd3cf9045d293853dd7a51
 
 library@OKRA@path=lib/okra-1.8.jar
 library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.8.jar
--- a/mxtool/mx.py	Tue Mar 11 18:03:09 2014 +0100
+++ b/mxtool/mx.py	Tue Mar 11 18:36:20 2014 +0100
@@ -36,6 +36,7 @@
 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile, fnmatch
 import textwrap
 import socket
+import hashlib
 import xml.parsers.expat
 import shutil, re, xml.dom.minidom
 import pipes
@@ -341,15 +342,49 @@
                     print >> fp, ap
         return outOfDate
 
+def _download_file_with_sha1(name, path, urls, sha1, sha1path, resolve, mustExist, sources=False):
+    def _download_lib():
+        print 'Downloading ' + ("Sources " if sources else "") + name + ' from ' + str(urls)
+        download(path, urls)
+
+    def _sha1Cached():
+        with open(sha1path, 'r') as f:
+            return f.readline()[0:40]
+
+    def _writesha1Cached():
+        with open(sha1path, 'w') as f:
+            f.write(_sha1OfFile())
+
+    def _sha1OfFile():
+        with open(path, 'r') as f:
+            return hashlib.sha1(f.read()).hexdigest()
+
+
+    if resolve and mustExist and not exists(path):
+        assert not len(urls) == 0, 'cannot find required library ' + name + ' ' + path
+        _download_lib()
+
+    if sha1 and not exists(sha1path):
+        _writesha1Cached()
+
+    if sha1 and sha1 != _sha1Cached():
+        _download_lib()
+        if sha1 != _sha1OfFile():
+            abort("SHA1 does not match for " + name + ". Broken download? SHA1 not updated in projects file?")
+        _writesha1Cached()
+
+    return path
 
 class Library(Dependency):
-    def __init__(self, suite, name, path, mustExist, urls, sourcePath, sourceUrls):
+    def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1):
         Dependency.__init__(self, suite, name)
         self.path = path.replace('/', os.sep)
         self.urls = urls
+        self.sha1 = sha1
         self.mustExist = mustExist
         self.sourcePath = sourcePath
         self.sourceUrls = sourceUrls
+        self.sourceSha1 = sourceSha1
         for url in urls:
             if url.endswith('/') != self.path.endswith(os.sep):
                 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url)
@@ -375,14 +410,14 @@
         path = self.path
         if not isabs(path):
             path = join(self.suite.dir, path)
+        sha1path = path + '.sha1'
+
         includedInJDK = getattr(self, 'includedInJDK', None)
         if includedInJDK and java().javaCompliance >= JavaCompliance(includedInJDK):
             return None
-        if resolve and self.mustExist and not exists(path):
-            assert not len(self.urls) == 0, 'cannot find required library ' + self.name + ' ' + path
-            print 'Downloading ' + self.name + ' from ' + str(self.urls)
-            download(path, self.urls)
-        return path
+
+        return _download_file_with_sha1(self.name, path, self.urls, self.sha1, sha1path, resolve, self.mustExist)
+
 
     def get_source_path(self, resolve):
         path = self.sourcePath
@@ -390,10 +425,9 @@
             return None
         if not isabs(path):
             path = join(self.suite.dir, path)
-        if resolve and len(self.sourceUrls) != 0 and not exists(path):
-            print 'Downloading sources for ' + self.name + ' from ' + str(self.sourceUrls)
-            download(path, self.sourceUrls)
-        return path
+        sha1path = path + '.sha1'
+
+        return _download_file_with_sha1(self.name, path, self.sourceUrls, self.sha1, sha1path, resolve, len(self.sourceUrls) != 0, sources=True)
 
     def append_to_classpath(self, cp, resolve):
         path = self.get_path(resolve)
@@ -556,9 +590,11 @@
             path = attrs.pop('path')
             mustExist = attrs.pop('optional', 'false') != 'true'
             urls = pop_list(attrs, 'urls')
+            sha1 = attrs.pop('sha1', None)
             sourcePath = attrs.pop('sourcePath', None)
             sourceUrls = pop_list(attrs, 'sourceUrls')
-            l = Library(self, name, path, mustExist, urls, sourcePath, sourceUrls)
+            sourceSha1 = attrs.pop('sourceSha1', None)
+            l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1)
             l.__dict__.update(attrs)
             self.libs.append(l)