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