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