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