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 hashlib 26 27from . import registry 28 29sys.path.append(os.path.join(os.path.dirname(__file__), "..")) 30 31from build.common import * 32 33BASE_URL = "" 34 35class RegistrySource: 36 def __init__(self, repository, filename, revision, checksum): 37 self.repository = repository 38 self.filename = filename 39 self.revision = revision 40 self.checksum = checksum 41 42 def __hash__(self): 43 return hash((self.repository, self.filename, self.revision, self.checksum)) 44 45 def __eq__(self, other): 46 return (self.repository, self.filename, self.revision, self.checksum) == (other.repository, other.filename, other.revision, other.checksum) 47 48 def getFilename (self): 49 return os.path.basename(self.filename) 50 51 def getCacheFilename (self): 52 return "r%s-%s" % (self.revision, self.getFilename()) 53 54 def getChecksum (self): 55 return self.checksum 56 57 def getRevision (self): 58 return self.revision 59 60 def getRepo (self): 61 return self.repository 62 63 def getRevision (self): 64 return self.revision 65 66 def getFilename (self): 67 return self.filename 68 69def computeChecksum (data): 70 dataFiltered = data.replace('\r','') 71 hash = hashlib.sha256(dataFiltered.encode("utf-8")).hexdigest() 72 return hash 73 74def makeSourceUrl (repository, revision, filename): 75 return "%s/%s/%s" % (repository, revision, filename) 76 77def checkoutGit (repository, revision, fullDstPath): 78 if not os.path.exists(fullDstPath): 79 execute(["git", "clone", "--no-checkout", repository, fullDstPath]) 80 81 pushWorkingDir(fullDstPath) 82 try: 83 execute(["git", "fetch", repository, "+refs/heads/*:refs/remotes/origin/*"]) 84 execute(["git", "checkout", revision]) 85 finally: 86 popWorkingDir() 87 88def checkoutFile (repository, revision, filename, cacheDir): 89 if sys.version_info < (3, 0): 90 from urllib2 import urlopen 91 else: 92 from urllib.request import urlopen 93 94 try: 95 req = urlopen(makeSourceUrl(repository, revision, filename)) 96 data = req.read() 97 if sys.version_info >= (3, 0): 98 data = data.decode("utf-8") 99 except IOError: 100 fullDstPath = os.path.join(cacheDir, "git") 101 102 checkoutGit(repository, revision, fullDstPath) 103 f = open(os.path.join(fullDstPath, filename), "rt") 104 data = f.read() 105 f.close() 106 except: 107 print("Unexpected error:", sys.exc_info()[0]) 108 109 return data 110 111def fetchFile (dstPath, repository, revision, filename, checksum, cacheDir): 112 def writeFile (filename, data): 113 f = open(filename, 'wt') 114 f.write(data) 115 f.close() 116 117 if not os.path.exists(os.path.dirname(dstPath)): 118 os.makedirs(os.path.dirname(dstPath)) 119 120 print("Fetching %s/%s@%s" % (repository, filename, revision)) 121 data = checkoutFile(repository, revision, filename, cacheDir) 122 gotChecksum = computeChecksum(data) 123 124 if checksum != gotChecksum: 125 raise Exception("Checksum mismatch, expected %s, got %s" % (checksum, gotChecksum)) 126 127 writeFile(dstPath, data) 128 129def checkFile (filename, checksum): 130 def readFile (filename): 131 f = open(filename, 'rt') 132 data = f.read() 133 f.close() 134 return data 135 136 if os.path.exists(filename): 137 return computeChecksum(readFile(filename)) == checksum 138 else: 139 return False 140 141g_registryCache = {} 142 143def getRegistry (source): 144 global g_registryCache 145 146 if source in g_registryCache: 147 return g_registryCache[source] 148 149 cacheDir = os.path.join(os.path.dirname(__file__), "cache") 150 cachePath = os.path.join(cacheDir, source.getCacheFilename()) 151 152 if not checkFile(cachePath, source.checksum): 153 fetchFile(cachePath, source.getRepo(), source.getRevision(), source.getFilename(), source.getChecksum(), cacheDir) 154 155 parsedReg = registry.parse(cachePath) 156 157 g_registryCache[source] = parsedReg 158 159 return parsedReg 160