1# -*- coding: utf-8 -*- 2 3#------------------------------------------------------------------------- 4# drawElements Quality Program utilities 5# -------------------------------------- 6# 7# Copyright 2015-2017 The Android Open Source Project 8# 9# Licensed under the Apache License, Version 2.0 (the "License"); 10# you may not use this file except in compliance with the License. 11# You may obtain a copy of the License at 12# 13# http://www.apache.org/licenses/LICENSE-2.0 14# 15# Unless required by applicable law or agreed to in writing, software 16# distributed under the License is distributed on an "AS IS" BASIS, 17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18# See the License for the specific language governing permissions and 19# limitations under the License. 20# 21#------------------------------------------------------------------------- 22 23import os 24import sys 25import urllib2 26import hashlib 27 28import registry 29 30sys.path.append(os.path.join(os.path.dirname(__file__), "..")) 31 32from build.common import * 33 34BASE_URL = "" 35 36class RegistrySource: 37 def __init__(self, repository, filename, revision, checksum): 38 self.repository = repository 39 self.filename = filename 40 self.revision = revision 41 self.checksum = checksum 42 43 def __hash__(self): 44 return hash((self.repository, self.filename, self.revision, self.checksum)) 45 46 def __eq__(self, other): 47 return (self.repository, self.filename, self.revision, self.checksum) == (other.repository, other.filename, other.revision, other.checksum) 48 49 def getFilename (self): 50 return os.path.basename(self.filename) 51 52 def getCacheFilename (self): 53 return "r%s-%s" % (self.revision, self.getFilename()) 54 55 def getChecksum (self): 56 return self.checksum 57 58 def getRevision (self): 59 return self.revision 60 61 def getRepo (self): 62 return self.repository 63 64 def getRevision (self): 65 return self.revision 66 67 def getFilename (self): 68 return self.filename 69 70def computeChecksum (data): 71 return hashlib.sha256(data).hexdigest() 72 73def makeSourceUrl (repository, revision, filename): 74 return "%s/%s/%s" % (repository, revision, filename) 75 76def checkoutGit (repository, revision, fullDstPath): 77 if not os.path.exists(fullDstPath): 78 execute(["git", "clone", "--no-checkout", repository, fullDstPath]) 79 80 pushWorkingDir(fullDstPath) 81 try: 82 execute(["git", "fetch", repository, "+refs/heads/*:refs/remotes/origin/*"]) 83 execute(["git", "checkout", revision]) 84 finally: 85 popWorkingDir() 86 87def checkoutFile (repository, revision, filename, cacheDir): 88 try: 89 req = urllib2.urlopen(makeSourceUrl(repository, revision, filename)) 90 data = req.read() 91 except IOError: 92 fullDstPath = os.path.join(cacheDir, "git") 93 94 checkoutGit(repository, revision, fullDstPath) 95 f = open(os.path.join(fullDstPath, filename), "r") 96 data = f.read() 97 f.close() 98 except: 99 print "Unexpected error:", sys.exc_info()[0] 100 101 return data 102 103def fetchFile (dstPath, repository, revision, filename, checksum, cacheDir): 104 def writeFile (filename, data): 105 f = open(filename, 'wb') 106 f.write(data) 107 f.close() 108 109 if not os.path.exists(os.path.dirname(dstPath)): 110 os.makedirs(os.path.dirname(dstPath)) 111 112 print "Fetching %s/%s@%s" % (repository, filename, revision) 113 data = checkoutFile(repository, revision, filename, cacheDir) 114 gotChecksum = computeChecksum(data) 115 116 if checksum != gotChecksum: 117 raise Exception("Checksum mismatch, expected %s, got %s" % (checksum, gotChecksum)) 118 119 writeFile(dstPath, data) 120 121def checkFile (filename, checksum): 122 def readFile (filename): 123 f = open(filename, 'rb') 124 data = f.read() 125 f.close() 126 return data 127 128 if os.path.exists(filename): 129 return computeChecksum(readFile(filename)) == checksum 130 else: 131 return False 132 133g_registryCache = {} 134 135def getRegistry (source): 136 global g_registryCache 137 138 if source in g_registryCache: 139 return g_registryCache[source] 140 141 cacheDir = os.path.join(os.path.dirname(__file__), "cache") 142 cachePath = os.path.join(cacheDir, source.getCacheFilename()) 143 144 if not checkFile(cachePath, source.checksum): 145 fetchFile(cachePath, source.getRepo(), source.getRevision(), source.getFilename(), source.getChecksum(), cacheDir) 146 147 parsedReg = registry.parse(cachePath) 148 149 g_registryCache[source] = parsedReg 150 151 return parsedReg 152